Created
May 28, 2013 22:43
-
-
Save wesdeboer/5666724 to your computer and use it in GitHub Desktop.
Amazon EC2 EBS Backup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# 2010-12-2, [email protected] | |
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