AWS Lambda - Copy more than 5 EC2 Snapshots automatically between regions

Posted: | Last updated: | 2 minute read

Copying EC2 snapshot between regions is quite an easy task now. In some scenarios, we may have to copy more than 5 snapshots automatically without any human entration.

Snapshot copy operation has a limitation of copying max 5 snapshots at one time. Hence you can not copy more than 5 snapshots at a time.

Lambda Function

Following are the steps to automate to copy more than 5 Snapshots.

Let’s say, we have around 50 snapshots in a region, and you want to automate to copying all Snapshots to another region on AWS.

Step 1: Create a tag in all 50 Snapshots like Key=Backup, and Value=Yes

Step 2: Use below filter for getting all Snapshots yet to copy. Filters=[{‘Name’:’tag:Backup’,’Values’:[‘Yes’]}]

Step 3: After getting all Snapshots with applied filter, run a for loop (max 5 iteration) and start copying only 5 Snapshots.

Step 4: Once the copy done, change the original Snapshot tag as follow: Key=Backup, and Value=Yes —-> To Key=Backup, and Value=Completed

Next time when this Lambda function will run, it will fetch all Snapshot except Completed on.

Step 5: To run this Lambda function, create a CloudWatch scheduler, and call this lambda function every 10 minutes.

The Lambda function code.

import boto3
import time

region_source = 'us-east-1'
region_dest = 'ap-southeast-1'

client_source = boto3.client('ec2',region_name=region_source)
client_dest = boto3.client('ec2',region_name=region_dest)
ec2_resource = boto3.resource('ec2')

#Getting all snapshots as per specified filter
def get_snapshots():
    response = client_source.describe_snapshots(
                    Filters=[{'Name':'tag:Backup','Values':['Yes']}]
                )
    return response["Snapshots"]

#Creating a list of snapshot_id and respective tags
def get_snapshot_list(snapshots):
    snapshot_list = []
    for snapshot in snapshots:
        snapshot_id = snapshot["SnapshotId"]
        tags = snapshot["Tags"]
        snapshot_list.append((snapshot_id, tags))
    return snapshot_list

#Copying snapshot with tags
def copy_snapshot(snapshot_id, tags):
    print "Started copying.. snapshot_id: " + snapshot_id + ", from: " + region_source + ", to: " + region_dest
    
    try:
        copy_response = client_dest.copy_snapshot(
            Description='copied from us-east-1',
            SourceRegion=region_source,
            SourceSnapshotId=snapshot_id,
            DryRun=False
        )
    except Exception, e:
        raise e

    new_snapshot_id = copy_response["SnapshotId"]
    print 'new_snapshot_id : ' + new_snapshot_id
    new_snapshot = ec2_resource.Snapshot(new_snapshot_id)
    
    #Creating tags in new snapshort
    tag = new_snapshot.create_tags(
        DryRun=False,
        Tags=tags
    )
    create_tag(client_dest, new_snapshot_id, 'Source Snapshot Id', snapshot_id)
    delete_tag(client_source, snapshot_id, 'Backup', 'Yes')
    create_tag(client_source, snapshot_id, 'Backup', 'Completed')
    print "Successfully copyied.. snapshot_id: " + snapshot_id + ", from: " + region_source + ", to: " + region_dest
    return new_snapshot_id
    
    
def delete_tag(client, snapshot_id, key, value):
    print "Deleting tag - " + key ":" + value + ", snapshot_id: " + snapshot_id
    client.delete_tags(
        Resources=[snapshot_id],
        Tags=[
            {
            'Key': key,
            'Value':value
            },
        ]
    )

def create_tag(client, snapshot_id, key, value):
    print "Creating tag - " + key ":" + value + ", snapshot_id: " + snapshot_id
    client.create_tags(
        Resources=[snapshot_id],
        Tags=[
            {
                'Key': key,
                'Value':value 
            },
        ]
    )

def lambda_handler(event, context):
    snapshots = get_snapshots()
    snapshot_list = get_snapshot_list(snapshots)
    
    i = 0
    for snapshort in snapshot_list:
        if i < 5:
            snapshot_id = snapshort[0]
            tags = snapshort[1]
            new_snapshot_id = copy_snapshot(snapshot_id, tags)
            i = i + 1
        else:
            exit(0)