text: # Automated AMI and Snapshot Deletion
  # This code is referred from with slight changes: https://gist.github.com/bkozora/d4f1cf0e5cf26acdd377
  # 
  # This script will search for all instances having a tag with "Backup"
  # on it. As soon as it has the instances list, it loops through each instance
  # and reference the AMIs of that instance. It then checks whether the latest daily backup
  # succeeded then it store every image that's reached its DeleteOn tag's date for
  # deletion. It 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
  
  #Specify the region in which EC2 Instances are located. Ex: N. Virginia region (us-east-1)
  ec = boto3.client('ec2', 'us-east-1')
  ec2 = boto3.resource('ec2', 'us-east-1')
  images = ec2.images.filter(Owners=["self"])# You can specify your AWS account owner id as well in place of "self" at all the places in this script
  
  def lambda_handler(event, context):
  
      reservations = ec.describe_instances(
          Filters=[
              {'Name': 'tag-key', 'Values': ['Backup']},
              { 'Name': 'instance-state-name','Values': ['running'] }
          ]
      ).get(
          'Reservations', []
      )
  
      instances = sum(
          [
              [i for i in r['Instances']]
              for r in reservations
          ], [])
  
      print "Found %d instances that need evaluation" % len(instances)
  
      to_tag = collections.defaultdict(list)
  
      date = datetime.datetime.now()
      date_fmt = date.strftime('%d-%m-%Y')
      print "Present date and time:" + date.strftime('%d-%m-%Y:%H.%m.%s')
      
      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 - Instance Name.
              # We now know these images are auto created
              if image.name.startswith('Lambda - ' + [result['Value'] for result in instance['Tags'] if result['Key'] == 'Name'][0]):
  	        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, "%d-%m-%Y")
          
                  except IndexError:
                      deletion_date = False
                      delete_date = False
                  
          
                  
                  today_time = datetime.datetime.now().strftime('%d-%m-%Y')
                  # today_fmt = today_time.strftime('%m-%d-%Y')
                  today_date = time.strptime(today_time, '%d-%m-%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:
          
          snapshotList = []
          
          for image in imagesList:
              #print image
              desc_image_snapshots = ec.describe_images(ImageIds=[image],Owners=['self',])['Images'][0]['BlockDeviceMappings']
             # print (desc_image_snapshots)
              try:
                  for desc_image_snapshot in desc_image_snapshots:
                      snapshot = ec.describe_snapshots(SnapshotIds=[desc_image_snapshot['Ebs']['SnapshotId'],], OwnerIds=['self'])['Snapshots'][0]
                      #if snapshot['Description'].find(image) > 0:
                      snapshotList.append(snapshot['SnapshotId'])
                      #else:
                      #   continue
                      #     print "Snapshot is not associated with an AMI"
                      
              except Exception as e:
                  print "Ignore Index Error:%s" % e.message
                  
              print "Deregistering image %s" % image
              amiResponse = ec.deregister_image(
                       DryRun=False,
                     ImageId=image,
                   )
  
          print "============="
          
          print "About to process the following Snapshots associated with above Images:"
          print (snapshotList)
          
          print "The timer is started for 5 seconds to wait for images to deregister before deleting the snapshots associated to it"    
          time.sleep(5)# This should be set to higher value if the image in the imagesList takes more time to deregister
          
          for snapshot in snapshotList:
              try:
                  snap = ec.delete_snapshot(SnapshotId=snapshot)
                  print "Deleted snapshot " + snapshot
              
              except Exception as e:
                  print "%s" % e.message
          print "-------------"
  
  
      else:
          print "No current backup found. Termination suspended."
  