# This script copies the AMI to other region and add tag 'DeleteOnCopy' with retention days specified. import boto3 from dateutil import parser import datetime import collections # Set the global variables globalVars = dict() globalVars['Owner'] = 'user' globalVars['Environment'] = 'env_name' globalVars['SourceRegion'] = 'ap-south-1' globalVars['destRegions'] = ['us-east-1','us-east-2',] # List of AWS Regions to which the AMI to be copied globalVars['amiRetentionDays'] = int(5) # AMI Rentention days in DR/Destination Region. # Create the Boto Resources and Clients srcEC2Resource = boto3.resource('ec2', region_name = globalVars['SourceRegion']) # Get the Account ID of the Lambda Runner Account - Assuming this is the source account globalVars['awsAccountId'] = boto3.client('sts').get_caller_identity()['Account'] def img_replicator(): # Get the list of images in source Region images = srcEC2Resource.images.filter(Owners=[ globalVars['awsAccountId'] ]) to_tag = collections.defaultdict(list) imgReplicationStatus = {'Images': []} for image in images: image_date = parser.parse(image.creation_date) # Copy ONLY today's images if image_date.date() == (datetime.datetime.today()).date(): # To Copy previous day images # if image_date.date() == (datetime.datetime.today()-datetime.timedelta(1)).date(): # Copy to Multiple destinations for awsRegion in globalVars['destRegions']: destEC2Client = boto3.client('ec2', region_name=awsRegion) # Copy ONLY if the destination doesn't have an image already with the same name # AMI Names have to be UNIQUE if not destEC2Client.describe_images(Owners=[ globalVars['awsAccountId'] ], Filters=[{'Name':'name', 'Values':[image.name]}])['Images']: print "Copying Image. \nImage Name:{name} \nID:{id} \nRegion:'{dest}'".format(name=image.name,id=image.id, dest=awsRegion) new_ami = destEC2Client.copy_image( DryRun=False, SourceRegion=globalVars['SourceRegion'], SourceImageId=image.id, Name=image.name, Description=image.description ) to_tag[ globalVars['amiRetentionDays'] ].append(new_ami['ImageId']) imgReplicationStatus['Images'].append({'Source-Image-Id':image.id, 'Destination-Image-Id':new_ami['ImageId'], 'RetentionDays':globalVars['amiRetentionDays'], 'Status':'Copied'}) for ami_retention_days in to_tag.keys(): delete_date = datetime.date.today() + datetime.timedelta(days=globalVars['amiRetentionDays']) delete_fmt = delete_date.strftime('%d-%m-%Y') print "Will delete {0} AMIs on {1}".format(len(to_tag[globalVars['amiRetentionDays']]), delete_fmt) # Add tag to the AMI enabling Lambda to delete/cleanUp after retention period expires destEC2Client.create_tags( Resources=to_tag[globalVars['amiRetentionDays']], Tags=[ {'Key': 'DeleteOnCopy', 'Value': delete_fmt} ] ) else: print "Image {name} - {id} already present in Virginia Region".format( name=image.name, id=image.id ) imgReplicationStatus['Images'].append({'AMI-Id':image.id,'Status':'Already Exists'}) else: print "There are no new images. The Image: {name} with AMI ID: {id} was created on {date}".format(name=image.name, id=image.id, date=image_date.strftime('%d-%m-%Y')) return imgReplicationStatus def lambda_handler(event, context): img_replicator() if __name__ == '__main__': lambda_handler(None, None)