Configure AWS EFS Replication

The aws:efs/replicationConfiguration:ReplicationConfiguration resource, part of the Pulumi AWS provider, creates a read-only replica of an EFS file system in the same or another region. This guide focuses on three capabilities: cross-region replication with defaults, One Zone storage with custom encryption, and replication to existing file systems.

Replication requires a source file system and may reference KMS keys or destination file systems that already exist. The examples are intentionally small. Combine them with your own file system configuration, backup policies, and access controls.

Replicate to a new regional file system

Most replication setups create a read-only replica in another region for disaster recovery, letting EFS provision the destination automatically.

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 provisions a new destination file system in the specified region with regional storage and default encryption using /aws/elasticfilesystem. The sourceFileSystemId identifies the file system to replicate; the destination.region specifies where the replica lives.

Replicate to One Zone storage with custom encryption

For cost-optimized replication, you can target One Zone storage in a specific availability zone and control encryption with your own 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 single availability zone, reducing storage costs compared to regional replication. The kmsKeyId property specifies a customer-managed KMS key for encryption instead of the AWS-managed default.

Replicate to an existing file system

If you’ve already provisioned a destination file system, you can configure replication to use it 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 targets an existing file system as the replication destination. EFS converts the destination to read-only mode and begins replicating data from the source. This approach works when you need to control the destination file system’s configuration separately from the replication setup.

Beyond these examples

These snippets focus on specific replication configuration features: cross-region replication, storage class and encryption options, and existing file system targeting. 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 file system features.

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

  • Lifecycle policies and transition rules
  • Access points and mount targets
  • Backup policies and retention
  • Performance mode and throughput settings

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

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 after replication stops.
Configuration & Setup
Can I change the destination or source file system after creating the replication?
No, both sourceFileSystemId and destination are immutable. You must recreate the replication configuration to change these.
Can I use an existing file system as the replication destination?
Yes, specify the existing file system ID using destination.fileSystemId along with the target region.
What's the difference between Regional and One Zone replication?
Regional replication (default) stores data across multiple Availability Zones. One Zone replication stores data in a single AZ specified by destination.availabilityZoneName.
Can I replicate to a different AWS region?
Yes, specify the target region in destination.region. The examples show replication from the source region to us-west-2.
Encryption & Security
What encryption is used by default for replicas?
Replicas are encrypted using the default EFS KMS key /aws/elasticfilesystem unless you specify a custom key with destination.kmsKeyId.
Import & State Management
Why am I seeing a 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 show them as differences.
Can I import using either the source or destination file system ID?
Yes, you can import the replication configuration using the file system ID of either the source or destination.

Using a different cloud?

Explore storage guides for other cloud providers: