Script Day: Automatically backup your EC2 instance using snapshots

The following script I install as a cron job on Amazon AWS virtual machines I deploy, to allow them to backup themselves automatically. The script uses the EC2 management utilities that are normally available on “Amazon Linux” installations (and can be easily installed on other Linux distributions) to create EBS snapshots of the current mounted root EBS volume1.

The script currently takes one snapshot of the root file system’s volume and delete all older snapshots (of the same volume) every time you run it (I just drop it in /etc/cron.daily) but it should be fairly easy to do something more interesting – such as maintaining three snapshots, one daily, one weekly and one monthly, or to backup more then just the root volume – you are welcome to post suggested fixes and I’ll integrate these if they work.

The script depends on you creating an IAM identity for use of this automation script and setting up the secret and access key for the script in a file called /etc/aws-security. The file should look something like this:


AWS_ACCESS_KEY=access-key
AWS_SECRET_KEY=secret-key

And it’s recommended to chmod the file to 0600 permissions so that only scripts with root permissions would be able to access it.

And now, here’s the entire thing:


#!/bin/bash


# initialize the EC2 environment
[ -e /etc/profile.d/aws-apitools-common.sh ] && source /etc/profile.d/aws-apitools-common.sh
# load the access keys
source /etc/aws-security


# locate the instance ID of this VM
instanceid="$(ec2-describe-instances | grep $(hostname -f) | cut -f2)"


if [ -z "$instanceid" ]; then
echo "Failed to locate instance ID" >&2
exit 5
fi


# locate the EBS volume ID for the root file system
rootvolumeid="$(ec2-describe-volumes | grep "$instanceid" | grep $(mount | egrep 'on / type' | cut -d' ' -f1 | sed -e 's/xvd/sd/;') | cut -f2)"


if [ -z "$rootvolumeid" ]; then
echo "Failed to locate root volume ID" >&2
exit 5
fi


# create the snapshot
snapshotid="$(ec2-create-snapshot -d "backup-${instanceid}-$(date +"%Y%m%d")" $rootvolumeid | cut -f2)"
#"


if [ -z "$snapshotid" ]; then
echo "Failed to take snapshot" >&2
exit 4
fi


# wait for the snapshot to complete
while [ "$(ec2-describe-snapshots | grep "$snapshotid" | cut -f4)" != "completed" ]; do
sleep 5
done


# delete old snapshots
ec2-describe-snapshots | grep "$rootvolumeid" | cut -f2 | grep -v "$snapshotid" | while read snapid; do
if ! ec2-delete-snapshot "$snapid" > /dev/null; then
echo "Failed to delete old snapshot $snapid" >&2
exit 4
fi
done

  1. I don’t expect this script to work for instances that have an instance-stored root device, but I don’t expect to encounter these any more []

4 Responses to “Script Day: Automatically backup your EC2 instance using snapshots”

  1. Automated Attached EBS Volume Backup Solution « Dream. Develop. Direct.:
    Fatal error: Uncaught Error: Call to undefined function comment_dir() in /vhosts/coil/geek/public_html/wp-content/themes/modern-bluish/single-comment2.php:17 Stack trace: #0 /vhosts/coil/geek/public_html/wp-content/themes/modern-bluish/functions.php(8): include() #1 /vhosts/coil/geek/public_html/wp-includes/class-walker-comment.php(179): themed_comment() #2 /vhosts/coil/geek/public_html/wp-includes/class-wp-walker.php(144): Walker_Comment->start_el() #3 /vhosts/coil/geek/public_html/wp-includes/class-walker-comment.php(139): Walker->display_element() #4 /vhosts/coil/geek/public_html/wp-includes/class-wp-walker.php(387): Walker_Comment->display_element() #5 /vhosts/coil/geek/public_html/wp-includes/comment-template.php(2229): Walker->paged_walk() #6 /vhosts/coil/geek/public_html/wp-content/themes/modern-bluish/comments.php(26): wp_list_comments() #7 /vhosts/coil/geek/public_html/wp-includes/comment-template.php(1539): require('/vhosts/coil/ge...') #8 /vhosts/coil/geek/public_html/wp-content/themes/modern-bluish/single.php( in /vhosts/coil/geek/public_html/wp-content/themes/modern-bluish/single-comment2.php on line 17