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 volume 1.

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.:

    […] Script Day: Automatically backup your EC2 instance using snapshots (geek.co.il) […]

  2. Vincent:

    Hello,
    Thanks for this article.
    I have created the aws-security file and then a dailybackup file inside the /etc/cron.daily/.

    If I try to run the cron manually :
    > sudo ./dailybackup
    Then I get this error :
    Required option ‘-O, –aws-access-key KEY’ missing (-h for usage)
    Failed to locate instance ID

  3. Oded:

    Weird – it sounds like the AWS tools can’t see your settings. It works for me so I don’t think the tools have been changed. Please double check your setting, and try to run the script with “bash -x” to see the command trace – likely that would give you enough information to figure out the problem.

  4. Viorel Condria:

    that is because cron doesn’t run under your user profile (sudo does the same) – hence it cannot find the AWS settings, including $path and all other AWS stuff.
    put all the AWS settings in .profile, for example, and then in front of the the croned script, just include “$HOME/.profile;”

    like:
    * * * * * $HOME/.profile; /path_to_aws_script/dailybackup

    or include the variables in the script itself.

    Hope this helps.

Leave a Reply