Skip to content

Commit 4ce6760

Browse files
author
Dave Osment
committed
Adding correct version of 'ebs-snapshot-creator'
1 parent a84b0d0 commit 4ce6760

File tree

1 file changed

+125
-128
lines changed

1 file changed

+125
-128
lines changed

ebs-snapshot-creator.py

Lines changed: 125 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,138 @@
11
import boto3
2-
import collections
3-
import datetime
4-
import os
5-
6-
ec = boto3.client('ec2')
7-
8-
def lambda_handler(event, context):
9-
10-
# Get Current Region
11-
aws_region = os.getenv('AWS_REGION')
12-
13-
# Get Retention Period From Environment Variable Or Assume Default If Not Specified
14-
retention_days = int(
15-
os.getenv(
16-
'RETENTION_DAYS',
17-
7
18-
)
19-
)
20-
21-
print "Setting SnapShot retention period To %s days" % (retention_days)
22-
23-
# Determine Which Instances To SnapShot
24-
instances = ec.describe_instances(
25-
Filters=[
26-
{ 'Name': 'tag:Backup', 'Values': ['Yes'] },
27-
]
28-
).get(
29-
'Reservations', []
30-
)
31-
32-
print "Found %d instances that need backing up" % len(instances[0]['Instances'])
33-
34-
# Initialise Dictionary Objects To Store Tags In
35-
to_tag = collections.defaultdict(list)
36-
37-
# Iterate Over Each Instance & SnapShot Volumes Not Explicitly Excluded From Backups
38-
for instance in instances[0]['Instances']:
39-
40-
# List All Volumes Attached To The Instance
41-
for dev in instance['BlockDeviceMappings']:
42-
43-
# Set Variable Defaults
44-
snapshot_required = True
45-
volume_name = None
46-
47-
if dev.get('Ebs', None) is None:
48-
continue
49-
vol_id = dev['Ebs']['VolumeId']
50-
dev_name = dev['DeviceName']
51-
52-
# Get a Volume Object Based Upon Volume ID
53-
volume = ec.describe_volumes(
54-
VolumeIds=[vol_id,]
55-
)
56-
57-
vol = volume['Volumes'][0]
58-
if 'Tags' in vol:
59-
for tag in vol['Tags']:
60-
61-
# Determine If Volume Has 'Backup' Flag Set To 'No' & Exclude From SnapShot If It Does
62-
if tag['Key'] == 'Backup' and tag['Value'] == 'No':
63-
snapshot_required = False
64-
65-
# Determine If Volume Has a Name Specified
66-
if tag['Key'] == 'Name':
67-
volume_name = tag['Value']
68-
69-
# Exit This Loop If SnapShot Not Required
70-
if snapshot_required == False:
71-
print "\tIgnoring EBS volume %s (%s) on instance %s - 'Backup' Tag set to 'No'" % (
72-
vol_id,
73-
dev_name,
74-
instance['InstanceId']
75-
)
76-
77-
else:
78-
print "\tFound EBS volume %s (%s) on instance %s - Proceeding with SnapShot" % (
79-
vol_id,
80-
dev_name,
81-
instance['InstanceId']
82-
)
83-
84-
# Determine EC2 Instance Name (If Present)
2+
import collections
3+
import datetime
4+
import os
5+
6+
ec = boto3.client('ec2')
7+
8+
def lambda_handler(event, context):
9+
10+
# Get Current Region
11+
aws_region = os.getenv('AWS_REGION')
12+
13+
# Determine Which Instances To SnapShot
14+
instances = ec.describe_instances(
15+
Filters=[
16+
{ 'Name': 'tag:Backup', 'Values': ['Yes'] },
17+
]
18+
).get(
19+
'Reservations', []
20+
)[0]['Instances']
21+
22+
print "Found %d instances that need backing up" % len(instances)
23+
24+
# Iterate Over Each Instance & SnapShot Volumes Not Explicitly Excluded From Backups
25+
for instance in instances:
26+
27+
# Determine Retention Period Based Upon Tags
28+
retention_days = 7
29+
destination_region = None
8530
instance_name = ""
8631
for tag in instance['Tags']:
87-
if tag['Key'] != 'Name':
88-
continue
89-
else:
90-
instance_name = tag['Value']
32+
if tag['Key'] == 'RetentionDays' and tag['Value'] > 0:
33+
retention_days = int(tag['Value'])
34+
35+
if tag['Key'] == 'DestinationRegion' and len(tag['Value']) > 0:
36+
destination_region = tag['Value']
37+
38+
if tag['Key'] == 'Name' and len(tag['Value']) > 0:
39+
instance_name = tag['Value']
40+
41+
print "Setting SnapShot retention period To %s days" % (retention_days)
42+
43+
# Determine When We're Going To Delete This SnapShot
44+
delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
45+
delete_fmt = delete_date.strftime('%Y-%m-%d')
46+
47+
# Set Default SnapShot Tags
48+
snapshot_tags = [
49+
{ 'Key': 'DeleteOn', 'Value': delete_fmt },
50+
{ 'Key': 'Type', 'Value': 'Automated' },
51+
]
52+
53+
# If We Want To Offsite This SnapShot, Set The Appropriate Tag
54+
if destination_region != None:
55+
snapshot_tags = snapshot_tags + [{ 'Key': 'DestinationRegion', 'Value': destination_region }]
56+
57+
# List All Volumes Attached To The Instance
58+
for dev in instance['BlockDeviceMappings']:
59+
60+
# Set Variable Defaults
61+
snapshot_required = True
62+
volume_name = None
63+
64+
if dev.get('Ebs', None) is None:
65+
continue
66+
vol_id = dev['Ebs']['VolumeId']
67+
dev_name = dev['DeviceName']
68+
69+
# Get a Volume Object Based Upon Volume ID
70+
volume = ec.describe_volumes(
71+
VolumeIds=[vol_id,]
72+
)['Volumes'][0]
73+
74+
# Set Default SnapShot Description
75+
description = '%s - %s (%s)' % (
76+
instance_name,
77+
vol_id,
78+
dev_name
79+
)
80+
81+
if 'Tags' in volume:
82+
for tag in volume['Tags']:
83+
84+
# Determine If Volume Has 'Backup' Flag Set To 'No' & Exclude From SnapShot If It Does
85+
if tag['Key'] == 'Backup' and tag['Value'] == 'No':
86+
snapshot_required = False
87+
88+
# Override Default Description With Volume Name If One Specified
89+
if tag['Key'] == 'Name':
90+
description = tag['Value']
91+
9192

