Automating snapshots of EC2 EBS volumes

08/09/2014
Posted in AWS Blog
08/09/2014 Bart Van Hecke

Note: We stopped using this script, and started using Ansible to create snapshots. You can read more about that here.

Recently we were looking for a way to have our EC2 EBS volumes snapshotted on a daily basis. Although AWS makes it easy to take snapshots of your EBS volumes, this requires some manual intervention and thus prone to human error.
As we love to automate as much as possible (we firmly believe in the ‘set & forget’ principle), we were looking for a way to script the AWS snapshotting mechanism. A quick Google search showed us that there already many solutions available that can handle this. However, one of these really drew our attention: The ec2-automate-backup script by Collin Johnson. The script has it all:

  • snapshot one specific volume or all volumes
  • Choose which volumes to backup
  • Backup volumes for as specific region
  • Snapshot retention: delete snapshots older than x days

To handle automated snapshots on a daily basis of all our EBS volumes, we’ve setup a t1.micro EC2 instance (running CentOS 6.5) on which we created a cron job that runs daily, inventarises all volumes and snapshots only those volumes that have a Backup TAG value set to TRUE. Snapshots are being retained for 7 days by default. If the script detects snapshots older than 7 days, they will be deleted.

This is how we’ve set this up:

Prerequisites

Java

The Amazon EC2 CLI tools require Java. If you don’t have Java 1.7 or later installed, download and install Java as shown below:

yum install java-1.7.0-openjdk

Run the file command recursively to find the binary:

file $(which java)

→ example output: /usr/bin/java: symbolic link to ‘/etc/alternatives/java’

The ‘/usr/bin/java location’ is actually a link to ‘/etc/alternatives/java’, so you need to run the file command on that location to see whether that is the real binary:

file /etc/alternatives/java

