Skip to content

How to automate coping snapshots from N.California to Oregon?

0

Hi re:Post,

Thank you for your time and help!

Everyday we manually delete the oldest (10) snapshot manual copies in Oregon.

Then we manually copy the latest (10) system generated snapshots from N. California to Oregon region.

It's the same set of (10) RDS snapshot we delete and same (10) RDS snapshots we copy everyday.

Is there a way we could automate this process ?

Thank you!

Best Regards,

Donald

2 Answers
1
Accepted Answer

Hey DC, of course.

You can use a Lambda function to perform these steps easily. Write a lambda funtion as follows to copy the snapshot from 1 region to another and then delete snapshots in the 2nd region that are older than 10 days old. You can schedule the lambda function to run using amazon eventbridge scheduler to run daily.

import boto3
import os
from datetime import datetime, timedelta

# Environment variables for flexibility
SOURCE_REGION = os.getenv("SOURCE_REGION", "us-east-1")
DEST_REGION = os.getenv("DEST_REGION", "us-west-2")
RETENTION_DAYS = int(os.getenv("RETENTION_DAYS", 10))

def get_latest_system_snapshot(rds_client):
    """Fetch the latest RDS system snapshot in the source region."""
    response = rds_client.describe_db_snapshots(SnapshotType='automated')
    snapshots = response['DBSnapshots']
    
    if not snapshots:
        raise Exception("No system snapshots found in the source region.")

    latest_snapshot = max(snapshots, key=lambda s: s['SnapshotCreateTime'])
    return latest_snapshot

def copy_snapshot(latest_snapshot, source_region, dest_region):
    """Copy the latest snapshot to the destination region."""
    snapshot_identifier = latest_snapshot['DBSnapshotIdentifier']
    target_snapshot_id = f"{snapshot_identifier}-copy-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
    
    dest_rds_client = boto3.client('rds', region_name=dest_region)
    
    print(f"Copying snapshot {snapshot_identifier} to {dest_region} as {target_snapshot_id}")
    
    response = dest_rds_client.copy_db_snapshot(
        SourceDBSnapshotIdentifier=f"arn:aws:rds:{source_region}:{latest_snapshot['DBInstanceIdentifier']}:{snapshot_identifier}",
        TargetDBSnapshotIdentifier=target_snapshot_id,
        SourceRegion=source_region
    )
    return response

def delete_old_snapshots(dest_rds_client, retention_days):
    """Delete snapshots in the destination region older than the retention period."""
    cutoff_date = datetime.utcnow() - timedelta(days=retention_days)
    
    response = dest_rds_client.describe_db_snapshots(SnapshotType='manual')
    snapshots = response['DBSnapshots']
    
    for snapshot in snapshots:
        snapshot_time = snapshot['SnapshotCreateTime']
        snapshot_id = snapshot['DBSnapshotIdentifier']
        
        if snapshot_time < cutoff_date:
            print(f"Deleting old snapshot: {snapshot_id} created on {snapshot_time}")
            dest_rds_client.delete_db_snapshot(DBSnapshotIdentifier=snapshot_id)

def lambda_handler(event, context):
    try:
        # Create RDS clients
        source_rds_client = boto3.client('rds', region_name=SOURCE_REGION)
        dest_rds_client = boto3.client('rds', region_name=DEST_REGION)

        # Get the latest system snapshot and copy it
        latest_snapshot = get_latest_system_snapshot(source_rds_client)
        copy_snapshot(latest_snapshot, SOURCE_REGION, DEST_REGION)

        # Delete old snapshots in the destination region
        delete_old_snapshots(dest_rds_client, RETENTION_DAYS)

        return {"status": "success", "message": "Snapshot copied and old snapshots deleted."}
    except Exception as e:
        print(f"Error: {e}")
        return {"status": "error", "message": str(e)}

Prerequisites

  1. IAM Role: Attach policies like AmazonRDSFullAccess or custom policies that allow the following actions:
  • rds:DescribeDBSnapshots
  • rds:CopyDBSnapshot
  • rds:DeleteDBSnapshot

2.Environment Variables (Optional):

  • SOURCE_REGION: The region where the RDS system snapshot resides.
  • DEST_REGION: The region where you want to copy the snapshot.
  • RETENTION_DAYS: Number of days to keep snapshots in the destination region

Environment Variables:

Configure the SOURCE_REGION, DEST_REGION, and RETENTION_DAYS as needed in your Lambda function settings.

Timeout:

Set the Lambda timeout to at least 5 minutes, as copying snapshots can take some time depending on the size.

Testing the Script Event Payload: You can trigger the Lambda function with a simple test event, e.g.:

{}

Eventbridge Scheduler https://docs.aws.amazon.com/eventbridge/latest/userguide/using-eventbridge-scheduler.html

EXPERT

answered 2 years ago

EXPERT

reviewed 2 years ago

  • Thank you very much Gary for your help and thorough lambda function script ! Best Regards, Donald

1

On RDS you can set the number of days you want to retain your backups and you can enable replication in another AWS Region.

Enable Backup replication and set Replicated backup retention period to 10 days.

answered 2 years ago

EXPERT

reviewed 2 years ago

  • Thank you very much darksama21 for your help and suggestion of enabling back replication - we are considering this option as well ! In case anyone comes across this - the 10 snapshot deletes we are doing is because AWS has a limit of 100 manual snapshot copies per region. So in order to add 10 new snaps per day we must first delete the 10 oldest.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.