92-
# Determine SnapShot Description (Use Volume Name If Specified)
93-
if volume_name == None:
94-
description = '%s - %s (%s)' % (
95-
instance_name,
96-
vol_id,
97-
dev_name
93+
# We Don't Want To SnapShot Any Volume Explictly Excluded
94+
if snapshot_required == False:
95+
print "\tIgnoring EBS volume %s (%s) on instance %s - 'Backup' Tag set to 'No'" % (
96+
vol_id,
97+
dev_name,
98+
instance['InstanceId']
9899
)
99-
else:
100-
description = volume_name
100+
101+
continue
102+
103+
104+
print "\tFound EBS volume %s (%s) on instance %s - Proceeding with SnapShot" % (
105+
vol_id,
106+
dev_name,
107+
instance['InstanceId']
108+
)
101109

102-
# Trigger SnapShot
103-
snap = ec.create_snapshot(
110+
# Take SnapShot Of Volume
111+
snap = ec.create_snapshot(
104112
VolumeId=vol_id,
105113
Description=description
106-
)
107-
108-
if (snap):
109-
print "\t\tSnapshot %s created in %s of [%s]" % (
110-
snap['SnapshotId'],
111-
aws_region,
112-
description
113-
)
114-
115-
# Tag The SnapShot To Facilitate Later Automated Deletion
116-
to_tag[retention_days].append(snap['SnapshotId'])
117-
118-
print "\t\tRetaining snapshot %s of volume %s from instance %s (%s) for %d days" % (
114+
)
115+
116+
if not (snap):
117+
print "\t\tSnapShot operation failed!"
118+
continue
119+
120+
print "\t\tSnapshot %s created in %s of [%s]" % (
121+
snap['SnapshotId'],
122+
aws_region,
123+
description
124+
)
125+
126+
print "\t\tRetaining snapshot %s of volume %s from instance %s (%s) for %d days" % (
119127
snap['SnapshotId'],
120128
vol_id,
121129
instance['InstanceId'],
122130
instance_name,
123131
retention_days,
124-
)
125-
126-
for retention_days in to_tag.keys():
127-
delete_date = datetime.date.today() + datetime.timedelta(days=retention_days)
128-
delete_fmt = delete_date.strftime('%Y-%m-%d')
129-
print "Will delete %d snapshots from %s on %s" % (
130-
len(to_tag[retention_days]),
131-
aws_region,
132-
delete_fmt
133-
)
134-
135-
ec.create_tags(
136-
Resources=to_tag[retention_days],
137-
Tags=[
138-
{ 'Key': 'DeleteOn', 'Value': delete_fmt },
139-
{ 'Key': 'Type', 'Value': 'Automated' },
140-
]
141-
)
132+
)
133+
134+
# Tag The SnapShot To Facilitate Later Automated Deletion & Offsiting
135+
ec.create_tags(
136+
Resources=[snap['SnapshotId']],
137+
Tags=snapshot_tags
138+
)

0 commit comments

Comments
 (0)