→ example output: /etc/alternatives/java: symbolic link to `/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java’

This returns a new location, which is the actual binary. Verify this by running the file command on this location:

file /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java

→ example output: /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
This location is the actual binary. The Java home directory is where bin/java lives; in this example, the Java home directory is ‘/usr/lib/jvm/jre-1.7.0-openjdk.x86_64’.

You will now have to set the JAVA_HOME variable to the full path of the Java home directory:

export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64

You can verify your JAVA_HOME setting using this command:

$JAVA_HOME/bin/java -version

That’s it. We can now continue installing the AWS EC2 CLI tools.

 

Amazon EC2 CLI Tools

Download EC2 API tools

#Go to temp directory
cd /tmp

#Download the latest version of the EC2 CLI tools
wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip

#Unzip the downloaded file
unzip ec2-api-tools.zip

 

Install EC2 API tools

#Create directory to install the EC2 CLI tools
mkdir /usr/local/ec2/apitools

#Move the downloaded tools to custom directory (replace version with your own version if other)
mv ec2-api-tools-1.7.1.1/* /usr/local/ec2/apitools

 

Set variables

#Set the EC2_HOME environment variable:
export EC2_HOME=/usr/local/ec2/apitools

#Update the PATH environment variable
export PATH=$PATH:$EC2_HOME/bin

 

Add variables to startup script, so they are widely available (Optional)

#Go to profile.d directory
cd etc/profile.d

#Create a new bash script
vi aws.sh

You can now add the variables into the script (we use vi as default editor):

export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64
export EC2_HOME=/usr/local/ec2/apitools
export PATH=$PATH:$EC2_HOME/bin

Save and close the file

Create IAM Backup User

It’s a common best practice to create a separate account with limited access rights for these kind of purpose.

  • Go to the IAM Console
  • Create a user “backup-ebs-user” (or a name of your own choice)

→ Follow the AWS instructions for adding a new IAM User
→ Take a note of the user and security credentials for future usage

  • Assign policy to the backup user, so only required access rights are assigned to the user

→ Follow AWS instructions for an overview of the IAM user polices

  • Below is a sample policy that contains the IAM permissions required to run ec2-automate-backup.sh
{
	"Statement": [
		{
			"Action": [
				"ec2:DescribeVolumes",
				"ec2:CreateSnapshot",
				"ec2:DescribeSnapshots",
				"ec2:DeleteSnapshot",
				"ec2:CreateTags",
				"ec2:DescribeTags"
			],
			"Effect": "Allow",
			"Resource": [
				"*"
			]
		}
	]
}

 

Install the ec2-automate-backup script

#Go to EC2 directory
cd /usr/local/ec2

#Create script directory
Mkdir scripts

#Go to script directory
Cd scripts

# Download the script
wget https://raw.githubusercontent.com/colinbjohnson/aws-missing-tools/master/ec2-automate-backup/ec2-automate-backup.sh

#Make the downloaded file executable by everyone
chmod +x ec2-automate-backup.sh

The ec2-automate-backup script allows you to specify a source file for environmental configuration. This is interesting for running the script as a cronjob. An example cron primer file is located at https://github.com/colinbjohnson/aws-missing-tools/tree/master/ec2-automate-backup/Resources.
Let’s download the file and modify it according to our specific needs:

#Download the cron-primer.sh example file
wget https://raw.githubusercontent.com/colinbjohnson/aws-missing-tools/master/ec2-automate-backup/Resources/cron-primer.sh

#Make the downloaded file executable by everyone
chmod +x cron-primer.sh

Now edit the cron-primer.sh script so custom variables are available to cron
→ (don’t forget to add your Access/Secret key)
Our edited cron-primer.sh file:

#!/bin/bash -
# EC2_HOME required for EC2 API Tools
export EC2_HOME=/usr/local/ec2/apitools
# JAVA_HOME required for EC2 API Tools
export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64
# export PATH=/bin is required for cut, date, grep
# export PATH=/opt/aws/bin/ is required for EC2 API Tools
export PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/ec2/apitools/bin/
export AWS_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxx
export AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxx

 

Add custom Backup TAG to your EBS Volumes

Because we only want to backup the volumes that have a Backup Tag value set to ‘true’, we need to add these tags to our EBS volumes. This has the advantage of leaving the scripts untouched and it enables us to manage the volumes we want snapshot through the AWS console.
Just add the Backup TAG and set its value to ‘true’ as shown in the example below:

Backup Tags

 

Create Cron job

In the example below, we created a cron job that runs daily at 03:00AM.

0 03 * * * /usr/local/ec2/scripts/ec2-automate-backup.sh -r eu-west-1 -s tag -t 'Backup=true' -k 7 -p -n -c /usr/local/ec2/scripts/cron-primer.sh

This cron job creates a snapshot of all EBS volumes which reside in the ‘eu-west-1’ region and that have the Backup Tag value set to ‘true’. Snapshots are being retained for 7 days.

We hope this blogpost can be of some assistance in helping you to automate some manual tasks. Feel free to comment or modify the script for your own purposes.

References we used

https://github.com/colinbjohnson/aws-missing-tools/tree/master/ec2-automate-backup

http://docs.aws.amazon.com/AWSEC2/latest/CommandLineReference/set-up-ec2-cli-linux.html

  • SHARE
, , , , , , , ,

Comments (9)

  1. Avatar

    Thanks for your contribution! It works perfect!
    I just had to change the tag -t ‘Backup=true’ by tag -t ‘Backup,Values=true’ . Otherwise describe-volumes didn’t detect my volumes with tag Backup on true.

  2. Avatar
    Wes

    Hi Roger,

    I finally got it working, however, I would like the name of all my instances to be included, in the snapshot, as volume-id is less desirable. how would I modify the code to do this?

  3. Avatar
    trent

    No unmounting or freezing of the filesystem as AWS recommends? The script unfortunately isn’t that useful to run centrally since it can’t go freeze all the filesystems while the snapshot runs.

  4. Avatar
    Ben Bridts

    Hi Trent,

    The snapshots are indeed not guaranteed to be consistent. They will only contain the data that’s written to disk. If you require consistency when creating snapshots (eg. for your database servers), have a look at https://github.com/alestic/ec2-consistent-snapshot . The setup is more complex though.

    Recently we stopped using this script, and started using Ansible to create snapshots. You can read more about that here: https://cloudar.be/awsblog/instance-and-snapshot-management-with-ansible/ . The Ansible modules do not support consistent snapshots at the moment, but it’s definitely something we want to implement in the future.

Leave a Reply

Your email address will not be published. Required fields are marked *

LET'S WORK
TOGETHER

Need a hand? Or a high five?
Feel free to visit our offices and come say hi
… or just drop us a message

We are ready when you are

Cloudar NV – Operations

Veldkant 7
2550 Kontich (Antwerp)
Belgium

info @ cloudar.be

+32 3 450 67 18

Cloudar NV – HQ

Veldkant 33A
2550 Kontich (Antwerp)
Belgium

VAT BE0564 763 890

    This contact form is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

    contact
    • SHARE