|# Automated AMI and Snapshot Deletion|
|# @author Bobby Kozora|
|# This script will search for all instances having a tag named "Backup" with a value of "Backup".|
|# As soon as we have the instances list, we loop through each instance|
|# and reference the AMIs of that instance. We check that the latest daily backup|
|# succeeded then we store every image that's reached its DeleteOn tag's date for|
|# deletion. We then loop through the AMIs, deregister them and remove all the|
|# snapshots associated with that AMI.|
|ec = boto3.client('ec2', 'us-east-1')|
|ec2 = boto3.resource('ec2', 'us-east-1')|
|images = ec2.images.filter(Owners=["self"])|
|def lambda_handler(event, context):|
|reservations = ec.describe_instances(Filters=[|
|'Values': ['backup', 'Backup']|
|instances = sum([[i for i in r['Instances']] for r in reservations], )|
|print("Found %d instances that need evaluated" % len(instances))|
|to_tag = collections.defaultdict(list)|
|date = datetime.datetime.now()|
|date_fmt = date.strftime('%Y-%m-%d')|
|imagesList = |
|# Set to true once we confirm we have a backup taken today|
|backupSuccess = False|
|# Loop through all of our instances with a tag named "Backup"|
|for instance in instances:|
|imagecount = 0|
|# Loop through each image of our current instance|
|for image in images:|
|# Our other Lambda Function names its AMIs Lambda - i-instancenumber.|
|# We now know these images are auto created|
|if image.name.startswith('Lambda - ' + instance['InstanceId']):|
|# print "FOUND IMAGE " + image.id + " FOR INSTANCE " + instance['InstanceId']|
|# Count this image's occcurance|
|imagecount = imagecount + 1|
|if image.tags is not None:|
|deletion_date = [|
|t.get('Value') for t in image.tags|
|if t['Key'] == 'DeleteOn'|
|delete_date = time.strptime(deletion_date, "%m-%d-%Y")|
|deletion_date = False|
|delete_date = False|
|today_time = datetime.datetime.now().strftime('%m-%d-%Y')|
|# today_fmt = today_time.strftime('%m-%d-%Y')|
|today_date = time.strptime(today_time, '%m-%d-%Y')|
|# If image's DeleteOn date is less than or equal to today,|
|# add this image to our list of images to process later|
|if delete_date <= today_date:|
|# Make sure we have an AMI from today and mark backupSuccess as true|
|# Our latest backup from our other Lambda Function succeeded|
|backupSuccess = True|
|print("Latest backup from " + date_fmt + " was a success")|
|print("instance " + instance['InstanceId'] + " has " +|
|str(imagecount) + " AMIs")|
|print("About to process the following AMIs:")|
|if backupSuccess == True:|
|myAccount = boto3.client('sts').get_caller_identity()['Account']|
|snapshots = ec.describe_snapshots(MaxResults=1000,|
|# loop through list of image IDs|
|for image in imagesList:|
|print("deregistering image %s" % image)|
|amiResponse = ec.deregister_image(|
|for snapshot in snapshots:|
|if snapshot['Description'].find(image) > 0:|
|snap = ec.delete_snapshot(|
|print("Deleting snapshot " + snapshot['SnapshotId'])|
|print("No current backup found. Termination suspended.")|
I just set it up as a cron-like Lambda trigger http://docs.aws.amazon.com/lambda/latest/dg/with-scheduled-events.html
Thanks for this nice script, I have made a small enhancement.
The line 20 can be replaced by:
And the line 100 can be replaced with:
Getting Error while executing the script
"errorMessage": "Syntax error in module 'lambda_function'"
Syntax error in module 'lambda_function': inconsistent use of tabs and spaces in indentation (lambda_function.py, line 49)
And also it's pointing the function error, where print command in script.
When I run this function to delete AMIs and snapshots; it never deletes anything. I updated the xxxx with my AWS account ID. The backup function is creating the AMIs and they have the DeleteOn Tag with the proper date. The CloudWatch log of the Delete function says "instance "instance ID" has 0 AMIs" for all of the EC2 instances.
@YorkITGuy Are you using my other Python AWS Lambda function to create the AMIs? https://gist.github.com/bkozora/724e01903a9ad481d21e The two scripts are meant to work together.
Imagine if you had 100 instances and your retention period is 14 days. You are looping through 1400 images, 100 times. I am trying to workout a better way. Either remove
This project is very nice. I also recommend using AWS Ops Automator: https://docs.aws.amazon.com/solutions/latest/ops-automator/overview.html
@bkozore even though i have the delete on tag, it gives a message "instance i-bxxxxx5 has 0 AMIs". I have used your own script to create AMI
The script is running fine for AMI deletion but the corresponding snapshots are not getting deleted.
Anyway I can troubleshoot what is the cause of the failure or any help
The cleanup function is looking for
My workaround was to put the time in front of the date, like this:
Hope this helps someone.
I am getting this error while testing. How to resolve this? Thanks in advance
Having implemented this function to back up over 80 instances, it keeps timing out even when function is set to 5 minute maxiumum with 512MB RAM. Looking at the cloudwatch logs, most of the time is spent looping through each instance to find the AMI's assigned and check if there is a backup today.
My first thought was to decouple the function into two, so parsing the
Would anyone be able to help with this? I am relatively new to python coming from an Ops background.
I found the solution to poor performance and timeouts.
Here is the code. See my comment on the bkozora's backup script to see the code inserted to add the tag to instances.
The 3 snapshots are not getting deleted though the script is picking up the correct snapshot. The AMIs are deleted daily. I have to manually delete the snapshots.
I have specified AWS Account Number in the place of "XXXXX" for both snapshots and AMI in the cleanup script.
DeleteOn date for AMIs are set to 1 day.
If anyone is running into issues with indentation, note that lines 52 and 64 begin with tabs -- you should replace each tab character with 8 spaces. If you already copied/pasted the source, it's possible your text editor replaced the tabs with some number of spaces. (Yes, I started from the raw source; @bkozora should correct this.)
52: imagecount = 0 # line should begin with 8 spaces
When i run the clean up it detects the instances, and is about to process the ones that need to be deleted, but it says no backup found. I noticed if i have more than 10 instances (even though they are not part of my backup tags) it gives me that. Did you run into issues like this?
This is the error msg
instance i-0d92511eef8axxxx has 1 AMIs
About to process the following AMIs:
Omg! Thank you! that worked!!!! mine was on line 46, but yes i changed it from False to True and now they started deregistering!