Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
AWS EC2 automatic volume daily snapshot.

How to create daily HDD/EBS snapshot of you AWS EC2 instance

It looks like a very required and trivial task. But there is not outof the box solution in AWS. But fortunately it is easy to setup with few steps.

How to setup

  1. Opent SSH connection to your server.

  2. Navigate to folder

     $ cd /usr/local/
    
  3. Clon this gist

     $ git clone https://gist.github.com/9738785.git ec2
    
  4. Go to that folder

     $ cd ec2
    
  5. Make backup.php executable

     $ chmod +x backup.php
    
  6. Open releases of the AWS PHP SDK github project and copy URL of aws.zip button. Now download it into your server.

     $ wget http://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
    
  7. Unzip this file into aws directory.

     $ unzip aws.zip -d aws 
    
  8. Edit backup.php php file and set all settings in line 5-12

     $dryrun     = FALSE;
     $interval   = '24 hours';
     $keep_for   = '10 Days';
     $volumes    = array('vol-********');
     $api_key    = '*********************';
     $api_secret = '****************************************';
     $ec2_region = 'us-east-1';
     $snap_descr = "Daily backup";
    
  9. Test it. Run this script

     $ ./backup.php
    

    Test is snapshot was created.

  10. If everything is ok just add cronjob.

    * 23 * * * /usr/local/ec2/backup.php
    
#!/usr/bin/php -q
<?php
date_default_timezone_set('UCT');
$dryrun = FALSE;
$interval = '24 hours';
$keep_for = '10 Days';
$volumes = array('vol-9677d14a');
$api_key = 'AKI****EYUA';
$api_secret = 'IzMni****ct';
$ec2_region = 'us-east-1';
$snap_descr = "Daily backup";
require 'aws/aws-autoloader.php';
use Aws\Ec2\Ec2Client;
$client = new Ec2Client(
array(
'credentials' => array(
'key' => $api_key,
'secret' => $api_secret
),
'version' => 'latest',
'region' => $ec2_region
)
);
$db = json_decode(file_get_contents(__DIR__ . '/db.json'), TRUE);
$snapshots = array();
foreach($db AS $key => $snapshot)
{
if(!empty($snapshots[$snapshot['volume']]))
{
if($snapshot['time'] > $snapshots[$snapshot['volume']]['time'])
{
$snapshots[$snapshot['volume']] = $snapshot;
}
}
else
{
$snapshots[$snapshot['volume']] = $snapshot;
}
if($snapshot['time'] < strtotime('- ' . $keep_for))
{
$client->deleteSnapshot(
array(
'DryRun' => $dryrun,
'SnapshotId' => $snapshot['id'],
)
);
unset($db[$key]);
}
}
foreach($volumes As $volume)
{
if((!empty($snapshots[$volume])) && ($snapshots[$volume]['time'] > strtotime('-' . $interval)))
{
continue;
}
$result = $client->createSnapshot(
array(
'DryRun' => $dryrun,
'VolumeId' => $volume,
'Description' => $snap_descr,
)
);
$db[] = array(
'volume' => $volume,
'time' => strtotime($result['StartTime']),
'id' => $result['SnapshotId']
);
}
file_put_contents(__DIR__ . '/db.json', json_encode($db));
return;
@JavierParral

This comment has been minimized.

Copy link

JavierParral commented Aug 10, 2015

Tks for the code but i got a question about the $api_key and $api_secret ? where do i get those.

@xyulex

This comment has been minimized.

Copy link

xyulex commented Dec 29, 2015

Thanks for your script, it was really helpful!

@atlkuk

This comment has been minimized.

Copy link

atlkuk commented Sep 6, 2016

Hello,
I can not make it work , I configure all the settings but it gives me the following error:
" AuthFailure ( client ) : AWS was not incendio validate the provided access credentials "

even though I set the right key and secret , but it's as if I did not authorize even if I set as AmazonEC2FullAccess policy .

the region should be eu -central- 1 . what could be your problem?

@Serhioromano

This comment has been minimized.

Copy link
Owner Author

Serhioromano commented Nov 9, 2016

@atlkuk Ok it looks like I have the same error. Investigating....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.