Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions .github/scripts/cleanup_e2e_unmanaged_log_groups.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env bash
set -euo pipefail

usage() {
cat <<'USAGE'
Usage: cleanup_e2e_unmanaged_log_groups.sh [--execute] [--region REGION] [--stack-name NAME ...]

Deletes Lambda CloudWatch log groups for e2e test stacks only when those log
groups are not already managed as AWS::Logs::LogGroup resources by the stack.

This is intended for the one-time migration from Lambda auto-created log groups
to CloudFormation-managed log groups with explicit retention. The default mode is
a dry run. Pass --execute to delete matching unmanaged log groups.
USAGE
}

execute=false
region="${AWS_REGION:-}"
stacks=()

while [[ $# -gt 0 ]]; do
case "$1" in
--execute)
execute=true
shift
;;
--region)
region="${2:?--region requires a value}"
shift 2
;;
--stack-name)
stacks+=("${2:?--stack-name requires a value}")
shift 2
;;
--help|-h)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done

if [[ ${#stacks[@]} -eq 0 ]]; then
stacks=(
Java17-JavaSDKCloudBasedIntegrationTestStack
Java21-JavaSDKCloudBasedIntegrationTestStack
Java25-JavaSDKCloudBasedIntegrationTestStack
)
fi

aws_args=()
if [[ -n "$region" ]]; then
aws_args+=(--region "$region")
fi

log_group_exists() {
local target="$1"
local found

found=$(aws "${aws_args[@]}" logs describe-log-groups \
--log-group-name-prefix "$target" \
--query 'logGroups[].logGroupName' \
--output text)

for log_group_name in $found; do
if [[ "$log_group_name" == "$target" ]]; then
return 0
fi
done

return 1
}

is_managed_log_group() {
local target="$1"
shift

for managed_log_group in "$@"; do
if [[ "$managed_log_group" == "$target" ]]; then
return 0
fi
done

return 1
}

for stack in "${stacks[@]}"; do
if ! aws "${aws_args[@]}" cloudformation describe-stacks --stack-name "$stack" >/dev/null 2>&1; then
echo "Skipping missing stack: $stack"
continue
fi

function_names_text=$(aws "${aws_args[@]}" cloudformation list-stack-resources \
--stack-name "$stack" \
--query "StackResourceSummaries[?ResourceType=='AWS::Lambda::Function'].PhysicalResourceId" \
--output text)
managed_log_groups_text=$(aws "${aws_args[@]}" cloudformation list-stack-resources \
--stack-name "$stack" \
--query "StackResourceSummaries[?ResourceType=='AWS::Logs::LogGroup'].PhysicalResourceId" \
--output text)

function_names=($function_names_text)
managed_log_groups=($managed_log_groups_text)

for function_name in "${function_names[@]}"; do
log_group="/aws/lambda/${function_name}"

if is_managed_log_group "$log_group" "${managed_log_groups[@]}"; then
echo "Keeping managed log group: $log_group"
continue
fi

if ! log_group_exists "$log_group"; then
echo "No unmanaged log group found: $log_group"
continue
fi

if [[ "$execute" == true ]]; then
echo "Deleting unmanaged log group: $log_group"
aws "${aws_args[@]}" logs delete-log-group --log-group-name "$log_group"
else
echo "Would delete unmanaged log group: $log_group"
fi
done
done

if [[ "$execute" != true ]]; then
echo "Dry run complete. Re-run with --execute to delete the unmanaged log groups listed above."
fi
8 changes: 8 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,21 @@ jobs:
cache: maven
- name: Build locally
run: mvn -B -q -Dmaven.test.skip=true install --file pom.xml
- name: Generate SAM template
run: python3 generate-template.py
working-directory: ./examples
- name: sam build
env:
MAVEN_OPTS: -DskipTests=true -Dmaven.test.skip=true
run: | # add --no-cached if debugging sam build
sam build --debug --parameter-overrides \
'ParameterKey=Architecture,ParameterValue=x86_64 ParameterKey=JavaVersion,ParameterValue=java${{ matrix.java }} ParameterKey=FunctionNamePrefix,ParameterValue=Java${{ matrix.java }}- ParameterKey=RoleArn,ParameterValue=${{ secrets.TEST_LAMBDA_EXECUTION_ROLE_ARN }}'
working-directory: ./examples
- name: Clean up unmanaged Lambda log groups
run: |
# TODO: Remove this one-time migration cleanup after existing e2e stacks adopt managed log groups.
.github/scripts/cleanup_e2e_unmanaged_log_groups.sh --execute \
--stack-name Java${{ matrix.java }}-JavaSDKCloudBasedIntegrationTestStack
- name: sam deploy
run: |
sam deploy --stack-name Java${{ matrix.java }}-JavaSDKCloudBasedIntegrationTestStack \
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@ buildNumber.properties
Thumbs.db

# Build artifacts
__pycache__/
*.jar
*.war
*.ear
*.class

# SAM
.aws-sam/
examples/template.yaml
samconfig.toml
samconfig.toml.bak

# OSS
.flattened-pom.xml
.flattened-pom.xml
11 changes: 11 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The local runner executes in-memory and skips wait durations—ideal for fast it
```bash
cd examples
mvn clean package
python3 generate-template.py
sam build
sam deploy --guided
```
Expand All @@ -45,8 +46,11 @@ sam deploy

The SAM template configures:
- `DurableConfig` with `ExecutionTimeout` and `RetentionPeriodInDays`
- CloudWatch log groups for Lambda functions with 7 days of retention
- IAM permissions for `lambda:CheckpointDurableExecutions` and `lambda:GetDurableExecutionState`

`template.yaml` is generated from the Java example handlers and is intentionally not checked in. Re-run `python3 generate-template.py` after adding or removing a deployable example handler.

## Invoke Deployed Functions

```bash
Expand Down Expand Up @@ -103,3 +107,10 @@ mvn test -Dtest=CloudBasedIntegrationTest \
```bash
sam delete
```

If an existing e2e test stack has Lambda-created log groups that predate the managed log group resources, clean them up before redeploying:

```bash
../.github/scripts/cleanup_e2e_unmanaged_log_groups.sh --stack-name Java17-JavaSDKCloudBasedIntegrationTestStack
../.github/scripts/cleanup_e2e_unmanaged_log_groups.sh --execute --stack-name Java17-JavaSDKCloudBasedIntegrationTestStack
```
1 change: 1 addition & 0 deletions examples/build-and-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mvn install -DskipTests
# Package example
cd examples
mvn clean package -DskipTests
python3 generate-template.py

# Run SAM local invoke
sam local invoke SimpleStepExampleFunction --event event.json --skip-pull-image
Loading
Loading