RDS backup event subscriptionAfter posting the previous post on this topic (Copying RDS snapshot to another region for cross-region recovery), I noticed a lot of people being interested in using the code I provided as an example. Many were not sure how to make use of it, and after a couple of pull requests it became obvious that a complete, fully-working code and CloudFormation template would be a good idea. So, yesterday, I pushed an update to aws-maintenance repository with a fully working code, which you can easily customize via CloudFormation parameters to match your needs.

The main changes include:

  1. The backup-rds.py code was moved to a separate CloudFormation template, which creates all (and only) the resources needed for the solution to work. You can now simply upload the infrastructure/templates/rds-cross-region-backup.json template to CloudFormation, fill out the parameters and have an automated cross-region snapshot copying happening all of its own!
  2. The code was updated to be triggered specifically by SNS message send by RDS “backup” events. This notifications are sent by RDS whenever the daily, automated snapshot is started and finished – the code will react to the “backup finished” event and copy the latest snapshot to the provided target region.
  3. Because of the above change, the code now only acts for a single RDS instance – copying the new snapshot for that specific instance and removing old snapshots from the target region for that specific instance.
  4. Added more comments to the code, to hopefully make it easier to understand for everyone πŸ™‚

Some notes as for what to expect:

  • The code intends to keep only 1 (latest) copy of the snapshot in the target region. Even though, you will likely notice 2 snapshots being present. This is because, the code triggers the copy to be made into the target region, but does not wait for it to be finished, before attempting to remove old snapshots (simply because this can take a long time, especially for large databases). Therefore, when the list of snapshots for the database is taken from target region, the most recent snapshot is likely to still be in progress, and the code only takes “available” (ready) snapshots into account. This is actually useful, as the operation of copying the snapshot can potentially fail to finish correctly, which would leave you without any usable snapshots for that database in the target region.
  • The snapshot in the target region will be named {source_rds_instance_name}-{source_region}-{original_snapshot_name}. The code itself relies on this name to check whether the snapshot was already copied or not. The Lambda can be executed multiple times, but will not trigger the copy if snapshot with this name already exists.
  • Only automated snapshots will be taken into account when making a copy. This means if you create a manual snapshot, it will not be copied, but it will trigger the Lambda (which may clean up the second snapshot from the target region, see point #1 above). None of this is a real issue πŸ™‚
  • (Obviously, I hope) if you disable automated snapshots on your RDS instance, this code will do nothing.

If you’re interested in seeing the exact changes made, check out this commit.

If you just want to use the solution, download the CloudFormation template and create a CloudFormation stack using it.
When creating a stack from this template, you will be asked for two required parameters: source and target regions. Source region must be the one where your RDS instance is running. The target region is the one where you want to store the copies of snapshots. Use the region IDs, not the full (human-friendly) names, so for example “eu-west-1” for Ireland. For a full list of regions where RDS is available (and their names and IDs), check out AWS documentation.

By default, the Lambda will be subscribed to notifications from all RDS instances within the source region. If you only want to limit this to specific instances, provide a comma-delimited list of the instances names in the third CloudFormation parameter (for example, “database-1,database-2” to limit the code to only those two instances). It’s helpful if all your test and production environments are in the same AWS account (though, they shouldn’t really…) and you only want to use the code for production databases.

2 people found this post helpful
Was this post helpful to you? Yes!


  1. Prashast Kumar

    This is extremely helpful and worked smoothly for me.

  2. Yros

    Greate, very good code, simple usage. Thank you very much!!

  3. Charles Schultz

    Thanks, Paulina, this has been exceptionally helpful; you have boiled it down to some really easy-to-implement steps, which are great.

    Quick question on the setup (from someone who is relatively new to AWS, and very new to IAM) – what is the minimum set of privileges needed to run this operation? What is the “least privileges necessary”? I was not able to find a predefined policy that allowed my test to run, and I ended opting for godlike powers just to see what it did.

    • Paulina Budzon

      Hi Charles!
      You can see the IAM policy attached to Lambda in the CloudFormation template. You can probably experiment with limiting the RDS permissions only to specific databases and their snapshots, if you’re using that parameter as well. Hope this helps!

  4. Laurie Kepford

    I want to keep all my snapshots in the new for 7 years. Can I do that by modifying this line: DEFAULT_RETENTION = 7

    • Paulina Budzon

      Hi Laurie.

      I’m assuming you’re talking about the EBS snapshot Lambda (https://github.com/pbudzon/aws-maintenance/blob/master/ebs-snapshots.py), not the RDS cross-region backup one πŸ™‚
      You can either set the “Backup” tag on the volumes to number of days, other than 7, that you’d like to keep the snapshots for, or if you want to use a different value on all your snapshots, then yes you can change the DEFAULT_RETENTION value directly in the code.

Leave a comment