0

I need to delete the snapshot of my Elastic Block Store volume whose EBS volumes are deleted. I would like to do this using a Lambda function. I wrote a script which will give me false if the EBS volume does not exist. How can I modify it to delete any related snapshots?

def get_snapshots():
    account_ids = list()
    account_ids.append( boto3.client('sts').get_caller_identity().get('Account'))
    return ec2.describe_snapshots(OwnerIds=account_ids)
 
def volume_exists(volume_id):
    if not volume_id: return ''
    try:
        ec2.describe_volumes(VolumeIds=[volume_id])
        return True
    except ClientError:
        return False
 

 
def lambda_handler(event, context):

    with open('/tmp/report.csv', 'w') as csvfile:
        writer = csv.writer(csvfile)
        writer.writerow([
        'volume exists'
        ])
        snaps = get_snapshots()
        
        for snap in snaps.get('Snapshots'):
            writer.writerow([
            
            str(volume_exists(snap['VolumeId']))
            ])

Any suggestion?

Ersoy
  • 8,816
  • 6
  • 34
  • 48

2 Answers2

6

Here's some code that will delete snapshots that don't have an existing volume:

import boto3

ec2_client = boto3.client('ec2')

# Make a list of existing volumes
volume_response = ec2_client.describe_volumes()
volumes = [volume['VolumeId'] for volume in volume_response['Volumes']]

# Find snapshots without existing volume
snapshot_response = ec2_client.describe_snapshots(OwnerIds=['self'])

for snapshot in snapshot_response['Snapshots']:
    if snapshot['VolumeId'] not in volumes:
        delete_response = ec2_client.delete_snapshot(SnapshotId=snapshot['SnapshotId'])

Or, here's a version that uses resource instead of client:

import boto3

ec2_resource = boto3.resource('ec2')

# Make a list of existing volumes
all_volumes = ec2_resource.volumes.all()
volumes = [volume.volume_id for volume in all_volumes]

# Find snapshots without existing volume
snapshots = ec2_resource.snapshots.filter(OwnerIds=['self'])

for snapshot in snapshots:
    if snapshot.volume_id not in volumes:
        snapshot.delete()

If they work as you wish, you'll need to incorporate it into a Lambda function.

(In addition to the license granted under the terms of service of this site the contents of this post are licensed under MIT-0.)

John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
2

The best approach to this is to create an "EBS delete" cloud watch event and trigger a lambda. The Payload of the event inside the lambda gives you all the informations about the deleted volume. From there you can query the snasphots and delete them too.

For this, go to Cloudwatch -> Events -> Rules and create a new rule like seen in the screenshot below:

enter image description here

There you can also attach your lambda. I would always go the Event way.

Logemann
  • 2,767
  • 33
  • 53