pythonamazon-web-servicesamazon-ec2aws-lambdaaws-ebs

delete the snapshot if its volume is deleted


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?


Solution

  • 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.)