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 different AWS region for disaster recovery. This guide focuses on three capabilities: basic cross-region backup replication, KMS encryption for replicated backups, and integration with RDS instance creation.

This resource must be created in the destination region and references a source DB instance from another region. Encrypted backups require a KMS key in the destination region. The examples are intentionally small. Combine them with your own RDS instances, KMS keys, and multi-region infrastructure.

Replicate automated backups to another region

Disaster recovery strategies often require database backups in a separate region 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 identifies the database in the source region whose backups you want to replicate. The retentionPeriod controls how long replicated backups are kept in the destination region (14 days in this example, defaulting to 7 if omitted). This resource must be created in the destination region, not the source region where the database lives.

Encrypt replicated backups with a KMS key

Compliance requirements often mandate encryption of backups at rest. When replicating to another region, you specify a KMS key 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 property points to a KMS key ARN in the destination region. RDS uses this key to encrypt the replicated backups. Without this property, backups replicate unencrypted (unless the source database is encrypted, in which case AWS manages encryption automatically).

Create a database and replicate its backups

When provisioning new databases, you can configure backup replication alongside the instance to ensure disaster recovery from the start.

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 the source database with backupRetentionPeriod set to 7 days and storageEncrypted enabled. The replication resource references the database’s ARN output and a newly created KMS key. The database must have backup retention enabled (backupRetentionPeriod > 0) for replication to work.

Beyond these examples

These snippets focus on specific backup replication features: cross-region backup replication, KMS encryption for replicated backups, and retention period configuration. They’re intentionally minimal rather than full disaster recovery solutions.

The examples may reference pre-existing infrastructure such as source RDS DB instances in the source region, and KMS keys in the destination region for encrypted backups. They focus on configuring backup replication rather than provisioning complete multi-region database architectures.

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 strategies
  • Monitoring and alerting for replication status

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 & Configuration
Which region do I create this resource in?
Create the resource in the destination region where you want backups replicated to, not the source region. The region property defaults to your provider configuration.
What's required on my source RDS instance for backup replication?
The source RDS instance must have backupRetentionPeriod configured to enable automated backups. The example shows setting this to 7 days.
Encryption & Security
Is encryption required for replicated backups?
Yes, kmsKeyId is a required property. You must provide the ARN of a KMS key in the destination region to encrypt replicated backups.
Can I use a different KMS key than my source database?
Yes, specify the ARN of any KMS key in the destination region. The example shows using a separate KMS key created specifically for automated backups.
Backup Retention & Lifecycle
How long are replicated backups retained by default?
Replicated backups are retained for 7 days by default. You can customize this with the retentionPeriod property.
What properties can't I change after creating the replication?
The following properties are immutable and require resource recreation to change: kmsKeyId, sourceDbInstanceArn, retentionPeriod, and preSignedUrl.

Using a different cloud?

Explore database guides for other cloud providers: