Skip to main content
S3 replication copies new objects from a source bucket to one or more destination buckets automatically. There are two flavours:
  • Cross-Region Replication (CRR) — source and destination are in different AWS regions. Use for disaster recovery, compliance, and latency reduction.
  • Same-Region Replication (SRR) — source and destination are in the same region. Use for log aggregation or production-to-test data copying.
Versioning must be enabled on both the source and destination buckets before replication can be configured. The module enables versioning first via depends_on internally.

Prerequisites

1

Enable versioning on the source bucket

module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "origin-s3-bucket"

  versioning = {
    enabled = true
  }
}
2

Create and version the destination bucket

module "replica_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  providers = {
    aws = aws.replica
  }

  bucket = "replica-s3-bucket"

  versioning = {
    enabled = true
  }
}
3

Create an IAM replication role

S3 replication requires an IAM role that permits the S3 service to read from the source and write to the destination. See the s3-replication example for the complete IAM configuration.

Basic replication configuration

module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = "origin-s3-bucket"

  versioning = {
    enabled = true
  }

  replication_configuration = {
    role = aws_iam_role.replication.arn

    rules = [
      {
        id     = "replicate-everything"
        status = true

        destination = {
          bucket        = module.replica_bucket.s3_bucket_arn
          storage_class = "STANDARD"
        }
      }
    ]
  }
}

Complete replication example with KMS and filters

The following example mirrors the s3-replication example and shows KMS encryption, prefix filters, delete marker replication, and Replication Time Control (RTC):
module "s3_bucket" {
  source = "terraform-aws-modules/s3-bucket/aws"

  bucket = local.bucket_name

  versioning = {
    enabled = true
  }

  replication_configuration = {
    role = aws_iam_role.replication.arn

    rules = [
      {
        id       = "something-with-kms-and-filter"
        status   = true
        priority = 10

        delete_marker_replication = false

        source_selection_criteria = {
          replica_modifications = {
            status = "Enabled"
          }
          sse_kms_encrypted_objects = {
            enabled = true
          }
        }

        filter = {
          prefix = "one"
          tags = {
            ReplicateMe = "Yes"
          }
        }

        destination = {
          bucket        = "arn:aws:s3:::${local.destination_bucket_name}"
          storage_class = "STANDARD"

          replica_kms_key_id = aws_kms_key.replica.arn
          account_id         = data.aws_caller_identity.current.account_id

          access_control_translation = {
            owner = "Destination"
          }

          replication_time = {
            status  = "Enabled"
            minutes = 15
          }

          metrics = {
            status  = "Enabled"
            minutes = 15
          }
        }
      }
    ]
  }
}

Rule configuration reference

Filters

Filters limit which objects a rule applies to. If no filter is supplied the rule applies to all objects.
# Single prefix filter
filter = {
  prefix = "logs/"
}

# Multiple conditions (AND logic)
filter = {
  prefix = "log1/"
  tags = {
    ReplicateMe = "Yes"
  }
}

Delete marker replication

Control whether delete markers on the source are replicated to the destination:
delete_marker_replication = false   # or true / "Enabled" / "Disabled"

Existing object replication

To replicate objects that existed before replication was enabled, set existing_object_replication:
existing_object_replication = "Enabled"
Existing object replication requires a one-time Batch Operations job and AWS Support contact. See the AWS documentation for details.

Destination storage class

You can change the storage class of replicated objects independently of the source:
ValueDescription
STANDARDStandard storage (default)
STANDARD_IAInfrequent Access
ONEZONE_IASingle-AZ Infrequent Access
GLACIERGlacier Flexible Retrieval
DEEP_ARCHIVEGlacier Deep Archive
INTELLIGENT_TIERINGAutomatic tiering

Multi-rule example

You can define multiple rules with different priorities and filters:
replication_configuration = {
  role = aws_iam_role.replication.arn

  rules = [
    {
      id       = "high-priority"
      priority = 10
      status   = true
      filter   = { prefix = "critical/" }
      destination = {
        bucket        = "arn:aws:s3:::destination-bucket"
        storage_class = "STANDARD"
      }
    },
    {
      id       = "low-priority"
      priority = 20
      status   = true
      filter   = { prefix = "archive/" }
      destination = {
        bucket        = "arn:aws:s3:::destination-bucket"
        storage_class = "GLACIER"
      }
    }
  ]
}
See the complete s3-replication example for the full IAM role and policy setup needed to enable replication.