in Lab2-EC2AutoSnapshot_CloudWatchEvent+Lambda/auto_snapshot_lambda.py [0:0]
def lambda_handler(event, context):
print('Recieve event: ', event)
SnapshotKeyWord = event['SnapshotKeyWord']
# List all instances in the region
response = ec2.describe_instances(
Filters=[
{'Name': 'tag-key', 'Values': [SnapshotKeyWord]},
]
)
# TODO if instance >1000, use NextToken to get full list
instances = sum(
[
[i for i in r['Instances']]
for r in response['Reservations']
], [])
print("Found %d instances have %s tag" % (len(instances), SnapshotKeyWord))
# Create snapshot
for instance in instances:
# How many Snapshot should be keep for each volume on this EC2 instance
try:
snapshot_numbers = [
int(t['Value']) for t in instance['Tags'] if t['Key'] == SnapshotKeyWord
][0]
except Exception as e:
snapshot_numbers = default_snapshot_number
print('Err SnapshotNumbers, set to default. Err code: ', e)
# figure out instance name if there is one
instance_name = ""
for tag in instance['Tags']:
if tag['Key'] != 'Name':
continue
else:
instance_name = tag['Value']
print('\nProcessing instance %s - %s, Max %d snapshots for %d volumes' %
(instance['InstanceId'], instance_name, snapshot_numbers, len(instance['BlockDeviceMappings'])))
# Each volume on this EC2 instance
for dev in instance['BlockDeviceMappings']:
# The volume id of this instance
if dev.get('Ebs', None) is None:
continue # Next Intance
vol_id = dev['Ebs']['VolumeId']
dev_name = dev['DeviceName']
description = 'AutoSnapshot %s - %s (%s)' % (
instance_name, vol_id, dev_name)
print('Processing volume', vol_id, dev_name)
# Trigger Snapshot
try:
snap = ec2.create_snapshot(
VolumeId=vol_id,
Description=description,
TagSpecifications=[
{
'ResourceType': 'snapshot',
'Tags': instance['Tags']
}
]
)
if (snap):
print("Snapshot %s created of [%s]" % (
snap['SnapshotId'], description))
except Exception as e:
print('fail to create snapshot, err code: ', e)
# TODO send sns notification for fail
continue
# List all existing snapshots with tag SnapshotKeyWord of this volume
try:
snapshot_response = ec2.describe_snapshots(
Filters=[
{'Name': 'tag-key', 'Values': [SnapshotKeyWord]},
{'Name': 'volume-id', 'Values': [vol_id]}
]
)
snap_list = []
for snap in snapshot_response['Snapshots']:
for t in snap['Tags']:
if t['Key'] == SnapshotKeyWord:
snap_list.append({
'SnapshotId': snap['SnapshotId'],
'StartTime': snap['StartTime']
})
snap_exist_num = len(snap_list)
print('There are %d snapshot for this volume' % snap_exist_num)
except Exception as e:
print('fail to list snapshot, err code: ', e)
# TODO send sns notification for fail
continue
# Delete old snapshot
try:
if snap_exist_num > snapshot_numbers:
# How many snapshot to delete
delta_num = snap_exist_num - snapshot_numbers
for i in range(0, delta_num):
# search the oldest
snap_to_delete = snap_list[0]
for n in snap_list:
if n['StartTime'] < snap_to_delete['StartTime']:
snap_to_delete = n
# delete the oldest snap_shot
ec2.delete_snapshot(
SnapshotId=snap_to_delete['SnapshotId'])
snap_list.remove(snap_to_delete)
print('Delete snapshot n=%d of %s' %
(i+1, snap_to_delete['SnapshotId']))
except Exception as e:
print('fail to delete snapshot, err code: ', e)
# TODO send sns notification for fail
continue
return {
'statusCode': 200,
'body': 'ok'
}