28.7 Cross-Account and Cross-Region Image Replication
Right, so you’ve built a container image. It’s a beautiful, perfect snowflake of an artifact, and you’ve dutifully shoved it into an ECR repository in your dev account. Now the fun begins: your prod account in a completely different region needs it. You could do the whole docker pull, retag, docker push dance, but that’s manual, error-prone, and frankly, a little sad. We’re engineers, not pack mules. Let’s automate this properly with cross-account and cross-region replication.
The magic here isn’t some complex CI/CD script; it’s a native ECR feature called Replication. You set up a rule, and AWS handles the rest, keeping your images in sync across accounts and regions automatically. It’s one of those things that feels like actual sorcery when you first use it.
Why You’d Bother With This
Before we dive into the config, let’s talk motives. Why replicate?
- Disaster Recovery: If
us-east-1decides to take a nap, your failover regionus-west-2has the exact same image ready to go. No frantic searching for the right version. - Latency Reduction: Pulling a multi-gigabyte image from a region on the other side of the planet is slow. Replicating it to a region closer to your compute (e.g., your EKS clusters) speeds up deployments drastically.
- Account Isolation: Your central “build” account produces the blessed, security-scanned image. Your myriad " workload" accounts (prod, staging, etc.) only need pull access. This is a fantastic security practice. They never need write access to the repository itself.
The Core Concept: It’s All About the Destination
This is the most important thing to internalize: replication rules are configured on the source repository, but they grant permissions to the destination.
You’re telling your source repo: “Hey, I give you permission to push copies of yourself to that other account and region over there.” This means all the IAM heavy lifting happens on the source side. The destination account just needs a basic trust policy to allow the source account to create repositories on its behalf (if they don’t exist) and push images to them.
Setting Up the IAM Voodoo
Here’s where everyone gets tripped up. You need an IAM principal (a user or role) in the source account that has permissions to set up the replication. This principal needs permission to call the replication APIs and to assume a role in the destination account. Yes, you read that right.
Let’s create a role in the destination account (123456789012) that the source account (555444333222) can assume. This role needs power over ECR.
Destination Account Role (Trust Policy):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::555444333222:root"
},
"Action": "sts:AssumeRole",
"Condition": {}
}
]
}
Destination Account Role (Permissions Policy):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:CreateRepository",
"ecr:ReplicateImage"
],
"Resource": "*"
}
]
}
Notice the CreateRepository permission? This is brilliant. If the repo doesn’t exist in the destination, ECR will just… create it. With the same name and everything. One less thing for you to manage.
Creating the Replication Rule
Now, in your source account, you create the replication rule. You can do this in the AWS Console under your ECR repository’s “Replication” tab, or you can be a pro and use Terraform like so:
resource "aws_ecr_replication_configuration" "cross_region_prod" {
replication_configuration {
rule {
# This tells the source repo where it can push to
destination {
region = "eu-west-1" # The target region
registry_id = "123456789012" # The target account ID
}
}
}
}
Apply this, push a new image to your source repo, and then go make a coffee. By the time you’re back, check the ECR console in the destination account and region. Your image, with its exact same tag and digest, will be there. Magic.
The Sharp Edges and “Gotchas”
It’s not all rainbows. Here’s what the manual doesn’t emphasize enough:
- It’s Not Retroactive: Replication only kicks in for new images pushed after the rule is created. Your existing images? They’re stuck in the source. You’ll have to re-tag and push them manually to trigger the replication if you need them.
- Tag Mutability is King: If you use immutable tags (which you should), you’re golden. If you use mutable tags (like
latest) and you push an updated image using the same tag, the replication will update the destination. However, if you push a new image manifest to the same tag after the initial replication, it will not automatically re-replicate. You must push the image again. This is why relying onlatestis a terrible idea for replication (and for life). - Region Enablement: The destination region must be enabled for your account. Obvious, but easy to forget if you’re working in a new AWS setup.
- The Bill Comes For Us All: Remember, you’re paying for storage in every region you replicate to. Data transfer out from the source region to the destination is free, but the storage costs add up. Don’t replicate a 10GB image to 12 regions “just because.”