Configure AWS EFS Replication

The aws:efs/replicationConfiguration:ReplicationConfiguration resource, part of the Pulumi AWS provider, establishes replication from a source EFS file system to a read-only destination in the same or another region. This guide focuses on three capabilities: cross-region disaster recovery, storage class and encryption configuration, and replication to existing file systems.

Replication requires an existing source file system and may reference KMS keys or destination file systems. Deleting the replication configuration stops replication but preserves the destination file system. The examples are intentionally small. Combine them with your own file systems, encryption keys, and monitoring.

Replicate to a new regional file system

Most replication deployments create a read-only replica in another region for disaster recovery.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.efs.FileSystem("example", {});
const exampleReplicationConfiguration = new aws.efs.ReplicationConfiguration("example", {
    sourceFileSystemId: example.id,
    destination: {
        region: "us-west-2",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.efs.FileSystem("example")
example_replication_configuration = aws.efs.ReplicationConfiguration("example",
    source_file_system_id=example.id,
    destination={
        "region": "us-west-2",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/efs"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := efs.NewFileSystem(ctx, "example", nil)
		if err != nil {
			return err
		}
		_, err = efs.NewReplicationConfiguration(ctx, "example", &efs.ReplicationConfigurationArgs{
			SourceFileSystemId: example.ID(),
			Destination: &efs.ReplicationConfigurationDestinationArgs{
				Region: pulumi.String("us-west-2"),
			},
		})
		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 example = new Aws.Efs.FileSystem("example");

    var exampleReplicationConfiguration = new Aws.Efs.ReplicationConfiguration("example", new()
    {
        SourceFileSystemId = example.Id,
        Destination = new Aws.Efs.Inputs.ReplicationConfigurationDestinationArgs
        {
            Region = "us-west-2",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.efs.FileSystem;
import com.pulumi.aws.efs.ReplicationConfiguration;
import com.pulumi.aws.efs.ReplicationConfigurationArgs;
import com.pulumi.aws.efs.inputs.ReplicationConfigurationDestinationArgs;
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 example = new FileSystem("example");

        var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
            .sourceFileSystemId(example.id())
            .destination(ReplicationConfigurationDestinationArgs.builder()
                .region("us-west-2")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:efs:FileSystem
  exampleReplicationConfiguration:
    type: aws:efs:ReplicationConfiguration
    name: example
    properties:
      sourceFileSystemId: ${example.id}
      destination:
        region: us-west-2

When you create the replication configuration, EFS automatically provisions a new destination file system in the specified region. The destination uses regional storage (replicated across multiple availability zones) and encrypts data with the AWS-managed EFS KMS key. The sourceFileSystemId identifies which file system to replicate; the destination.region specifies where the replica lives.

Replicate to One Zone storage with custom encryption

Applications with specific availability zone requirements or encryption policies can target One Zone storage and specify a customer-managed KMS key.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.efs.FileSystem("example", {});
const exampleReplicationConfiguration = new aws.efs.ReplicationConfiguration("example", {
    sourceFileSystemId: example.id,
    destination: {
        availabilityZoneName: "us-west-2b",
        kmsKeyId: "1234abcd-12ab-34cd-56ef-1234567890ab",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.efs.FileSystem("example")
example_replication_configuration = aws.efs.ReplicationConfiguration("example",
    source_file_system_id=example.id,
    destination={
        "availability_zone_name": "us-west-2b",
        "kms_key_id": "1234abcd-12ab-34cd-56ef-1234567890ab",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/efs"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := efs.NewFileSystem(ctx, "example", nil)
		if err != nil {
			return err
		}
		_, err = efs.NewReplicationConfiguration(ctx, "example", &efs.ReplicationConfigurationArgs{
			SourceFileSystemId: example.ID(),
			Destination: &efs.ReplicationConfigurationDestinationArgs{
				AvailabilityZoneName: pulumi.String("us-west-2b"),
				KmsKeyId:             pulumi.String("1234abcd-12ab-34cd-56ef-1234567890ab"),
			},
		})
		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 example = new Aws.Efs.FileSystem("example");

    var exampleReplicationConfiguration = new Aws.Efs.ReplicationConfiguration("example", new()
    {
        SourceFileSystemId = example.Id,
        Destination = new Aws.Efs.Inputs.ReplicationConfigurationDestinationArgs
        {
            AvailabilityZoneName = "us-west-2b",
            KmsKeyId = "1234abcd-12ab-34cd-56ef-1234567890ab",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.efs.FileSystem;
import com.pulumi.aws.efs.ReplicationConfiguration;
import com.pulumi.aws.efs.ReplicationConfigurationArgs;
import com.pulumi.aws.efs.inputs.ReplicationConfigurationDestinationArgs;
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 example = new FileSystem("example");

        var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
            .sourceFileSystemId(example.id())
            .destination(ReplicationConfigurationDestinationArgs.builder()
                .availabilityZoneName("us-west-2b")
                .kmsKeyId("1234abcd-12ab-34cd-56ef-1234567890ab")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:efs:FileSystem
  exampleReplicationConfiguration:
    type: aws:efs:ReplicationConfiguration
    name: example
    properties:
      sourceFileSystemId: ${example.id}
      destination:
        availabilityZoneName: us-west-2b
        kmsKeyId: 1234abcd-12ab-34cd-56ef-1234567890ab

The availabilityZoneName property places the replica in a specific availability zone, creating One Zone storage instead of regional. The kmsKeyId property specifies a customer-managed KMS key for encryption rather than using the AWS-managed default. One Zone storage reduces costs but concentrates the replica in a single availability zone.

Replicate to an existing file system

Teams with pre-provisioned file systems can configure replication to an existing destination rather than creating a new one.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.efs.FileSystem("example", {});
const exampleReplicationConfiguration = new aws.efs.ReplicationConfiguration("example", {
    sourceFileSystemId: example.id,
    destination: {
        fileSystemId: "fs-1234567890",
        region: "us-west-2",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.efs.FileSystem("example")
example_replication_configuration = aws.efs.ReplicationConfiguration("example",
    source_file_system_id=example.id,
    destination={
        "file_system_id": "fs-1234567890",
        "region": "us-west-2",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/efs"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := efs.NewFileSystem(ctx, "example", nil)
		if err != nil {
			return err
		}
		_, err = efs.NewReplicationConfiguration(ctx, "example", &efs.ReplicationConfigurationArgs{
			SourceFileSystemId: example.ID(),
			Destination: &efs.ReplicationConfigurationDestinationArgs{
				FileSystemId: pulumi.String("fs-1234567890"),
				Region:       pulumi.String("us-west-2"),
			},
		})
		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 example = new Aws.Efs.FileSystem("example");

    var exampleReplicationConfiguration = new Aws.Efs.ReplicationConfiguration("example", new()
    {
        SourceFileSystemId = example.Id,
        Destination = new Aws.Efs.Inputs.ReplicationConfigurationDestinationArgs
        {
            FileSystemId = "fs-1234567890",
            Region = "us-west-2",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.efs.FileSystem;
import com.pulumi.aws.efs.ReplicationConfiguration;
import com.pulumi.aws.efs.ReplicationConfigurationArgs;
import com.pulumi.aws.efs.inputs.ReplicationConfigurationDestinationArgs;
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 example = new FileSystem("example");

        var exampleReplicationConfiguration = new ReplicationConfiguration("exampleReplicationConfiguration", ReplicationConfigurationArgs.builder()
            .sourceFileSystemId(example.id())
            .destination(ReplicationConfigurationDestinationArgs.builder()
                .fileSystemId("fs-1234567890")
                .region("us-west-2")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:efs:FileSystem
  exampleReplicationConfiguration:
    type: aws:efs:ReplicationConfiguration
    name: example
    properties:
      sourceFileSystemId: ${example.id}
      destination:
        fileSystemId: fs-1234567890
        region: us-west-2

The fileSystemId property tells EFS to use an existing file system as the replication destination instead of creating a new one. The destination file system becomes read-only once replication starts. This approach works when you’ve already provisioned file systems with specific configurations or need to control the destination’s lifecycle independently.

Beyond these examples

These snippets focus on specific replication configuration features: cross-region replication, storage class and encryption control, and existing file system destinations. They’re intentionally minimal rather than full disaster recovery solutions.

The examples reference pre-existing infrastructure such as source EFS file systems, KMS keys for custom encryption, and destination file systems when using fileSystemId. They focus on configuring replication rather than provisioning the surrounding infrastructure.

To keep things focused, common replication patterns are omitted, including:

  • Replication monitoring and status checks
  • Failover and failback procedures
  • Performance mode and throughput configuration
  • Lifecycle policies and backup integration

These omissions are intentional: the goal is to illustrate how each replication feature is wired, not provide drop-in disaster recovery modules. See the EFS ReplicationConfiguration resource reference for all available configuration options.

Let's configure AWS EFS Replication

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Replication Lifecycle & Deletion
What happens to the destination file system when I delete the replication configuration?
The destination file system is not automatically deleted. It remains in your account but is no longer read-only and stops receiving updates from the source.
Is the replica file system read-only?
Yes, the destination file system is read-only while replication is active. It becomes writable only after you delete the replication configuration.
Destination Configuration
Can I replicate to an existing EFS file system?
Yes, specify destination.fileSystemId with an existing file system ID to use it as the replication target instead of creating a new one.
Can I replicate to a different AWS region?
Yes, specify destination.region to replicate to any AWS region, including the same region as the source.
How do I create a One Zone replica instead of regional storage?
Specify destination.availabilityZoneName with the target availability zone (e.g., us-west-2b) to create a One Zone storage class replica.
What encryption options are available for replicas?
Replicas are encrypted by default using the EFS KMS key /aws/elasticfilesystem. You can specify a custom KMS key using destination.kmsKeyId.
Immutability & Changes
Can I change the destination or source file system after creating the replication?
No, both destination and sourceFileSystemId are immutable. Changing either requires recreating the replication configuration.
What properties can't be modified after creation?
The destination configuration block and sourceFileSystemId are immutable and cannot be changed without recreating the resource.
Import & Troubleshooting
Why do I see a perpetual diff after importing my replication configuration?
Remove availabilityZoneName and kmsKeyId from your configuration before importing. The AWS API doesn’t return these values, causing Pulumi to detect them as changes.

Using a different cloud?

Explore storage guides for other cloud providers: