Configure AWS RDS Automated Backups Replication

The aws:rds/instanceAutomatedBackupsReplication:InstanceAutomatedBackupsReplication resource, part of the Pulumi AWS provider, manages cross-region replication of RDS automated backups to a destination AWS region. This guide focuses on three capabilities: setting up cross-region backup replication, encrypting replicated backups with KMS, and integrating replication with RDS instance creation.

This resource must be created in the destination region and references a source RDS instance ARN from another region. Encryption requires a KMS key in the destination region. The examples are intentionally small. Combine them with your own RDS instances and KMS keys.

Replicate automated backups to another region

Disaster recovery strategies often require database backups to exist in multiple regions without manual intervention.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const _default = new aws.rds.InstanceAutomatedBackupsReplication("default", {
    sourceDbInstanceArn: "arn:aws:rds:us-west-2:123456789012:db:mydatabase",
    retentionPeriod: 14,
});
import pulumi
import pulumi_aws as aws

default = aws.rds.InstanceAutomatedBackupsReplication("default",
    source_db_instance_arn="arn:aws:rds:us-west-2:123456789012:db:mydatabase",
    retention_period=14)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := rds.NewInstanceAutomatedBackupsReplication(ctx, "default", &rds.InstanceAutomatedBackupsReplicationArgs{
			SourceDbInstanceArn: pulumi.String("arn:aws:rds:us-west-2:123456789012:db:mydatabase"),
			RetentionPeriod:     pulumi.Int(14),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var @default = new Aws.Rds.InstanceAutomatedBackupsReplication("default", new()
    {
        SourceDbInstanceArn = "arn:aws:rds:us-west-2:123456789012:db:mydatabase",
        RetentionPeriod = 14,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplication;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new InstanceAutomatedBackupsReplication("default", InstanceAutomatedBackupsReplicationArgs.builder()
            .sourceDbInstanceArn("arn:aws:rds:us-west-2:123456789012:db:mydatabase")
            .retentionPeriod(14)
            .build());

    }
}
resources:
  default:
    type: aws:rds:InstanceAutomatedBackupsReplication
    properties:
      sourceDbInstanceArn: arn:aws:rds:us-west-2:123456789012:db:mydatabase
      retentionPeriod: 14

The sourceDbInstanceArn points to your RDS instance in the source region (us-west-2 in this example). RDS copies daily automated backups to the destination region where you create this resource. The retentionPeriod controls how long replicated backups are kept; here it’s set to 14 days instead of the default 7.

Encrypt replicated backups with a KMS key

Compliance requirements often mandate encryption of backups at rest in the destination region.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const _default = new aws.rds.InstanceAutomatedBackupsReplication("default", {
    sourceDbInstanceArn: "arn:aws:rds:us-west-2:123456789012:db:mydatabase",
    kmsKeyId: "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
});
import pulumi
import pulumi_aws as aws

default = aws.rds.InstanceAutomatedBackupsReplication("default",
    source_db_instance_arn="arn:aws:rds:us-west-2:123456789012:db:mydatabase",
    kms_key_id="arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012")
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := rds.NewInstanceAutomatedBackupsReplication(ctx, "default", &rds.InstanceAutomatedBackupsReplicationArgs{
			SourceDbInstanceArn: pulumi.String("arn:aws:rds:us-west-2:123456789012:db:mydatabase"),
			KmsKeyId:            pulumi.String("arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012"),
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var @default = new Aws.Rds.InstanceAutomatedBackupsReplication("default", new()
    {
        SourceDbInstanceArn = "arn:aws:rds:us-west-2:123456789012:db:mydatabase",
        KmsKeyId = "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplication;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new InstanceAutomatedBackupsReplication("default", InstanceAutomatedBackupsReplicationArgs.builder()
            .sourceDbInstanceArn("arn:aws:rds:us-west-2:123456789012:db:mydatabase")
            .kmsKeyId("arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012")
            .build());

    }
}
resources:
  default:
    type: aws:rds:InstanceAutomatedBackupsReplication
    properties:
      sourceDbInstanceArn: arn:aws:rds:us-west-2:123456789012:db:mydatabase
      kmsKeyId: arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012

The kmsKeyId specifies a KMS key ARN in the destination region (us-east-1 in this example) to encrypt the replicated backups. Without this property, backups use the default RDS encryption. The source instance ARN still points to the database in the source region.

Create instance and replicate backups together

When provisioning a new database, you can configure backup replication in the same stack by referencing the instance ARN output.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const _default = new aws.rds.Instance("default", {
    allocatedStorage: 10,
    identifier: "mydb",
    engine: "postgres",
    engineVersion: "13.4",
    instanceClass: aws.rds.InstanceType.T3_Micro,
    dbName: "mydb",
    username: "masterusername",
    password: "mustbeeightcharacters",
    backupRetentionPeriod: 7,
    storageEncrypted: true,
    skipFinalSnapshot: true,
});
const defaultKey = new aws.kms.Key("default", {description: "Encryption key for automated backups"});
const defaultInstanceAutomatedBackupsReplication = new aws.rds.InstanceAutomatedBackupsReplication("default", {
    sourceDbInstanceArn: _default.arn,
    kmsKeyId: defaultKey.arn,
});
import pulumi
import pulumi_aws as aws

default = aws.rds.Instance("default",
    allocated_storage=10,
    identifier="mydb",
    engine="postgres",
    engine_version="13.4",
    instance_class=aws.rds.InstanceType.T3_MICRO,
    db_name="mydb",
    username="masterusername",
    password="mustbeeightcharacters",
    backup_retention_period=7,
    storage_encrypted=True,
    skip_final_snapshot=True)
default_key = aws.kms.Key("default", description="Encryption key for automated backups")
default_instance_automated_backups_replication = aws.rds.InstanceAutomatedBackupsReplication("default",
    source_db_instance_arn=default.arn,
    kms_key_id=default_key.arn)
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kms"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/rds"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_default, err := rds.NewInstance(ctx, "default", &rds.InstanceArgs{
			AllocatedStorage:      pulumi.Int(10),
			Identifier:            pulumi.String("mydb"),
			Engine:                pulumi.String("postgres"),
			EngineVersion:         pulumi.String("13.4"),
			InstanceClass:         pulumi.String(rds.InstanceType_T3_Micro),
			DbName:                pulumi.String("mydb"),
			Username:              pulumi.String("masterusername"),
			Password:              pulumi.String("mustbeeightcharacters"),
			BackupRetentionPeriod: pulumi.Int(7),
			StorageEncrypted:      pulumi.Bool(true),
			SkipFinalSnapshot:     pulumi.Bool(true),
		})
		if err != nil {
			return err
		}
		defaultKey, err := kms.NewKey(ctx, "default", &kms.KeyArgs{
			Description: pulumi.String("Encryption key for automated backups"),
		})
		if err != nil {
			return err
		}
		_, err = rds.NewInstanceAutomatedBackupsReplication(ctx, "default", &rds.InstanceAutomatedBackupsReplicationArgs{
			SourceDbInstanceArn: _default.Arn,
			KmsKeyId:            defaultKey.Arn,
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var @default = new Aws.Rds.Instance("default", new()
    {
        AllocatedStorage = 10,
        Identifier = "mydb",
        Engine = "postgres",
        EngineVersion = "13.4",
        InstanceClass = Aws.Rds.InstanceType.T3_Micro,
        DbName = "mydb",
        Username = "masterusername",
        Password = "mustbeeightcharacters",
        BackupRetentionPeriod = 7,
        StorageEncrypted = true,
        SkipFinalSnapshot = true,
    });

    var defaultKey = new Aws.Kms.Key("default", new()
    {
        Description = "Encryption key for automated backups",
    });

    var defaultInstanceAutomatedBackupsReplication = new Aws.Rds.InstanceAutomatedBackupsReplication("default", new()
    {
        SourceDbInstanceArn = @default.Arn,
        KmsKeyId = defaultKey.Arn,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.rds.Instance;
import com.pulumi.aws.rds.InstanceArgs;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplication;
import com.pulumi.aws.rds.InstanceAutomatedBackupsReplicationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var default_ = new Instance("default", InstanceArgs.builder()
            .allocatedStorage(10)
            .identifier("mydb")
            .engine("postgres")
            .engineVersion("13.4")
            .instanceClass("db.t3.micro")
            .dbName("mydb")
            .username("masterusername")
            .password("mustbeeightcharacters")
            .backupRetentionPeriod(7)
            .storageEncrypted(true)
            .skipFinalSnapshot(true)
            .build());

        var defaultKey = new Key("defaultKey", KeyArgs.builder()
            .description("Encryption key for automated backups")
            .build());

        var defaultInstanceAutomatedBackupsReplication = new InstanceAutomatedBackupsReplication("defaultInstanceAutomatedBackupsReplication", InstanceAutomatedBackupsReplicationArgs.builder()
            .sourceDbInstanceArn(default_.arn())
            .kmsKeyId(defaultKey.arn())
            .build());

    }
}
resources:
  default:
    type: aws:rds:Instance
    properties:
      allocatedStorage: 10
      identifier: mydb
      engine: postgres
      engineVersion: '13.4'
      instanceClass: db.t3.micro
      dbName: mydb
      username: masterusername
      password: mustbeeightcharacters
      backupRetentionPeriod: 7
      storageEncrypted: true
      skipFinalSnapshot: true
  defaultKey:
    type: aws:kms:Key
    name: default
    properties:
      description: Encryption key for automated backups
  defaultInstanceAutomatedBackupsReplication:
    type: aws:rds:InstanceAutomatedBackupsReplication
    name: default
    properties:
      sourceDbInstanceArn: ${default.arn}
      kmsKeyId: ${defaultKey.arn}

This example creates an RDS instance with backupRetentionPeriod set to 7 days, provisions a KMS key for encryption, and wires them together through the replication resource. The sourceDbInstanceArn references the instance’s arn output, and kmsKeyId points to the key’s ARN. This approach ensures backup replication is configured from the start.

Beyond these examples

These snippets focus on specific backup replication features: cross-region backup replication, KMS encryption for replicated backups, and integration with RDS instance creation. They’re intentionally minimal rather than full disaster recovery solutions.

The examples may reference pre-existing infrastructure such as source RDS instances (for examples 1 and 2) and KMS keys in the destination region (for examples 2 and 3). They focus on configuring backup replication rather than provisioning the entire database infrastructure.

To keep things focused, common replication patterns are omitted, including:

  • Pre-signed URLs for cross-account replication (preSignedUrl)
  • Custom retention periods beyond the default 7 days
  • Multi-region replication (replicating to more than one destination)

These omissions are intentional: the goal is to illustrate how backup replication is wired, not provide drop-in disaster recovery modules. See the RDS Instance Automated Backups Replication resource reference for all available configuration options.

Let's configure AWS RDS Automated Backups Replication

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Setup & Region Configuration
Which region do I create this resource in?
Create this resource in the destination region where you want backups replicated to, not the source region.
Does my source RDS instance need backups enabled?
Yes, the source DB instance must have backupRetentionPeriod configured to enable automated backups for replication.
Encryption & KMS
How do I encrypt my replicated backups?
Specify kmsKeyId with the ARN of a KMS key in the destination region. The KMS key must exist in the same region where backups are being replicated.
Can I use a KMS key from the source region?
No, the KMS key must be in the destination region where the replicated backups are stored.
Retention & Backup Configuration
What's the default retention period for replicated backups?
Replicated backups default to a 7-day retention period if not specified.
Immutability & Updates
What properties can't I change after creation?
The following properties are immutable and force replacement if changed: kmsKeyId, sourceDbInstanceArn, retentionPeriod, and preSignedUrl.
What happens if I need to change the source database or KMS key?
Since sourceDbInstanceArn and kmsKeyId are immutable, you’ll need to destroy and recreate the replication resource with the new values.

Using a different cloud?

Explore database guides for other cloud providers: