- Newest
- Most votes
- Most comments
Hello.
The following if statement retrieves the number of snapshots specified by "count" from the "snapshots" variable.
Your code currently has "NUM_SNAPSHOTS" set to 2, which means it will copy two of the most recent snapshots.
# Copy the newest 'count' snapshots
for i, snapshot in enumerate(snapshots[:count]):
if i >= count:
break
If you only want to copy the most recent one, there is no need for "for i, snapshot in enumerate(snapshots[:count]):".
As stated in the AI automated response from re:Post Agent, you can copy the first latest snapshot by getting "snapshots[0]".
So, the "copy_latest_snapshots" function would look like this:
def copy_latest_snapshots(source_rds, dest_rds):
# Define the database names based on your example
# "amgen", "alpine"
db_names = [
"db-drtest20250410", "db-drtest20240314"
]
for db_name in db_names:
# Get all automated snapshots in source region
response = source_rds.describe_db_snapshots(
DBInstanceIdentifier=db_name,
SnapshotType='automated'
)
# Sort snapshots by creation time (newest first)
snapshots = sorted(response['DBSnapshots'],
key=lambda s: s['SnapshotCreateTime'],
reverse=True
)
# Get today's date for naming
today = datetime.now().strftime("%Y-%m-%d")
# Copy the newest 'count' snapshots
if snapshots:
snapshot = snapshots[0]
source_snapshot_id = snapshot['DBSnapshotIdentifier']
# Create target snapshot name
target_snapshot_id = f"copy-rds-{db_name}-{today}"
print(f"Copying snapshot {source_snapshot_id} to {target_snapshot_id}")
try:
# Create ARN for source snapshot
source_arn = snapshot['DBSnapshotArn']
# Copy the snapshot
dest_rds.copy_db_snapshot(
SourceDBSnapshotIdentifier=source_arn,
TargetDBSnapshotIdentifier=target_snapshot_id,
KmsKeyId="arn:aws:kms:us-west-2:910286192445:key/mrk-6dae29119b094afaa3b9ed67c781ab3c",
SourceRegion=SOURCE_REGION
)
print(f"Successfully initiated copy of {source_snapshot_id} to {target_snapshot_id}")
except Exception as e:
print(f"Error copying snapshot {source_snapshot_id}: {str(e)}")
By the way, if you want to create a specified number of copies from the latest snapshot, you will need to modify "target_snapshot_id = f"copy-rds-{db_name}-{today}"" so that it becomes a unique value.
For example, if you include the date and time in the snapshot name, there will be no duplication unless they are executed at the same time.
today = datetime.now().strftime("%Y-%m-%d-%H%M%S")
You could also add a process to check for duplicate names.
You can also add a number to the end of the snapshot name if there are duplicates by adding a process to check for duplicates as shown below.
def copy_latest_snapshots(source_rds, dest_rds, count):
# Define the database names based on your example
# "amgen", "alpine"
db_names = [
"db-drtest20250410", "db-drtest20240314"
]
for db_name in db_names:
# Get all automated snapshots in source region
response = source_rds.describe_db_snapshots(
DBInstanceIdentifier=db_name,
SnapshotType='automated'
)
# Sort snapshots by creation time (newest first)
snapshots = sorted(response['DBSnapshots'],
key=lambda s: s['SnapshotCreateTime'],
reverse=True
)
# Get today's date for naming
today = datetime.now().strftime("%Y-%m-%d")
# Copy the newest 'count' snapshots
for i, snapshot in enumerate(snapshots[:count]):
if i >= count:
break
source_snapshot_id = snapshot['DBSnapshotIdentifier']
# Create target snapshot name
base_snapshot_id = f"copy-rds-{db_name}-{today}"
target_snapshot_id = f"copy-rds-{db_name}-{today}"
# Name Duplicate check
index = 1
while True:
existing_snapshots = rds.describe_db_snapshots(
DBSnapshotIdentifier=target_snapshot_id,
SnapshotType='manual'
)
if not existing_snapshots["DBSnapshots"]:
break
target_snapshot_id = f"{base_snapshot_id}-{index}"
index += 1
print(f"Copying snapshot {source_snapshot_id} to {target_snapshot_id}")
try:
# Create ARN for source snapshot
source_arn = snapshot['DBSnapshotArn']
# Copy the snapshot
dest_rds.copy_db_snapshot(
SourceDBSnapshotIdentifier=source_arn,
TargetDBSnapshotIdentifier=target_snapshot_id,
KmsKeyId="arn:aws:kms:us-west-2:910286192445:key/mrk-6dae29119b094afaa3b9ed67c781ab3c",
SourceRegion=SOURCE_REGION
)
print(f"Successfully initiated copy of {source_snapshot_id} to {target_snapshot_id}")
except Exception as e:
print(f"Error copying snapshot {source_snapshot_id}: {str(e)}")
The issue in your Lambda function is related to how you're processing snapshots in the copy_latest_snapshots function. The problem occurs because you're retrieving multiple snapshots for each database and then trying to copy all of them up to the count limit, but you're using the same target snapshot name for all copies from the same database.
Here's what's happening:
- For each database in
db_names, you retrieve all automated snapshots - You sort them by creation time (newest first)
- You then try to copy the newest
count(2) snapshots for each database - However, you're using the same target name (
copy-rds-{db_name}-{today}) for all snapshots from the same database
Since you only want to copy the single most recent snapshot for each database, you need to modify your code to only process the first snapshot in the sorted list.
Change this part of your code:
# Copy the newest 'count' snapshots for i, snapshot in enumerate(snapshots[:count]): if i >= count: break
To this:
# Copy only the newest snapshot if snapshots: snapshot = snapshots[0] # Get only the most recent snapshot
This way, for each database, you'll only copy the single most recent snapshot instead of trying to copy multiple snapshots with the same target name. This will prevent the "DBSnapshotAlreadyExists" error you're seeing.
Additionally, make sure your NUM_SNAPSHOTS variable is set correctly. Since you're only copying one snapshot per database and you have two databases, you might want to set it to 1 to be clearer about your intent.
Sources
Copied snapshot is being deleted after creation by DLM | AWS re:Post
How to automate daily delete snapshots and automate daily copy snapshots between regions | AWS re:Post
How to automate coping snapshots from N.California to Oregon? | AWS re:Post
Relevant content
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated a year ago

Thank you again Riku for all your help! My test lambda function/python script works like a charm. It deletes the oldest snapshot for each database in us-west-2 (manual) and then copies the most recent snapshot in us-west-2 (system) over to us-west-2 (manual) with the correct renaming format! Next, I will move on from the testing stage to trying this out in production after changing the source from us-west-2 (system generated, Oregon) to us-west-1 (system generated, N. California) and using other databases. Best Regards, Donald