The aws:ecr/replicationConfiguration:ReplicationConfiguration resource, part of the Pulumi AWS provider, defines registry-level replication rules that automatically copy container images to destination regions and accounts. This guide focuses on two capabilities: single and multi-region replication, and repository filtering by prefix.
Replication configuration operates at the registry level and applies to existing ECR repositories. The examples are intentionally small. Combine them with your own repository naming conventions and multi-account strategies.
Replicate all repositories to a single region
Teams deploying multi-region applications need container images available in multiple AWS regions to reduce latency and improve availability.
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 replicates it to the destination region. The replicationConfiguration property defines rules with destinations arrays. Each destination specifies a region and registryId (the AWS account). Here, images replicate to the first available region in the current account.
Replicate to multiple regions simultaneously
Global applications often need images in several regions at once. A single rule can target multiple destinations.
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: {}
The destinations array can include multiple regions. ECR replicates each image push to all specified destinations in parallel, ensuring consistent availability across deployment regions. This extends the basic example by adding a second destination region.
Replicate only repositories matching a prefix
Organizations with many repositories often want selective replication to control costs and reduce data transfer.
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 property limits replication to repositories matching specific patterns. The filter property sets the prefix to match (e.g., “prod-microservice”), and filterType specifies how to match (PREFIX_MATCH checks if repository names start with the filter string). Only repositories matching the filter replicate to destinations.
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 full registry management solutions.
The examples assume pre-existing infrastructure such as ECR repositories in the source registry. 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)
- Advanced filter types beyond PREFIX_MATCH
- Replication to multiple accounts simultaneously
- Replication rule ordering and priority
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
Replication Setup
destinations array within a rule. Each destination specifies a region and registryId, as shown in the Multiple Region Usage example.registryId.Repository Filtering
repositoryFilters in your replication rule with a filter string and filterType. The example shows PREFIX_MATCH to replicate repositories matching a prefix like “prod-microservice”.PREFIX_MATCH replicates repositories whose names start with the specified filter string. For example, a filter of “prod-microservice” would match repositories like “prod-microservice-api” and “prod-microservice-web”.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: