The azure-native:storage:ObjectReplicationPolicy resource, part of the Pulumi Azure Native provider, defines object replication policies that asynchronously copy blobs between storage accounts. This guide focuses on three capabilities: destination-side policy creation, source-side policy linking, and multi-rule policy updates.
Object replication requires two storage accounts with versioning and change feed enabled, plus existing containers in both accounts. The examples are intentionally small. Combine them with your own storage accounts, containers, and access policies.
Create a policy on the destination account
Object replication setup begins on the destination account, where you define which containers receive replicated objects and what filtering rules apply.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const objectReplicationPolicy = new azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy", {
accountName: "dst112",
destinationAccount: "dst112",
metrics: {
enabled: true,
},
objectReplicationPolicyId: "default",
resourceGroupName: "res7687",
rules: [{
destinationContainer: "dcont139",
filters: {
prefixMatch: [
"blobA",
"blobB",
],
},
sourceContainer: "scont139",
}],
sourceAccount: "src1122",
});
import pulumi
import pulumi_azure_native as azure_native
object_replication_policy = azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy",
account_name="dst112",
destination_account="dst112",
metrics={
"enabled": True,
},
object_replication_policy_id="default",
resource_group_name="res7687",
rules=[{
"destination_container": "dcont139",
"filters": {
"prefix_match": [
"blobA",
"blobB",
],
},
"source_container": "scont139",
}],
source_account="src1122")
package main
import (
storage "github.com/pulumi/pulumi-azure-native-sdk/storage/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := storage.NewObjectReplicationPolicy(ctx, "objectReplicationPolicy", &storage.ObjectReplicationPolicyArgs{
AccountName: pulumi.String("dst112"),
DestinationAccount: pulumi.String("dst112"),
Metrics: &storage.ObjectReplicationPolicyPropertiesMetricsArgs{
Enabled: pulumi.Bool(true),
},
ObjectReplicationPolicyId: pulumi.String("default"),
ResourceGroupName: pulumi.String("res7687"),
Rules: storage.ObjectReplicationPolicyRuleArray{
&storage.ObjectReplicationPolicyRuleArgs{
DestinationContainer: pulumi.String("dcont139"),
Filters: &storage.ObjectReplicationPolicyFilterArgs{
PrefixMatch: pulumi.StringArray{
pulumi.String("blobA"),
pulumi.String("blobB"),
},
},
SourceContainer: pulumi.String("scont139"),
},
},
SourceAccount: pulumi.String("src1122"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var objectReplicationPolicy = new AzureNative.Storage.ObjectReplicationPolicy("objectReplicationPolicy", new()
{
AccountName = "dst112",
DestinationAccount = "dst112",
Metrics = new AzureNative.Storage.Inputs.ObjectReplicationPolicyPropertiesMetricsArgs
{
Enabled = true,
},
ObjectReplicationPolicyId = "default",
ResourceGroupName = "res7687",
Rules = new[]
{
new AzureNative.Storage.Inputs.ObjectReplicationPolicyRuleArgs
{
DestinationContainer = "dcont139",
Filters = new AzureNative.Storage.Inputs.ObjectReplicationPolicyFilterArgs
{
PrefixMatch = new[]
{
"blobA",
"blobB",
},
},
SourceContainer = "scont139",
},
},
SourceAccount = "src1122",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.ObjectReplicationPolicy;
import com.pulumi.azurenative.storage.ObjectReplicationPolicyArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyPropertiesMetricsArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyRuleArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyFilterArgs;
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) {
var objectReplicationPolicy = new ObjectReplicationPolicy("objectReplicationPolicy", ObjectReplicationPolicyArgs.builder()
.accountName("dst112")
.destinationAccount("dst112")
.metrics(ObjectReplicationPolicyPropertiesMetricsArgs.builder()
.enabled(true)
.build())
.objectReplicationPolicyId("default")
.resourceGroupName("res7687")
.rules(ObjectReplicationPolicyRuleArgs.builder()
.destinationContainer("dcont139")
.filters(ObjectReplicationPolicyFilterArgs.builder()
.prefixMatch(
"blobA",
"blobB")
.build())
.sourceContainer("scont139")
.build())
.sourceAccount("src1122")
.build());
}
}
resources:
objectReplicationPolicy:
type: azure-native:storage:ObjectReplicationPolicy
properties:
accountName: dst112
destinationAccount: dst112
metrics:
enabled: true
objectReplicationPolicyId: default
resourceGroupName: res7687
rules:
- destinationContainer: dcont139
filters:
prefixMatch:
- blobA
- blobB
sourceContainer: scont139
sourceAccount: src1122
The destinationAccount and sourceAccount properties identify the two storage accounts involved. Each rule in the rules array maps a sourceContainer to a destinationContainer. The filters property lets you replicate only blobs matching specific prefixes. Azure generates a policy ID and rule IDs when you create this resource; you’ll need these values to configure the source account.
Configure the source account with policy and rule IDs
After creating the destination policy, you configure the source account using the policy ID and rule IDs that Azure returned.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const objectReplicationPolicy = new azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy", {
accountName: "src1122",
destinationAccount: "dst112",
metrics: {
enabled: true,
},
objectReplicationPolicyId: "2a20bb73-5717-4635-985a-5d4cf777438f",
resourceGroupName: "res7687",
rules: [{
destinationContainer: "dcont139",
filters: {
minCreationTime: "2020-02-19T16:05:00Z",
prefixMatch: [
"blobA",
"blobB",
],
},
ruleId: "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
sourceContainer: "scont139",
}],
sourceAccount: "src1122",
});
import pulumi
import pulumi_azure_native as azure_native
object_replication_policy = azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy",
account_name="src1122",
destination_account="dst112",
metrics={
"enabled": True,
},
object_replication_policy_id="2a20bb73-5717-4635-985a-5d4cf777438f",
resource_group_name="res7687",
rules=[{
"destination_container": "dcont139",
"filters": {
"min_creation_time": "2020-02-19T16:05:00Z",
"prefix_match": [
"blobA",
"blobB",
],
},
"rule_id": "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
"source_container": "scont139",
}],
source_account="src1122")
package main
import (
storage "github.com/pulumi/pulumi-azure-native-sdk/storage/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := storage.NewObjectReplicationPolicy(ctx, "objectReplicationPolicy", &storage.ObjectReplicationPolicyArgs{
AccountName: pulumi.String("src1122"),
DestinationAccount: pulumi.String("dst112"),
Metrics: &storage.ObjectReplicationPolicyPropertiesMetricsArgs{
Enabled: pulumi.Bool(true),
},
ObjectReplicationPolicyId: pulumi.String("2a20bb73-5717-4635-985a-5d4cf777438f"),
ResourceGroupName: pulumi.String("res7687"),
Rules: storage.ObjectReplicationPolicyRuleArray{
&storage.ObjectReplicationPolicyRuleArgs{
DestinationContainer: pulumi.String("dcont139"),
Filters: &storage.ObjectReplicationPolicyFilterArgs{
MinCreationTime: pulumi.String("2020-02-19T16:05:00Z"),
PrefixMatch: pulumi.StringArray{
pulumi.String("blobA"),
pulumi.String("blobB"),
},
},
RuleId: pulumi.String("d5d18a48-8801-4554-aeaa-74faf65f5ef9"),
SourceContainer: pulumi.String("scont139"),
},
},
SourceAccount: pulumi.String("src1122"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var objectReplicationPolicy = new AzureNative.Storage.ObjectReplicationPolicy("objectReplicationPolicy", new()
{
AccountName = "src1122",
DestinationAccount = "dst112",
Metrics = new AzureNative.Storage.Inputs.ObjectReplicationPolicyPropertiesMetricsArgs
{
Enabled = true,
},
ObjectReplicationPolicyId = "2a20bb73-5717-4635-985a-5d4cf777438f",
ResourceGroupName = "res7687",
Rules = new[]
{
new AzureNative.Storage.Inputs.ObjectReplicationPolicyRuleArgs
{
DestinationContainer = "dcont139",
Filters = new AzureNative.Storage.Inputs.ObjectReplicationPolicyFilterArgs
{
MinCreationTime = "2020-02-19T16:05:00Z",
PrefixMatch = new[]
{
"blobA",
"blobB",
},
},
RuleId = "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
SourceContainer = "scont139",
},
},
SourceAccount = "src1122",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.ObjectReplicationPolicy;
import com.pulumi.azurenative.storage.ObjectReplicationPolicyArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyPropertiesMetricsArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyRuleArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyFilterArgs;
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) {
var objectReplicationPolicy = new ObjectReplicationPolicy("objectReplicationPolicy", ObjectReplicationPolicyArgs.builder()
.accountName("src1122")
.destinationAccount("dst112")
.metrics(ObjectReplicationPolicyPropertiesMetricsArgs.builder()
.enabled(true)
.build())
.objectReplicationPolicyId("2a20bb73-5717-4635-985a-5d4cf777438f")
.resourceGroupName("res7687")
.rules(ObjectReplicationPolicyRuleArgs.builder()
.destinationContainer("dcont139")
.filters(ObjectReplicationPolicyFilterArgs.builder()
.minCreationTime("2020-02-19T16:05:00Z")
.prefixMatch(
"blobA",
"blobB")
.build())
.ruleId("d5d18a48-8801-4554-aeaa-74faf65f5ef9")
.sourceContainer("scont139")
.build())
.sourceAccount("src1122")
.build());
}
}
resources:
objectReplicationPolicy:
type: azure-native:storage:ObjectReplicationPolicy
properties:
accountName: src1122
destinationAccount: dst112
metrics:
enabled: true
objectReplicationPolicyId: 2a20bb73-5717-4635-985a-5d4cf777438f
resourceGroupName: res7687
rules:
- destinationContainer: dcont139
filters:
minCreationTime: 2020-02-19T16:05:00Z
prefixMatch:
- blobA
- blobB
ruleId: d5d18a48-8801-4554-aeaa-74faf65f5ef9
sourceContainer: scont139
sourceAccount: src1122
The objectReplicationPolicyId must match the policy ID from the destination account. Each rule needs its ruleId from the destination policy. The minCreationTime property limits replication to blobs created after a specific timestamp, useful for avoiding large initial sync operations. This completes the bidirectional link: the source account now knows where to send replicated blobs.
Add replication rules to an existing policy
Policies can be updated to replicate additional container pairs without disrupting existing replication.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const objectReplicationPolicy = new azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy", {
accountName: "dst112",
destinationAccount: "dst112",
metrics: {
enabled: true,
},
objectReplicationPolicyId: "2a20bb73-5717-4635-985a-5d4cf777438f",
resourceGroupName: "res7687",
rules: [
{
destinationContainer: "dcont139",
filters: {
prefixMatch: [
"blobA",
"blobB",
],
},
ruleId: "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
sourceContainer: "scont139",
},
{
destinationContainer: "dcont179",
sourceContainer: "scont179",
},
],
sourceAccount: "src1122",
});
import pulumi
import pulumi_azure_native as azure_native
object_replication_policy = azure_native.storage.ObjectReplicationPolicy("objectReplicationPolicy",
account_name="dst112",
destination_account="dst112",
metrics={
"enabled": True,
},
object_replication_policy_id="2a20bb73-5717-4635-985a-5d4cf777438f",
resource_group_name="res7687",
rules=[
{
"destination_container": "dcont139",
"filters": {
"prefix_match": [
"blobA",
"blobB",
],
},
"rule_id": "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
"source_container": "scont139",
},
{
"destination_container": "dcont179",
"source_container": "scont179",
},
],
source_account="src1122")
package main
import (
storage "github.com/pulumi/pulumi-azure-native-sdk/storage/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := storage.NewObjectReplicationPolicy(ctx, "objectReplicationPolicy", &storage.ObjectReplicationPolicyArgs{
AccountName: pulumi.String("dst112"),
DestinationAccount: pulumi.String("dst112"),
Metrics: &storage.ObjectReplicationPolicyPropertiesMetricsArgs{
Enabled: pulumi.Bool(true),
},
ObjectReplicationPolicyId: pulumi.String("2a20bb73-5717-4635-985a-5d4cf777438f"),
ResourceGroupName: pulumi.String("res7687"),
Rules: storage.ObjectReplicationPolicyRuleArray{
&storage.ObjectReplicationPolicyRuleArgs{
DestinationContainer: pulumi.String("dcont139"),
Filters: &storage.ObjectReplicationPolicyFilterArgs{
PrefixMatch: pulumi.StringArray{
pulumi.String("blobA"),
pulumi.String("blobB"),
},
},
RuleId: pulumi.String("d5d18a48-8801-4554-aeaa-74faf65f5ef9"),
SourceContainer: pulumi.String("scont139"),
},
&storage.ObjectReplicationPolicyRuleArgs{
DestinationContainer: pulumi.String("dcont179"),
SourceContainer: pulumi.String("scont179"),
},
},
SourceAccount: pulumi.String("src1122"),
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using AzureNative = Pulumi.AzureNative;
return await Deployment.RunAsync(() =>
{
var objectReplicationPolicy = new AzureNative.Storage.ObjectReplicationPolicy("objectReplicationPolicy", new()
{
AccountName = "dst112",
DestinationAccount = "dst112",
Metrics = new AzureNative.Storage.Inputs.ObjectReplicationPolicyPropertiesMetricsArgs
{
Enabled = true,
},
ObjectReplicationPolicyId = "2a20bb73-5717-4635-985a-5d4cf777438f",
ResourceGroupName = "res7687",
Rules = new[]
{
new AzureNative.Storage.Inputs.ObjectReplicationPolicyRuleArgs
{
DestinationContainer = "dcont139",
Filters = new AzureNative.Storage.Inputs.ObjectReplicationPolicyFilterArgs
{
PrefixMatch = new[]
{
"blobA",
"blobB",
},
},
RuleId = "d5d18a48-8801-4554-aeaa-74faf65f5ef9",
SourceContainer = "scont139",
},
new AzureNative.Storage.Inputs.ObjectReplicationPolicyRuleArgs
{
DestinationContainer = "dcont179",
SourceContainer = "scont179",
},
},
SourceAccount = "src1122",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.storage.ObjectReplicationPolicy;
import com.pulumi.azurenative.storage.ObjectReplicationPolicyArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyPropertiesMetricsArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyRuleArgs;
import com.pulumi.azurenative.storage.inputs.ObjectReplicationPolicyFilterArgs;
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) {
var objectReplicationPolicy = new ObjectReplicationPolicy("objectReplicationPolicy", ObjectReplicationPolicyArgs.builder()
.accountName("dst112")
.destinationAccount("dst112")
.metrics(ObjectReplicationPolicyPropertiesMetricsArgs.builder()
.enabled(true)
.build())
.objectReplicationPolicyId("2a20bb73-5717-4635-985a-5d4cf777438f")
.resourceGroupName("res7687")
.rules(
ObjectReplicationPolicyRuleArgs.builder()
.destinationContainer("dcont139")
.filters(ObjectReplicationPolicyFilterArgs.builder()
.prefixMatch(
"blobA",
"blobB")
.build())
.ruleId("d5d18a48-8801-4554-aeaa-74faf65f5ef9")
.sourceContainer("scont139")
.build(),
ObjectReplicationPolicyRuleArgs.builder()
.destinationContainer("dcont179")
.sourceContainer("scont179")
.build())
.sourceAccount("src1122")
.build());
}
}
resources:
objectReplicationPolicy:
type: azure-native:storage:ObjectReplicationPolicy
properties:
accountName: dst112
destinationAccount: dst112
metrics:
enabled: true
objectReplicationPolicyId: 2a20bb73-5717-4635-985a-5d4cf777438f
resourceGroupName: res7687
rules:
- destinationContainer: dcont139
filters:
prefixMatch:
- blobA
- blobB
ruleId: d5d18a48-8801-4554-aeaa-74faf65f5ef9
sourceContainer: scont139
- destinationContainer: dcont179
sourceContainer: scont179
sourceAccount: src1122
You can add new rules to the rules array while keeping existing ones. Each rule operates independently, so adding a second rule (scont179 to dcont179) doesn’t affect the first rule’s replication. The second rule omits filters, meaning it replicates all blobs in the source container.
Beyond these examples
These snippets focus on specific policy-level features: destination and source policy configuration, prefix-based filtering and time-based replication, and multi-rule policies. They’re intentionally minimal rather than full replication deployments.
The examples reference pre-existing infrastructure such as source and destination storage accounts with versioning enabled, blob containers in both accounts, and policy and rule IDs from destination account for source configuration. They focus on configuring the policy rather than provisioning the storage infrastructure.
To keep things focused, common replication patterns are omitted, including:
- Change feed enablement (required Azure prerequisite)
- Cross-tenant replication (allowCrossTenantReplication)
- Metrics configuration details (metrics.enabled shown but not explained)
- Policy deletion and lifecycle management
These omissions are intentional: the goal is to illustrate how each policy feature is wired, not provide drop-in replication modules. See the ObjectReplicationPolicy resource reference for all available configuration options.
Let's configure Azure Storage Object Replication Policies
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Setup & Configuration
Object replication requires a two-step setup process:
- Destination account: Create the policy with
objectReplicationPolicyIdset to"default" - Source account: Create the policy using the
policyIdreturned from the destination (a UUID)
Configure accountName to match whichever account you’re setting up in each step.
accountName specifies where you’re configuring the policy (immutable). sourceAccount and destinationAccount (both required) identify the two storage accounts involved in replication. When configuring the destination, accountName matches destinationAccount. When configuring the source, accountName matches sourceAccount.Rules & Filtering
Use the filters property within each rule. You can specify:
prefixMatch: Array of blob name prefixes (e.g.,["blobA", "blobB"])minCreationTime: ISO 8601 timestamp to replicate only blobs created after this time
ruleId for new rules. On the source account, specify ruleId for all rules (existing and new).Policy IDs & Immutability
"default" when creating the policy on the destination account. Use the UUID returned from the destination’s policyId output when creating the policy on the source account.accountName, objectReplicationPolicyId, and resourceGroupName are immutable. Changing any of these requires recreating the resource.Cross-Tenant Replication
allowCrossTenantReplication is set to false, both sourceAccount and destinationAccount must be specified as full resource IDs rather than just account names.metrics property with enabled: true to enable object replication policy metrics.