Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
127 lines (103 sloc) 4.25 KB
import boto3
import collections
import datetime
import base64
import os
import json
import itertools
base64_region = os.environ['aws_regions']
aws_sns_arn = os.getenv('aws_sns_arn', None)
def send_to_sns(subject, message):
if aws_sns_arn is None:
return
print "Sending notification to: %s" % aws_sns_arn
client = boto3.client('sns')
response = client.publish(
TargetArn=aws_sns_arn,
Message=message,
Subject=subject)
if 'MessageId' in response:
print "Notification sent with message id: %s" % response['MessageId']
else:
print "Sending notification failed with response: %s" % str(response)
def lambda_handler(event, context):
decoded_regions = base64.b64decode(base64_region)
regions = decoded_regions.split(',')
print "Backing up instances in regions: %s" % regions
for region in regions:
ec = boto3.client('ec2', region_name=region)
reservations = ec.describe_instances(
Filters=[
{'Name': 'tag-key', 'Values': ['backup', 'Backup']},
]
).get(
'Reservations', []
)
instances = sum(
[
[i for i in r['Instances']]
for r in reservations
], [])
print "Found %d instances that need backing up in region %s" % (len(instances), region)
to_tag_retention = collections.defaultdict(list)
to_tag_mount_point = collections.defaultdict(list)
for instance in instances:
try:
retention_days = [
int(t.get('Value')) for t in instance['Tags']
if t['Key'] == 'Retention'][0]
except IndexError:
retention_days = 7
try:
skip_volumes = [
str(t.get('Value')).split(',') for t in instance['Tags']
if t['Key'] == 'Skip_Backup_Volumes']
except Exception:
pass
from itertools import chain
skip_volumes_list = list(chain.from_iterable(skip_volumes))
for dev in instance['BlockDeviceMappings']:
if dev.get('Ebs', None) is None:
continue
vol_id = dev['Ebs']['VolumeId']
if vol_id in skip_volumes_list:
print "Volume %s is set to be skipped, not backing up" % (vol_id)
continue
dev_attachment = dev['DeviceName']
print "Found EBS volume %s on instance %s attached to %s" % (
vol_id, instance['InstanceId'], dev_attachment)
instance_name = ''
try:
instance_name = [ x['Value'] for x in instance['Tags'] if x['Key'] == 'Name' ][0]
except IndexError:
pass
snap = ec.create_snapshot(
VolumeId=vol_id,
Description='{} {}'.format(instance_name, instance['InstanceId'])
)
to_tag_retention[retention_days].append(snap['SnapshotId'])
to_tag_mount_point[vol_id].append(snap['SnapshotId'])
print "Retaining snapshot %s of volume %s from instance %s for %d days" % (
snap['SnapshotId'],
vol_id,
instance['InstanceId'],
retention_days,
)
ec.create_tags(
Resources=to_tag_mount_point[vol_id],
Tags=[
{'Key': 'Name', 'Value': dev_attachment},
]
)
for retention_days in to_tag_retention.keys():
delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
delete_fmt = delete_date.strftime('%Y-%m-%d')
print "Will delete %d snapshots on %s" % (len(to_tag_retention[retention_days]), delete_fmt)
ec.create_tags(
Resources=to_tag_retention[retention_days],
Tags=[
{'Key': 'DeleteOn', 'Value': delete_fmt},
]
)
message = "{} instances have been backed up in region {}".format(len(instances), region)
send_to_sns('EBS Backups', message)