The aws:ecr/replicationConfiguration:ReplicationConfiguration resource, part of the Pulumi AWS provider, defines registry-level replication rules that automatically copy container images across regions or accounts. This guide focuses on two capabilities: single and multi-region replication, and repository filtering by naming patterns.
Replication configuration operates at the registry level and applies to existing ECR repositories. Target regions must be enabled in your AWS account. The examples are intentionally small. Combine them with your own repository naming conventions and regional requirements.
Replicate all repositories to another region
Container registries often replicate images across regions for disaster recovery or to reduce latency for distributed deployments.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getCallerIdentity({});
const example = aws.getRegions({});
const exampleReplicationConfiguration = new aws.ecr.ReplicationConfiguration("example", {replicationConfiguration: {
rules: [{
destinations: [{
region: example.then(example => example.names?.[0]),
registryId: current.then(current => current.accountId),
}],
}],
}});
import pulumi
import pulumi_aws as aws
current = aws.get_caller_identity()
example = aws.get_regions()
example_replication_configuration = aws.ecr.ReplicationConfiguration("example", replication_configuration={
"rules": [{
"destinations": [{
"region": example.names[0],
"registry_id": current.account_id,
}],
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecr"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
example, err := aws.GetRegions(ctx, &aws.GetRegionsArgs{}, nil)
if err != nil {
return err
}
_, err = ecr.NewReplicationConfiguration(ctx, "example", &ecr.ReplicationConfigurationArgs{
ReplicationConfiguration: &ecr.ReplicationConfigurationReplicationConfigurationArgs{
Rules: ecr.ReplicationConfigurationReplicationConfigurationRuleArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleArgs{
Destinations: ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs{
Region: pulumi.String(example.Names[0]),
RegistryId: pulumi.String(current.AccountId),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetCallerIdentity.Invoke();
var example = Aws.GetRegions.Invoke();
var exampleReplicationConfiguration = new Aws.Ecr.ReplicationConfiguration("example", new()
{
ReplicationConfigurationDetails = new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationArgs
{
Rules = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleArgs
{
Destinations = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs
{
Region = example.Apply(getRegionsResult => getRegionsResult.Names[0]),
RegistryId = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.inputs.GetRegionsArgs;
import com.pulumi.aws.ecr.ReplicationConfiguration;
import com.pulumi.aws.ecr.ReplicationConfigurationArgs;
import com.pulumi.aws.ecr.inputs.ReplicationConfigurationReplicationConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
.build());
final var example = AwsFunctions.getRegions(GetRegionsArgs.builder()
.build());
var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
.replicationConfiguration(ReplicationConfigurationReplicationConfigurationArgs.builder()
.rules(ReplicationConfigurationReplicationConfigurationRuleArgs.builder()
.destinations(ReplicationConfigurationReplicationConfigurationRuleDestinationArgs.builder()
.region(example.names()[0])
.registryId(current.accountId())
.build())
.build())
.build())
.build());
}
}
resources:
exampleReplicationConfiguration:
type: aws:ecr:ReplicationConfiguration
name: example
properties:
replicationConfiguration:
rules:
- destinations:
- region: ${example.names[0]}
registryId: ${current.accountId}
variables:
current:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
example:
fn::invoke:
function: aws:getRegions
arguments: {}
When you push an image to any repository in the source registry, ECR automatically copies it to the destination region. The rules array defines replication behavior; each rule contains a destinations array specifying target regions and registry IDs. Here, registryId references the current account, enabling same-account cross-region replication.
Replicate to multiple regions simultaneously
Global applications may need images available in several regions to support multi-region deployments or data residency requirements.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getCallerIdentity({});
const example = aws.getRegions({});
const exampleReplicationConfiguration = new aws.ecr.ReplicationConfiguration("example", {replicationConfiguration: {
rules: [{
destinations: [
{
region: example.then(example => example.names?.[0]),
registryId: current.then(current => current.accountId),
},
{
region: example.then(example => example.names?.[1]),
registryId: current.then(current => current.accountId),
},
],
}],
}});
import pulumi
import pulumi_aws as aws
current = aws.get_caller_identity()
example = aws.get_regions()
example_replication_configuration = aws.ecr.ReplicationConfiguration("example", replication_configuration={
"rules": [{
"destinations": [
{
"region": example.names[0],
"registry_id": current.account_id,
},
{
"region": example.names[1],
"registry_id": current.account_id,
},
],
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecr"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
example, err := aws.GetRegions(ctx, &aws.GetRegionsArgs{}, nil)
if err != nil {
return err
}
_, err = ecr.NewReplicationConfiguration(ctx, "example", &ecr.ReplicationConfigurationArgs{
ReplicationConfiguration: &ecr.ReplicationConfigurationReplicationConfigurationArgs{
Rules: ecr.ReplicationConfigurationReplicationConfigurationRuleArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleArgs{
Destinations: ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs{
Region: pulumi.String(example.Names[0]),
RegistryId: pulumi.String(current.AccountId),
},
&ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs{
Region: pulumi.String(example.Names[1]),
RegistryId: pulumi.String(current.AccountId),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetCallerIdentity.Invoke();
var example = Aws.GetRegions.Invoke();
var exampleReplicationConfiguration = new Aws.Ecr.ReplicationConfiguration("example", new()
{
ReplicationConfigurationDetails = new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationArgs
{
Rules = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleArgs
{
Destinations = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs
{
Region = example.Apply(getRegionsResult => getRegionsResult.Names[0]),
RegistryId = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
},
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs
{
Region = example.Apply(getRegionsResult => getRegionsResult.Names[1]),
RegistryId = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.inputs.GetRegionsArgs;
import com.pulumi.aws.ecr.ReplicationConfiguration;
import com.pulumi.aws.ecr.ReplicationConfigurationArgs;
import com.pulumi.aws.ecr.inputs.ReplicationConfigurationReplicationConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
.build());
final var example = AwsFunctions.getRegions(GetRegionsArgs.builder()
.build());
var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
.replicationConfiguration(ReplicationConfigurationReplicationConfigurationArgs.builder()
.rules(ReplicationConfigurationReplicationConfigurationRuleArgs.builder()
.destinations(
ReplicationConfigurationReplicationConfigurationRuleDestinationArgs.builder()
.region(example.names()[0])
.registryId(current.accountId())
.build(),
ReplicationConfigurationReplicationConfigurationRuleDestinationArgs.builder()
.region(example.names()[1])
.registryId(current.accountId())
.build())
.build())
.build())
.build());
}
}
resources:
exampleReplicationConfiguration:
type: aws:ecr:ReplicationConfiguration
name: example
properties:
replicationConfiguration:
rules:
- destinations:
- region: ${example.names[0]}
registryId: ${current.accountId}
- region: ${example.names[1]}
registryId: ${current.accountId}
variables:
current:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
example:
fn::invoke:
function: aws:getRegions
arguments: {}
Adding multiple entries to the destinations array distributes images to several regions from a single source. Each destination operates independently; ECR replicates to all targets whenever you push an image.
Replicate only repositories matching a prefix
Large registries with hundreds of repositories may want to replicate only production images or specific application families to control costs and replication traffic.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const current = aws.getCallerIdentity({});
const example = aws.getRegions({});
const exampleReplicationConfiguration = new aws.ecr.ReplicationConfiguration("example", {replicationConfiguration: {
rules: [{
destinations: [{
region: example.then(example => example.names?.[0]),
registryId: current.then(current => current.accountId),
}],
repositoryFilters: [{
filter: "prod-microservice",
filterType: "PREFIX_MATCH",
}],
}],
}});
import pulumi
import pulumi_aws as aws
current = aws.get_caller_identity()
example = aws.get_regions()
example_replication_configuration = aws.ecr.ReplicationConfiguration("example", replication_configuration={
"rules": [{
"destinations": [{
"region": example.names[0],
"registry_id": current.account_id,
}],
"repository_filters": [{
"filter": "prod-microservice",
"filter_type": "PREFIX_MATCH",
}],
}],
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ecr"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
if err != nil {
return err
}
example, err := aws.GetRegions(ctx, &aws.GetRegionsArgs{}, nil)
if err != nil {
return err
}
_, err = ecr.NewReplicationConfiguration(ctx, "example", &ecr.ReplicationConfigurationArgs{
ReplicationConfiguration: &ecr.ReplicationConfigurationReplicationConfigurationArgs{
Rules: ecr.ReplicationConfigurationReplicationConfigurationRuleArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleArgs{
Destinations: ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs{
Region: pulumi.String(example.Names[0]),
RegistryId: pulumi.String(current.AccountId),
},
},
RepositoryFilters: ecr.ReplicationConfigurationReplicationConfigurationRuleRepositoryFilterArray{
&ecr.ReplicationConfigurationReplicationConfigurationRuleRepositoryFilterArgs{
Filter: pulumi.String("prod-microservice"),
FilterType: pulumi.String("PREFIX_MATCH"),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;
return await Deployment.RunAsync(() =>
{
var current = Aws.GetCallerIdentity.Invoke();
var example = Aws.GetRegions.Invoke();
var exampleReplicationConfiguration = new Aws.Ecr.ReplicationConfiguration("example", new()
{
ReplicationConfigurationDetails = new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationArgs
{
Rules = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleArgs
{
Destinations = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleDestinationArgs
{
Region = example.Apply(getRegionsResult => getRegionsResult.Names[0]),
RegistryId = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
},
},
RepositoryFilters = new[]
{
new Aws.Ecr.Inputs.ReplicationConfigurationReplicationConfigurationRuleRepositoryFilterArgs
{
Filter = "prod-microservice",
FilterType = "PREFIX_MATCH",
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.inputs.GetRegionsArgs;
import com.pulumi.aws.ecr.ReplicationConfiguration;
import com.pulumi.aws.ecr.ReplicationConfigurationArgs;
import com.pulumi.aws.ecr.inputs.ReplicationConfigurationReplicationConfigurationArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
.build());
final var example = AwsFunctions.getRegions(GetRegionsArgs.builder()
.build());
var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
.replicationConfiguration(ReplicationConfigurationReplicationConfigurationArgs.builder()
.rules(ReplicationConfigurationReplicationConfigurationRuleArgs.builder()
.destinations(ReplicationConfigurationReplicationConfigurationRuleDestinationArgs.builder()
.region(example.names()[0])
.registryId(current.accountId())
.build())
.repositoryFilters(ReplicationConfigurationReplicationConfigurationRuleRepositoryFilterArgs.builder()
.filter("prod-microservice")
.filterType("PREFIX_MATCH")
.build())
.build())
.build())
.build());
}
}
resources:
exampleReplicationConfiguration:
type: aws:ecr:ReplicationConfiguration
name: example
properties:
replicationConfiguration:
rules:
- destinations:
- region: ${example.names[0]}
registryId: ${current.accountId}
repositoryFilters:
- filter: prod-microservice
filterType: PREFIX_MATCH
variables:
current:
fn::invoke:
function: aws:getCallerIdentity
arguments: {}
example:
fn::invoke:
function: aws:getRegions
arguments: {}
The repositoryFilters array limits which repositories participate in replication. The filter property specifies a string to match; filterType determines the matching behavior. PREFIX_MATCH replicates repositories whose names start with the filter value, allowing you to replicate entire application families (e.g., all repositories starting with “prod-microservice”).
Beyond these examples
These snippets focus on specific replication configuration features: single and multi-region replication, and repository filtering by prefix. They’re intentionally minimal rather than complete registry management solutions.
The examples assume pre-existing infrastructure such as ECR repositories to replicate, and target regions enabled in the AWS account. They focus on configuring replication rules rather than provisioning repositories or managing cross-account access.
To keep things focused, common replication patterns are omitted, including:
- Cross-account replication (different registryId values)
- Repository filters using EXACT_MATCH filterType
- Multiple rules with different filter criteria
- Replication to AWS accounts in different organizations
These omissions are intentional: the goal is to illustrate how replication rules are wired, not provide drop-in registry modules. See the ECR ReplicationConfiguration resource reference for all available configuration options.
Let's configure AWS ECR Replication
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Configuration & Setup
replicationConfiguration with rules containing destinations that specify the target region and registryId. The basic example shows replication to a single region using the current account ID.destinations array within a single rule. Each destination specifies its own region and registryId.destinations configuration accepts any valid registryId. While the examples show same-account replication using the current account ID, you can specify a different account’s registry ID.Repository Filtering
repositoryFilters within your replication rules. Each filter specifies a filter string and filterType. For example, use filterType: "PREFIX_MATCH" with filter: "prod-microservice" to replicate only repositories starting with that prefix.repositoryFilters is an array that can contain multiple filter objects, each with its own filter and filterType.Import & Management
pulumi import with the registry ID: pulumi import aws:ecr/replicationConfiguration:ReplicationConfiguration service 012345678912Using a different cloud?
Explore containers guides for other cloud providers: