Deleting old AMIs and snapshots

About deleting old AMIs by date and orphaned snapshots

Posted by Daniel Viorreta on May 20, 2015

Deleting AMIs by date

When you are a heavy use of Amazon you can have a lot of Amazon Machine Images (AMIs). I have created a boto function to delete AMIs by date:

def delete_old_amis(awsAccount, vRetentionTime=68, vdryRun=False):

ec2conn = boto.ec2.connect_to_region("eu-west-1", profile_name=awsAccount)

images = ec2conn.get_all_images(owners=['self'])

count = 0
for image in images:
creation_date = image.creationDate.split('T')[0].split('-')
split_time = (date.today() - date(int(creation_date[0]), int(creation_date[1]), int(creation_date[2]))).days
if split_time > vRetentionTime:
print image.id+ " : is going to be deregistered"
print "Split_time is : "+str(split_time)
if vdryRun == True:
image.deregister(delete_snapshot=True)
count = count + 1
print 'AMIs deleted: ' + str(count)

Deleting orphaned snapshots

When you create a new AMI, AWS creates a S3 snapshot of all of the instance’s EBS volumes. But when you delete an AMI the snapshots are left behind. I have created a boto function to delete snapshot not associated with an existing AMI:

def delete_orphan_snapshots(awsAccount, vdryRun=False):
ec2conn = boto.ec2.connect_to_region("eu-west-1", profile_name=awsAccount)

imageIds = []
for image in ec2conn.get_all_images(owners=['self']):
#print image.id, image.name + ", " + image.description
#imageIds, imageNames = zip(*[(image.id, image.id)])
imageIds.append(image.id)

print 'Number of AMIs: '+str(len(imageIds))

# Get list of snapshots and AMIs
reAmi = re.compile('ami-[^ ]+')
snapshots = []
snapshotsToDelete = []
snapshotsUnknown = []
imageSnapshots = {}

for snapshot in ec2conn.get_all_snapshots(owner='self'):
# Get id and image ID via regex.
snapshotId = snapshot.id
snapshotImageId = reAmi.findall(snapshot.description)
if len(snapshotImageId) != 1:
snapshotsUnknown.append(snapshotId)
else:
snapshotImageId = snapshotImageId[0]

# Update lists
snapshots.append(snapshotId)
#print 'snapshotImageId: '+str(snapshotImageId)
if snapshotImageId not in imageIds:
snapshotsToDelete.append(snapshotId)
else:
if snapshotImageId in imageSnapshots:
imageSnapshots[snapshotImageId].append(snapshotId)
else:
imageSnapshots[snapshotImageId] = [snapshotId]

print 'Number of orphaned snapshots to delete: '+str(len(snapshotsToDelete))
print 'Number of mapped snapshots to keep: '+str(len(imageSnapshots))

if vdryRun == True:
for snapshot in snapshotsToDelete:
print 'Removing ' + snapshot + '...'
ec2conn.delete_snapshot(snapshot)