AWS S3 geo-replication with Terraform

Adrian Angel Sanz Melchor
AWS Tip
Published in
2 min readApr 5, 2022

--

Photo by NASA on Unsplash

You will find cases where you would like to save data easily, securely and make sure you won’t lose it unless the world is ending, for real… We came across this situation, where we needed to save sensitive information, and make sure we won’t lose it whatever it happens. I came across a Terraform module that will “make my life easier” but the last commit is from 2018, so I forked it and started working, the final result is this:

You can take a look at the code, and share feedback with me or create a merge request with improvements! (disclaimer: the original module was design for cross-account replication, but I don’t need that feature, and forgot to change the name)

How it works

Well… The README explains it really well, but in a nutshell, it will:

  • Create 2 buckets on selected regions
  • Create a policy & role so replication can happen
  • Create 2 KMS keys for object encryption on both buckets

On the buckets it will:

  • Both have encryption enabled
  • Both have versioning enable (required for replication)
  • Both are private
  • On source there’s a lifecycle policy that by default it will move objects to STANDARD_IA after 30 days, and to GLACIER after 90
  • On source a replication rule will be configured (remember that objects on destination are encrypted with a different key)
  • On destination objects are stored directly on GLACIER

Once the module is configured, you can test uploading an object and check replication!

How to use it

The module has tags, so you can use it like this on your main.tf file

module "s3-cross-account-replication" {
source = "github.com/adsanz/terraform-aws-s3-cross-account-replication?ref=1.0.0"
bucket_source_name = var.bucket_source_name
bucket_dest_name = var.bucket_dest_name
replication_name = var.replication_name
versioning_enable = var.versioning_enable
replication_policy_name = var.replication_policy_name
replication_role_name = var.replication_role_name
replication_prefix = var.replication_prefix
source_region = var.source_region
dest_region = var.dest_region
providers = {
aws.source = aws.source
aws.dest = aws.dest
}
}
provider "aws" {
alias = "source"
region = "us-west-2"
profile = "your-profile"
}
provider "aws" {
alias = "dest"
region = "us-west-1"
profile = "your-profile"
}

I usually define the variables at variables.tf file, but they are more or less self-explanatory (you can read the description on the “variables.tf” file for better understanding). Remember to change the “ref” version in case there are updates

Once everything is defined, you could just launch terraform plan to check that everything looks good, and then terraform apply to create changes.

Friendly reminder! The AWS provider used on this module needs to be 4.8 or above, otherwise you will see changes every time you launch terraform apply

--

--

Just a spanish DevOps who likes sharing useful knowledge, working proudly @ Cipher