Automatically Backup EBS Volumes with PHP and Amazon Command Line Tools

Recently we had need to implement some automated backups for our EBS volumes on Amazon Web Services, so I wrote a small script to do just that, using the AWS Command Line Tools.

I don't do a lot of PHP programming these days, but sometimes I do like it for a good shell script. That said, you could easily follow the same process below with any scripting language without too much difficultly.

The first step in this process is to log in to your AWS Management Console and go to your list of EBS volumes ("EC2" > "Volumes"). From this list, select the volumes you want to back up.

In the properties panel, click "Tags", then "Add/Edit Tags". Click the "Create Tag" button and add a new tag to signify that this volume should be backed up automatically. Let's call it "BackupDaily." Just set the value to "true" for now. At we really care about is that the tag exists.

Don't forget to save when you're done.

Next up, if you haven't done so, install the AWS Command Line tools on one of your EC2 instances.

cd ~
wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

Next, configure the tools - You'll need to have an IAM user for this. If you haven't done that already, you can read all about it here

There are a lot of ways to configure the tools, but perhaps the easiest is just to run aws configure and fill out the fields when prompted. For the default region, you should select the region where your EBS volumes reside. For the output format, you can just use "text" for now.

Next, you're ready to install the backup.php script. Just save it to your home directory. Here it is in all its glory. Its very short:

<?php

$date = date("Y-m-d");

$volumes = `aws ec2 describe-volumes --output json`;

$volumes = json_decode($volumes);

$backup_list = array();

foreach($volumes->Volumes as $vol) {
  if(isset($vol->Tags)) {
    foreach($vol->Tags as $tag) {
      if ($tag->Key == "BackupDaily") {
        $backup_list[] = $vol->VolumeId;
      }
    }
  }
}

foreach($backup_list as $id) {
  `aws ec2 create-snapshot --volume-id $id --description "Automated backup for $date."`;
}

Let's run through what it does real quick.

  1. First, it sets today's date to use later.
  2. Next, it uses the AWS CLI to get a JSON array of all volumes and parses that into a PHP object.
  3. Next, it iterates through that and looks for volums that have the "BackupDaily" flag set. If the flag is present, it pushes that volume's ID into a master list of volumes to back up.
  4. Once it's done that, it loops through the list of volumes that need backing up and executes the aws ec2 create-snapshot command.

And that's pretty much all there is to it. You can now manually run this whenever you like, or you can create a cron job using crontab -e to automatically run the backups.

Like so:

0 0 * * * /usr/bin/php -q ~/backup.php >> /dev/null 2>&1

Now Cron will run the EBS backup script every night at midnight.

Kelli Shaver

Kelli is a full-stack developer with over 15 years of experience. She's also the lead developer at StickyAlbums and the co-host of the Terrifying Robot Dog Podcast.