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
| Step | What You Do | Key Requirement |
|---|---|---|
| 1 | Enable versioning on both buckets | Mandatory prerequisite |
| 2 | Create an IAM role for S3 replication | Least-privilege trust + permissions policy |
| 3 | Configure a Replication Rule on the source bucket | Specify destination bucket ARN + IAM role ARN |
| 4 | (Optional) Enable S3 Replication Time Control | For 99.99% of objects replicated within 15 min SLA |
| 5 | Validate with S3 Replication metrics & test uploads | CloudWatch 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.
- Client PUT: An application writes an object to the source bucket in
us-east-1. - Versioning Engine: S3 assigns a Version ID — versioning must be enabled for CRR to function.
- Replication Engine: S3's internal replication engine reads the replication configuration attached to the source bucket.
- IAM Role Assumption: S3 assumes the configured IAM role to gain permission to read from the source and write to the destination.
- Cross-Region Copy: The object is copied to the destination bucket in
eu-west-1, preserving metadata, ACLs (if configured), and encryption settings. - Status Tag: The source object's replication status is updated to
COMPLETED(orFAILEDon 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_IAis 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
- Source Bucket (us-east-1): Versioning enabled; replication rule and IAM role ARN configured here.
- IAM Role: Trusted by the S3 service principal; holds read permissions on the source and write permissions on the destination.
- S3 Replication Engine: Assumes the IAM role and orchestrates the async copy.
- Destination Bucket (eu-west-1): Versioning enabled; receives replicated objects tagged with
ReplicationStatus: REPLICA. - CloudWatch (optional with RTC): Surfaces replication lag and pending operation metrics for monitoring.
Common Pitfalls
| Pitfall | Root Cause | Fix |
|---|---|---|
| Replication status stuck at PENDING | IAM role missing permissions or wrong ARN | Verify role ARN in config; check IAM policy actions |
| Existing objects not replicated | CRR only applies to new objects after rule creation | Use S3 Batch Replication for existing objects |
| Encrypted objects fail to replicate | KMS key permissions not granted to replication role | Add kms:Decrypt (source key) and kms:GenerateDataKey (destination key) to the IAM role |
| Cross-account replication denied | Destination bucket policy missing | Add bucket policy granting the source role write access |
Glossary
| Term | Definition |
|---|---|
| CRR | Cross-Region Replication — automatic, asynchronous copying of S3 objects to a bucket in a different AWS region. |
| RTC | Replication Time Control — an optional S3 feature providing an SLA for replication completion within 15 minutes for 99.99% of objects. |
| Replication Status | Object-level metadata tag indicating the replication state: PENDING, COMPLETED, FAILED, or REPLICA. |
| Delete Marker Replication | Optional setting that propagates versioned delete markers (soft deletes) to the destination bucket. |
| S3 Batch Replication | A separate S3 feature used to replicate pre-existing objects that were present before a CRR rule was created. |
Next Steps
- For existing objects, configure S3 Batch Replication to backfill your replica bucket.
- If source objects are encrypted with SSE-KMS, review the KMS replication documentation to add the required key permissions to your IAM role.
- For a formal DR strategy, pair CRR with S3 Object Lock on the destination to prevent replica tampering.
- Official reference: AWS S3 Replication Documentation.
Comments
Post a Comment