Skip to content

Instantly share code, notes, and snippets.

@wesdeboer
Created May 28, 2013 22:43
Show Gist options
  • Save wesdeboer/5666724 to your computer and use it in GitHub Desktop.
Save wesdeboer/5666724 to your computer and use it in GitHub Desktop.
Amazon EC2 EBS Backup
Simple python script to take snapshots of ebs volumes daily/monthly and allow delete expired (10 days for daily, 120 days for monthly)
Ex:
python snapshot.py -m [daily|monthly] -v [vol-XXXXXX] -d 'description'
#!/usr/bin/env python
# 2010-12-2, murat@invokemedia.com
import boto.ec2
import os, sys
from optparse import OptionParser
from datetime import datetime, timedelta
aws_access_key_id = ''
aws_secret_access_key = ''
region = 'us-east-1'
class SnapshotManager:
def __init__(self, _aws_access_key_id, _aws_secret_access_key, region='us-east-1'):
os.environ['AWS_ACCESS_KEY_ID'] = _aws_access_key_id
os.environ['AWS_SECRET_ACCESS_KEY'] = _aws_secret_access_key
self.region = region
self.ec2 = boto.ec2.connect_to_region(self.region)
def parse_date(self, snapshot_date):
# date format: 2010-01-30T16:55:03.000Z
return datetime.strptime(snapshot_date, "%Y-%m-%dT%H:%M:%S.000Z")
def check_volume_exists(self, volume_id):
try:
self.ec2.get_all_volumes(volume_id)
return True
except Exception:
return False
def get_snapshots_for_volume(self, volume_id):
snapshots_by_volume = []
for snapshot in self.ec2.get_all_snapshots():
if(snapshot.volume_id==volume_id):
snapshots_by_volume.append(snapshot)
return snapshots_by_volume
def delete_expired(self, rotate_volume_id):
num_deleted = 0
for snapshot in self.get_snapshots_for_volume(rotate_volume_id):
snap_time = self.parse_date(snapshot.start_time)
current_time = datetime.now()
if "(daily)" in snapshot.description:
if snap_time < current_time - timedelta(days=10): # snapshot older than 10 days
self.ec2.delete_snapshot(snapshot.id)
num_deleted += 1
if "(monthly)" in snapshot.description:
if snap_time < current_time - timedelta(days=120): # snapshot 4 months or older
self.ec2.delete_snapshot(snapshot.id)
num_deleted += 1
return num_deleted
def create_daily_snapshot(self, volume_id, description):
return self.ec2.create_snapshot(volume_id, "(daily) "+description)
def create_monthly_snapshot(self, volume_id, description):
return self.ec2.create_snapshot(volume_id, "(monthly) "+description)
if __name__ == "__main__":
parser = OptionParser(description='Amazon EBS volume snapshot rotations. This script has three use cases: take daily snapshot, take monthly snapshot, and remove expired snapshots (rotate).')
parser.add_option('-m', '--snapshot-mode', dest='mode', help="Set the snapshot to be created as 'daily' or 'monthly'.")
parser.add_option('-v', '--volume', dest='volume', help='EBS Volume id (e.g. vol-995849f2)')
parser.add_option('--delete', dest='delete', action='store_true', help='Delete expired snapshots')
parser.add_option('-d', '--description', dest='description', help='Snapshot description')
(options, args) = parser.parse_args()
print "----- " + __file__ + " " + datetime.now().strftime("%Y-%m-%d, %H:%M:%S") + " ----- use option [-h] for help"
sm = SnapshotManager(aws_access_key_id, aws_secret_access_key, region)
description = options.description
if options.volume:
volume_id = options.volume
if not sm.check_volume_exists(volume_id):
print "Volume ID " + volume_id + " does not exist in your account. (region: " + sm.region + ")"
sys.exit(-1)
else:
print "Using volume "+volume_id
if options.mode:
if not description:
print "Please enter a description [-d]"
sys.exit(-1)
mode = options.mode
if mode == 'daily':
daily_snapshot = sm.create_daily_snapshot(volume_id, description)
if daily_snapshot:
print "Created new daily snapshot: " + daily_snapshot.id + " (" + description + ")"
else:
print "Failed to create daily snapshot for volume " + volume_id
elif mode == 'monthly':
monthly_snapshot = sm.create_monthly_snapshot(volume_id, description)
if monthly_snapshot:
print "Created new monthly snapshot: " + monthly_snapshot.id + " (" + description + ")"
else:
print "Failed to create monthly snapshot for volume " + volume_id
else:
print "Snapshot mode must be set to 'daily' or 'monthly'."
sys.exit(-1)
if options.delete:
num_deleted = sm.delete_expired(volume_id)
print "Deleted {0} snapshots during rotation".format(num_deleted)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment