Skip to content

Instantly share code, notes, and snippets.

@Serhioromano
Last active February 20, 2021 10:43
Show Gist options
  • Save Serhioromano/9738785 to your computer and use it in GitHub Desktop.
Save Serhioromano/9738785 to your computer and use it in GitHub Desktop.
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
Copy link

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

@xyulex
Copy link

xyulex commented Dec 29, 2015

Thanks for your script, it was really helpful!

@atlkuk
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
Copy link
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