def lambda_handler()

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'
    }