Search code examples
amazon-web-servicesamazon-s3terraformterraform-provider-aws

S3 buckets two-way replication with terraform


Using terraform, I'm trying to create two s3 buckets, that each replicate back to each other. This causes a dependency cycle. I'm not sure how to handle this in terraform.

One solution I thought of is possibly split it into two sets of terraform scripts, one to create the two buckets, and then a second to modify those buckets adding the replication rules.

Is there another way to handle this scenario?


Solution

  • This is supported in AWS Terraform Provider version 4 (released Feb 2022) by separating out the replication configuration as a separate resource. From the provider documentation:

    # ... other configuration ...
    
    resource "aws_s3_bucket" "east" {
      bucket = "tf-test-bucket-east-12345"
    }
    
    resource "aws_s3_bucket_versioning" "east" {
      bucket = aws_s3_bucket.east.id
      versioning_configuration {
        status = "Enabled"
      }
    }
    
    resource "aws_s3_bucket" "west" {
      provider = aws.west
      bucket   = "tf-test-bucket-west-12345"
    }
    
    resource "aws_s3_bucket_versioning" "west" {
      provider = aws.west
    
      bucket = aws_s3_bucket.west.id
      versioning_configuration {
        status = "Enabled"
      }
    }
    
    resource "aws_s3_bucket_replication_configuration" "east_to_west" {
      # Must have bucket versioning enabled first
      depends_on = [aws_s3_bucket_versioning.east]
    
      role   = aws_iam_role.east_replication.arn
      bucket = aws_s3_bucket.east.id
    
      rule {
        id = "foobar"
    
        filter {
          prefix = "foo"
        }
    
        status = "Enabled"
    
        destination {
          bucket        = aws_s3_bucket.west.arn
          storage_class = "STANDARD"
        }
      }
    }
    
    resource "aws_s3_bucket_replication_configuration" "west_to_east" {
      provider = aws.west
      # Must have bucket versioning enabled first
      depends_on = [aws_s3_bucket_versioning.west]
    
      role   = aws_iam_role.west_replication.arn
      bucket = aws_s3_bucket.west.id
    
      rule {
        id = "foobar"
    
        filter {
          prefix = "foo"
        }
    
        status = "Enabled"
    
        destination {
          bucket        = aws_s3_bucket.east.arn
          storage_class = "STANDARD"
        }
      }
    }