S3 Cross-Region Replication: A Complete Setup Guide for Disaster Recovery

When a regional AWS outage hits, your S3 data availability depends entirely on whether you planned ahead. Cross-Region Replication (CRR) is the mechanism that automatically copies every new object written to a source bucket into a destination bucket in a different AWS region — giving you a live, asynchronous replica for disaster recovery, compliance, or latency reduction.

TL;DR

StepWhat You DoKey Requirement
1Enable versioning on both bucketsMandatory prerequisite
2Create an IAM role for S3 replicationLeast-privilege trust + permissions policy
3Configure a Replication Rule on the source bucketSpecify destination bucket ARN + IAM role ARN
4(Optional) Enable S3 Replication Time ControlFor 99.99% of objects replicated within 15 min SLA
5Validate with S3 Replication metrics & test uploadsCloudWatch metrics + Replication status object tag

How CRR Works: Data Flow

Before touching the console or CLI, understand the replication pipeline. S3 CRR is event-driven and asynchronous — it does not replicate existing objects by default (use S3 Batch Replication for that). Every new PUT triggers the replication engine.

sequenceDiagram participant App as Application participant SRC as Source Bucket (us-east-1) participant IAM as IAM Role participant REP as S3 Replication Engine participant DST as Destination Bucket (eu-west-1) App->>SRC: PUT object SRC->>SRC: Assign Version ID SRC->>REP: Trigger replication event REP->>IAM: AssumeRole IAM-->>REP: Temporary credentials REP->>SRC: GetObjectVersionForReplication REP->>DST: ReplicateObject DST-->>REP: 200 OK REP->>SRC: Update ReplicationStatus to COMPLETED
  1. Client PUT: An application writes an object to the source bucket in us-east-1.
  2. Versioning Engine: S3 assigns a Version ID — versioning must be enabled for CRR to function.
  3. Replication Engine: S3's internal replication engine reads the replication configuration attached to the source bucket.
  4. IAM Role Assumption: S3 assumes the configured IAM role to gain permission to read from the source and write to the destination.
  5. Cross-Region Copy: The object is copied to the destination bucket in eu-west-1, preserving metadata, ACLs (if configured), and encryption settings.
  6. Status Tag: The source object's replication status is updated to COMPLETED (or FAILED on error).
Analogy: Think of CRR like a bank's nightly ledger synchronization. Every transaction (object write) at the main branch (source region) is automatically mirrored to a backup vault (destination region) by a trusted courier (IAM role). The courier only carries new transactions — it doesn't retroactively copy the entire historical ledger unless you explicitly ask it to.

Prerequisites

  • Two S3 buckets in different AWS regions (can be in the same or different AWS accounts).
  • Versioning enabled on both the source and destination bucket — this is a hard requirement enforced by the S3 API.
  • Sufficient IAM permissions to create roles and configure bucket replication policies.

Step 1: Enable Versioning on Both Buckets

Use the AWS CLI to enable versioning. Replace bucket names with your own.

# Enable versioning on the SOURCE bucket (us-east-1)
aws s3api put-bucket-versioning \
  --bucket my-source-bucket-use1 \
  --versioning-configuration Status=Enabled \
  --region us-east-1

# Enable versioning on the DESTINATION bucket (eu-west-1)
aws s3api put-bucket-versioning \
  --bucket my-destination-bucket-euw1 \
  --versioning-configuration Status=Enabled \
  --region eu-west-1

Step 2: Create the IAM Replication Role

S3 needs an IAM role it can assume to perform the replication. This role requires two policies: a trust policy (who can assume it) and a permissions policy (what it can do).

2a. Trust Policy (s3-replication-trust.json)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

2b. Permissions Policy (s3-replication-permissions.json)

🔽 Click to expand — IAM Permissions Policy JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SourceBucketReadAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetReplicationConfiguration",
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::my-source-bucket-use1"
    },
    {
      "Sid": "SourceObjectReadAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObjectVersionForReplication",
        "s3:GetObjectVersionAcl",
        "s3:GetObjectVersionTagging"
      ],
      "Resource": "arn:aws:s3:::my-source-bucket-use1/*"
    },
    {
      "Sid": "DestinationBucketWriteAccess",
      "Effect": "Allow",
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags"
      ],
      "Resource": "arn:aws:s3:::my-destination-bucket-euw1/*"
    }
  ]
}

2c. Create and Attach the Role via CLI

# Create the IAM role
aws iam create-role \
  --role-name S3ReplicationRole \
  --assume-role-policy-document file://s3-replication-trust.json

# Create and attach the permissions policy
aws iam put-role-policy \
  --role-name S3ReplicationRole \
  --policy-name S3ReplicationPolicy \
  --policy-document file://s3-replication-permissions.json

Step 3: Configure the Replication Rule on the Source Bucket

The replication configuration is a JSON document applied to the source bucket only. It references the IAM role ARN and the destination bucket ARN.

