rfg
rfg

Reputation: 1636

Callbacks for AWS EBS Backups or Snapshots

I want to make a backup of several EBS volumes attached to a EC2. There are Snapshots and AWS Backups available.

Issue is, before I can do a backup, I must execute a special script to freeze my application.

Why: it's somewhat im-memory, so this call forces all writes to disk to comlpete and also prevents new disk writes for a duration of a backup.

Is there a way to execute an arbitrary bash script before the backup job/snapshot?

Upvotes: 0

Views: 182

Answers (1)

Ermiya Eskandary
Ermiya Eskandary

Reputation: 23642

Unfortunately, there's no native --pre-snapshot-script option for creating an EBS snapshot.

However, you could use a Lambda function, that is triggered based on a scheduled EventBridge rule, to trigger a script to be run before you then programmatically take the EBS snapshot. You'd need the SSM agent to be installed on your EC2 instance(s).

The idea is to use ssm:SendCommand and the AWS-RunShellScript managed document to run Linux shell commands on your EC2 instance(s).

You have a couple of options, specifically:

  1. if you want to inline all of your 'special script' in your Lambda function, or download it from S3 during your user data script, or manually transfer it or ...

  2. if you can run the Boto3 create_snapshot() (or the AWS CLI ec2 create-snapshot command) as part of your 'special script'. If not & you want to do it separately after doing send_command, you will also have to use the Boto3 ssm.get_command_invocation (or the AWS CLI ssm get-command-invocation command) to poll+wait for the command to finish, before you create your snapshot

What you decide to do is dependent on your specific requirements and how much infrastructure you want to manage, but the essence remains the same.

This could be a good starting point:

import boto3

def lambda_handler(event, context):
    ssm = boto3.client('ssm')

    commands = ["echo 'Command xxxxx of special script'"]

    commands.append("aws ec2 create-snapshot --volume-id vol-yyyyy")

    ssm.send_command(
        InstanceIds=['i-zzzzz'],
        DocumentName='AWS-RunShellScript',
        Parameters={'commands': commands}
    )

Upvotes: 1

Related Questions