@@ -0,0 +1,117 @@
# Automated AMI and Snapshot Deletion
#
# @author Robert Kozora <[email protected] >
#
# This script will search for all instances having a tag with "Backup" or "backup"
# on it. 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.
import boto3
import collections
import datetime
import time
import sys
ec = boto3 .client ('ec2' , 'us-east-1' )
ec2 = boto3 .resource ('ec2' , 'us-east-1' )
images = ec2 .images .filter (Owners = ["xxxxxx" ])
def lambda_handler (event , context ):
reservations = ec .describe_instances (
Filters = [
{'Name' : 'tag-key' , 'Values' : ['backup' , 'Backup' ]},
]
).get (
'Reservations' , []
)
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
try :
if image .tags is not None :
deletion_date = [
t .get ('Value' ) for t in image .tags
if t ['Key' ] == 'DeleteOn' ][0 ]
delete_date = time .strptime (deletion_date , "%m-%d-%Y" )
except IndexError :
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 :
imagesList .append (image .id )
# Make sure we have an AMI from today and mark backupSuccess as true
if image .name .endswith (date_fmt ):
# 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 "============="
print "About to process the following AMIs:"
print imagesList
if backupSuccess == True :
snapshots = ec .describe_snapshots (MaxResults = 1000 , OwnerIds = ['xxxxx' ])['Snapshots' ]
# loop through list of image IDs
for image in imagesList :
print "deregistering image %s" % image
amiResponse = ec .deregister_image (
DryRun = False ,
ImageId = image ,
)
for snapshot in snapshots :
if snapshot ['Description' ].find (image ) > 0 :
snap = ec .delete_snapshot (SnapshotId = snapshot ['SnapshotId' ])
print "Deleting snapshot " + snapshot ['SnapshotId' ]
print "-------------"
else :
print "No current backup found. Termination suspended."