🔽 Click to expand — Replication Configuration JSON (replication-config.json)
{
  "Role": "arn:aws:iam::123456789012:role/S3ReplicationRole",
  "Rules": [
    {
      "ID": "DR-Replication-Rule",
      "Status": "Enabled",
      "Filter": {
        "Prefix": ""
      },
      "Destination": {
        "Bucket": "arn:aws:s3:::my-destination-bucket-euw1",
        "StorageClass": "STANDARD_IA"
      },
      "DeleteMarkerReplication": {
        "Status": "Enabled"
      }
    }
  ]
}
# Apply the replication configuration to the SOURCE bucket
aws s3api put-bucket-replication \
  --bucket my-source-bucket-use1 \
  --replication-configuration file://replication-config.json \
  --region us-east-1

Key configuration notes:

  • Filter Prefix "": An empty prefix replicates all objects. Scope it to a specific prefix (e.g., "logs/") for partial replication.
  • StorageClass: You can override the storage class on the destination. STANDARD_IA is cost-effective for DR replicas that are rarely accessed.
  • DeleteMarkerReplication: When enabled, delete markers created by versioned deletes are also replicated. Actual version deletions are not replicated by default to protect against accidental mass-deletion propagation.

Step 4 (Optional): Enable S3 Replication Time Control (RTC)

By default, CRR replicates most objects within minutes but provides no SLA. If your DR RPO requires a guaranteed replication window, enable S3 Replication Time Control (RTC), which provides an SLA of replicating 99.99% of objects within 15 minutes. Note that RTC incurs additional charges.

Add the following block inside the Destination object of your replication configuration:

"ReplicationTime": {
  "Status": "Enabled",
  "Time": {
    "Minutes": 15
  }
},
"Metrics": {
  "Status": "Enabled",
  "EventThreshold": {
    "Minutes": 15
  }
}

Step 5: Validate Replication

After configuration, validate that replication is working correctly using two methods.

Method A: Check Object Replication Status

# Upload a test object
aws s3 cp test-file.txt s3://my-source-bucket-use1/test-file.txt

# Check the replication status metadata on the object
aws s3api head-object \
  --bucket my-source-bucket-use1 \
  --key test-file.txt \
  --query 'ReplicationStatus'

The ReplicationStatus value will be one of: PENDING, COMPLETED, FAILED, or REPLICA (on the destination object).

Method B: CloudWatch Metrics (when RTC is enabled)

When RTC is enabled, S3 publishes replication metrics to CloudWatch under the AWS/S3 namespace. You can monitor metrics such as replication latency and the number of operations pending replication. Check the official AWS documentation for the exact metric names available for your configuration.

Cross-Account CRR: Additional Requirement

If the destination bucket is in a different AWS account, the destination bucket's bucket policy must explicitly grant the source account's IAM replication role permission to write objects.

🔽 Click to expand — Destination Bucket Policy for Cross-Account CRR
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountReplication",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/S3ReplicationRole"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateDelete",
        "s3:ReplicateTags",
        "s3:ObjectOwnerOverrideToBucketOwner"
      ],
      "Resource": "arn:aws:s3:::my-destination-bucket-euw1/*"
    }
  ]
}

Architecture Summary

graph LR subgraph us-east-1 SRC[Source Bucket] RULE[Replication Rule] end subgraph IAM_Global[IAM - Global] ROLE[S3ReplicationRole] end subgraph eu-west-1 DST[Destination Bucket] CW[CloudWatch Metrics] end SRC -- triggers --> RULE RULE -- assumes --> ROLE ROLE -- reads from --> SRC ROLE -- writes to --> DST DST -- metrics via RTC --> CW
  1. Source Bucket (us-east-1): Versioning enabled; replication rule and IAM role ARN configured here.
  2. IAM Role: Trusted by the S3 service principal; holds read permissions on the source and write permissions on the destination.
  3. S3 Replication Engine: Assumes the IAM role and orchestrates the async copy.
  4. Destination Bucket (eu-west-1): Versioning enabled; receives replicated objects tagged with ReplicationStatus: REPLICA.
  5. CloudWatch (optional with RTC): Surfaces replication lag and pending operation metrics for monitoring.

Common Pitfalls

PitfallRoot CauseFix
Replication status stuck at PENDINGIAM role missing permissions or wrong ARNVerify role ARN in config; check IAM policy actions
Existing objects not replicatedCRR only applies to new objects after rule creationUse S3 Batch Replication for existing objects
Encrypted objects fail to replicateKMS key permissions not granted to replication roleAdd kms:Decrypt (source key) and kms:GenerateDataKey (destination key) to the IAM role
Cross-account replication deniedDestination bucket policy missingAdd bucket policy granting the source role write access

Glossary

TermDefinition
CRRCross-Region Replication — automatic, asynchronous copying of S3 objects to a bucket in a different AWS region.
RTCReplication Time Control — an optional S3 feature providing an SLA for replication completion within 15 minutes for 99.99% of objects.
Replication StatusObject-level metadata tag indicating the replication state: PENDING, COMPLETED, FAILED, or REPLICA.
Delete Marker ReplicationOptional setting that propagates versioned delete markers (soft deletes) to the destination bucket.
S3 Batch ReplicationA separate S3 feature used to replicate pre-existing objects that were present before a CRR rule was created.

Next Steps

Related Posts

Comments

Popular posts from this blog

EC2 No Internet Access in Custom VPC: Attaching an Internet Gateway and Fixing Route Tables

IAM User vs. IAM Role: Why Your EC2 Instance Should Never Use a User

EC2 SSH Connection Timeout: The Exact Security Group Rules You Need to Fix It