Automating snapshots of EC2 EBS volumes

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:



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

#Unzip the downloaded file


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-* /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

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
	"Statement": [
			"Action": [
			"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

#Make the downloaded file executable by everyone
chmod +x

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
Let’s download the file and modify it according to our specific needs:

#Download the example file

#Make the downloaded file executable by everyone
chmod +x

Now edit the script so custom variables are available to cron
→ (don’t forget to add your Access/Secret key)
Our edited 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/ -r eu-west-1 -s tag -t 'Backup=true' -k 7 -p -n -c /usr/local/ec2/scripts/

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

, , , , , , , ,

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

    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

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


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)

info @

+32 3 450 67 18

Cloudar NV – HQ

Veldkant 33A
2550 Kontich (Antwerp)

VAT BE0564 763 890

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

    • SHARE