S3 Bucket Cross Account Replication

In this tutorial, I’ll guide you through setting up cross-account replication for an S3 bucket. The S3 replication process is more than just syncing buckets; it’s a slightly more sophisticated procedure, though not overly complex.

Here’s the scenario we’ll be working with: You have two AWS accounts—Account B (source account) and Account A (destination account). You want to replicate data from an S3 bucket in Account B to another bucket in Account A.

Important points to note:
1. Deleting synced data from the bucket in Account A won’t affect data in the bucket of Account B.
2. If data is deleted from the bucket in Account A, it won’t be resynced. Only new data added to the source bucket will be replicated. This is crucial to remember during testing.
3. You can replicate buckets in a one-to-one relationship. You can’t replicate two buckets to different paths within a single bucket.

Here’s the workflow:
    a. Create a bucket in Account A (destination).
    b. Create a bucket in Account B (source) and set up a replication rule (this will create a service role).
    c. Add a bucket policy to the bucket in Account A, including relevant values obtained from Account B, such as the ARN of the S3 cross-account replication (S3CRR) role.

first let’s create the bucket on account A, this will be the destination bucket.
just click through the UI and create the simplest S3 bucket.

it’s important to enable ‘Bucket versioning’, it wont work without it.

Next let’s create the bucket on account B, this will be the source bucket.
just like in the previous stage, click…click…click… and you got your bucket.
don’t forget to enable versioning….

After creating the source bucket go to bucket’s ‘management’ tab,
there you will get the chance to configure ‘Replication Rules’.

Click the ‘Create replication rule’ button, it’s nothing special, just go with the flow and select to create a new ROLE with that.

After configuring the replication rule there will be a ROLE created, it starts with ‘s3crr….’

View the ROLE it’ll look like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetReplicationConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetObjectVersionAcl",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectRetention",
                "s3:GetObjectLegalHold"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::<source-bucket>",
                "arn:aws:s3:::<source-bucket>/*",
                "arn:aws:s3:::<destination-bucket>",
                "arn:aws:s3:::<destination-bucket>/*"
            ]
        },
        {
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateDelete",
                "s3:ReplicateTags",
                "s3:ObjectOwnerOverrideToBucketOwner"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::<source-bucket>/*",
                "arn:aws:s3:::<destination-bucket>/*"
            ]
        }
    ]
}

now go to the destination bucket on account A and configure a bucket policy

{
    "Version": "2012-10-17",
    "Id": "PolicyForDestinationBucket",
    "Statement": [
        {
            "Sid": "Permissions on objects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::987654321011:role/service-role/s3crr..." //the ARN of the ROLE on the source account
            },
            "Action": [
                "s3:ReplicateDelete",
                "s3:ReplicateObject",
                "s3:ObjectOwnerOverrideToBucketOwner"
            ],
            "Resource": "arn:aws:s3:::<destination-bucket>/*" // destination bucket ARN
        },
        {
            "Sid": "Permissions on bucket",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::987654321011:role/service-role/s3crr..." //the ARN of the ROLE on the source account
            },
            "Action": [
                "s3:List*",
                "s3:GetBucketVersioning",
                "s3:PutBucketVersioning"
            ],
            "Resource": "arn:aws:s3:::<destination-bucket>" // destination bucket ARN
        }
    ]
}

That’s it…. you got your replication configured, now every new item that will be added to source will replicate to destination :>