Skip to content

Commit badccaf

Browse files
authored
Add lambda layer resource cleanup. (#339)
*Description of changes:* Add lambda layer resource cleanup script. *Rollback procedure:* Revert the commit. <Can we safely revert this commit if needed? If not, detail what must be done to safely revert and why it is needed.> *Ensure you've run the following tests on your changes and include the link below:* Test workflow passed: https://github.com/aws-observability/aws-application-signals-test-framework/actions/runs/12485707531/job/34844864812 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 754f5ac commit badccaf

File tree

3 files changed

+108
-1
lines changed

3 files changed

+108
-1
lines changed

.github/workflows/resource-cleanup.yml

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,50 @@ jobs:
8181
python -m pip install -r requirements.txt
8282
python cleaner.py
8383
84+
cleanup-lambda-layer:
85+
strategy:
86+
fail-fast: false
87+
matrix:
88+
aws-region: ['af-south-1','ap-east-1','ap-northeast-1','ap-northeast-2','ap-northeast-3','ap-south-1','ap-south-2','ap-southeast-1',
89+
'ap-southeast-2','ap-southeast-3','ap-southeast-4','ca-central-1','eu-central-1','eu-central-2','eu-north-1',
90+
'eu-south-1','eu-south-2','eu-west-1','eu-west-2','eu-west-3','il-central-1','me-central-1','me-south-1', 'sa-east-1',
91+
'us-east-1','us-east-2', 'us-west-1', 'us-west-2']
92+
runs-on: ubuntu-latest
93+
permissions:
94+
id-token: write
95+
contents: read
96+
steps:
97+
- uses: actions/checkout@v3
98+
- uses: actions/setup-python@v5
99+
with:
100+
python-version: '3.10'
101+
102+
- name: Configure AWS credentials for IAD account access
103+
uses: aws-actions/configure-aws-credentials@v4
104+
with:
105+
role-to-assume: ${{ secrets.E2E_IAD_TEST_ACCOUNT_ARN }}
106+
aws-region: us-east-1
107+
108+
- name: Retrieve account id for the region
109+
uses: aws-actions/aws-secretsmanager-get-secrets@v1
110+
with:
111+
secret-ids:
112+
ACCOUNT_ID, region-account/${{ matrix.aws-region }}
113+
114+
- name: Configure AWS credentials for the regional account access
115+
uses: aws-actions/configure-aws-credentials@v4
116+
with:
117+
role-to-assume: arn:aws:iam::${{ env.ACCOUNT_ID }}:role/${{ secrets.RESOURCE_CLEANER_ROLE_NAME }}
118+
aws-region: ${{ matrix.aws-region }}
119+
120+
- name: Cleanup Lambda Layer
121+
working-directory: .github/workflows/util/clean/lambda_layer_cleanup
122+
env:
123+
AWS_DEFAULT_REGION: ${{ matrix.aws-region }}
124+
run: |
125+
python -m pip install -r requirements.txt
126+
python cleaner.py
127+
84128
publish-metric:
85129
needs: [ cleanup-ec2-instances, cleanup-k8s-cluster ]
86130
if: always()
@@ -89,4 +133,4 @@ jobs:
89133
with:
90134
aws-region: 'us-east-1'
91135
caller-workflow-name: 'enablement-test-resource-cleanup'
92-
validation-result: ${{ (needs.cleanup-ec2-instances.result == 'success' && needs.cleanup-k8s-cluster.result == 'success') && 'success' || 'failure' }}
136+
validation-result: ${{ (needs.cleanup-ec2-instances.result == 'success' && needs.cleanup-k8s-cluster.result == 'success' && needs.cleanup-lambda-layer.result == 'success') && 'success' || 'failure' }}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import boto3
2+
from botocore.exceptions import ClientError
3+
from datetime import datetime, timezone, timedelta
4+
import time
5+
6+
client = boto3.client('apigateway')
7+
8+
def delete_api_with_retries(client, api_id, retries=5):
9+
"""Deletes an API with retries and exponential backoff."""
10+
delay = 10
11+
for attempt in range(retries):
12+
try:
13+
client.delete_rest_api(restApiId=api_id)
14+
print(f"API {api_id} deleted successfully. Sleeping for 32 seconds...")
15+
time.sleep(32)
16+
return
17+
except ClientError as e:
18+
if e.response['Error']['Code'] == 'TooManyRequestsException':
19+
print(f"Rate limit exceeded. Retrying in {delay} seconds (Attempt {attempt + 1}/{retries})...")
20+
time.sleep(delay)
21+
delay *= 2 # Exponential backoff
22+
else:
23+
print(f"Error deleting API {api_id}: {e}")
24+
raise # Re-raise other exceptions
25+
print(f"Failed to delete API {api_id} after {retries} attempts.")
26+
27+
def delete_old_api_gateways(hours_old=3, batch_size=5):
28+
"""Deletes API Gateways older than the specified hours in batches."""
29+
now = datetime.now(timezone.utc) # Ensure `now` is timezone-aware
30+
cutoff_time = now - timedelta(hours=hours_old)
31+
32+
print(f"Cutoff time: {cutoff_time}")
33+
34+
# Fetch all APIs
35+
apis = client.get_rest_apis()
36+
batch_counter = 0
37+
38+
for api in apis.get('items', []):
39+
created_date = api.get('createdDate') # This is usually UTC already
40+
if created_date and isinstance(created_date, datetime):
41+
# Ensure `created_date` is timezone-aware
42+
created_date = created_date.astimezone(timezone.utc)
43+
44+
api_id = api['id']
45+
api_name = api.get('name', 'Unnamed API')
46+
if "AdotLambda" in api_name and "SampleApp" in api_name and created_date < cutoff_time:
47+
print(f"Preparing to delete API: {api_name} (ID: {api_id}), created at {created_date}")
48+
49+
# Attempt to delete the API with retries
50+
delete_api_with_retries(client, api_id)
51+
52+
batch_counter += 1
53+
54+
# Pause after every batch
55+
if batch_counter % batch_size == 0:
56+
print("Pausing for 2 minutes to avoid rate-limiting...")
57+
time.sleep(120)
58+
else:
59+
print("Invalid or missing createdDate for API:", api)
60+
61+
if __name__ == "__main__":
62+
delete_old_api_gateways()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
boto3

0 commit comments

Comments
 (0)