Create AWS FSx Backups

The aws:fsx/backup:Backup resource, part of the Pulumi AWS provider, creates manual backups of FSx file systems or ONTAP volumes for disaster recovery and data migration. This guide focuses on four capabilities: Lustre file system backups, Windows file system backups, ONTAP volume backups, and OpenZFS file system backups.

Backups reference existing FSx file systems or ONTAP volumes. The examples are intentionally small. Combine them with your own file system provisioning and backup scheduling logic.

Back up a Lustre file system

High-performance computing workloads running on FSx for Lustre need point-in-time backups for disaster recovery or data migration between file systems.

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

const exampleLustreFileSystem = new aws.fsx.LustreFileSystem("example", {
    storageCapacity: 1200,
    subnetIds: exampleAwsSubnet.id,
    deploymentType: "PERSISTENT_1",
    perUnitStorageThroughput: 50,
});
const example = new aws.fsx.Backup("example", {fileSystemId: exampleLustreFileSystem.id});
import pulumi
import pulumi_aws as aws

example_lustre_file_system = aws.fsx.LustreFileSystem("example",
    storage_capacity=1200,
    subnet_ids=example_aws_subnet["id"],
    deployment_type="PERSISTENT_1",
    per_unit_storage_throughput=50)
example = aws.fsx.Backup("example", file_system_id=example_lustre_file_system.id)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleLustreFileSystem, err := fsx.NewLustreFileSystem(ctx, "example", &fsx.LustreFileSystemArgs{
			StorageCapacity:          pulumi.Int(1200),
			SubnetIds:                pulumi.Any(exampleAwsSubnet.Id),
			DeploymentType:           pulumi.String("PERSISTENT_1"),
			PerUnitStorageThroughput: pulumi.Int(50),
		})
		if err != nil {
			return err
		}
		_, err = fsx.NewBackup(ctx, "example", &fsx.BackupArgs{
			FileSystemId: exampleLustreFileSystem.ID(),
		})
		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 exampleLustreFileSystem = new Aws.Fsx.LustreFileSystem("example", new()
    {
        StorageCapacity = 1200,
        SubnetIds = exampleAwsSubnet.Id,
        DeploymentType = "PERSISTENT_1",
        PerUnitStorageThroughput = 50,
    });

    var example = new Aws.Fsx.Backup("example", new()
    {
        FileSystemId = exampleLustreFileSystem.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.fsx.LustreFileSystem;
import com.pulumi.aws.fsx.LustreFileSystemArgs;
import com.pulumi.aws.fsx.Backup;
import com.pulumi.aws.fsx.BackupArgs;
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 exampleLustreFileSystem = new LustreFileSystem("exampleLustreFileSystem", LustreFileSystemArgs.builder()
            .storageCapacity(1200)
            .subnetIds(exampleAwsSubnet.id())
            .deploymentType("PERSISTENT_1")
            .perUnitStorageThroughput(50)
            .build());

        var example = new Backup("example", BackupArgs.builder()
            .fileSystemId(exampleLustreFileSystem.id())
            .build());

    }
}
resources:
  example:
    type: aws:fsx:Backup
    properties:
      fileSystemId: ${exampleLustreFileSystem.id}
  exampleLustreFileSystem:
    type: aws:fsx:LustreFileSystem
    name: example
    properties:
      storageCapacity: 1200
      subnetIds: ${exampleAwsSubnet.id}
      deploymentType: PERSISTENT_1
      perUnitStorageThroughput: 50

The fileSystemId property references the Lustre file system to back up. FSx creates a consistent snapshot of the file system at the time the backup resource is created. Lustre, Windows, and OpenZFS file systems all use fileSystemId.

Back up a Windows file system

Windows file servers integrated with Active Directory require backups to protect shared drives and user data.

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

const exampleWindowsFileSystem = new aws.fsx.WindowsFileSystem("example", {
    activeDirectoryId: eample.id,
    skipFinalBackup: true,
    storageCapacity: 32,
    subnetIds: [example1.id],
    throughputCapacity: 8,
});
const example = new aws.fsx.Backup("example", {fileSystemId: exampleWindowsFileSystem.id});
import pulumi
import pulumi_aws as aws

example_windows_file_system = aws.fsx.WindowsFileSystem("example",
    active_directory_id=eample["id"],
    skip_final_backup=True,
    storage_capacity=32,
    subnet_ids=[example1["id"]],
    throughput_capacity=8)
example = aws.fsx.Backup("example", file_system_id=example_windows_file_system.id)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleWindowsFileSystem, err := fsx.NewWindowsFileSystem(ctx, "example", &fsx.WindowsFileSystemArgs{
			ActiveDirectoryId: pulumi.Any(eample.Id),
			SkipFinalBackup:   pulumi.Bool(true),
			StorageCapacity:   pulumi.Int(32),
			SubnetIds: pulumi.StringArray{
				example1.Id,
			},
			ThroughputCapacity: pulumi.Int(8),
		})
		if err != nil {
			return err
		}
		_, err = fsx.NewBackup(ctx, "example", &fsx.BackupArgs{
			FileSystemId: exampleWindowsFileSystem.ID(),
		})
		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 exampleWindowsFileSystem = new Aws.Fsx.WindowsFileSystem("example", new()
    {
        ActiveDirectoryId = eample.Id,
        SkipFinalBackup = true,
        StorageCapacity = 32,
        SubnetIds = new[]
        {
            example1.Id,
        },
        ThroughputCapacity = 8,
    });

    var example = new Aws.Fsx.Backup("example", new()
    {
        FileSystemId = exampleWindowsFileSystem.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.fsx.WindowsFileSystem;
import com.pulumi.aws.fsx.WindowsFileSystemArgs;
import com.pulumi.aws.fsx.Backup;
import com.pulumi.aws.fsx.BackupArgs;
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 exampleWindowsFileSystem = new WindowsFileSystem("exampleWindowsFileSystem", WindowsFileSystemArgs.builder()
            .activeDirectoryId(eample.id())
            .skipFinalBackup(true)
            .storageCapacity(32)
            .subnetIds(example1.id())
            .throughputCapacity(8)
            .build());

        var example = new Backup("example", BackupArgs.builder()
            .fileSystemId(exampleWindowsFileSystem.id())
            .build());

    }
}
resources:
  example:
    type: aws:fsx:Backup
    properties:
      fileSystemId: ${exampleWindowsFileSystem.id}
  exampleWindowsFileSystem:
    type: aws:fsx:WindowsFileSystem
    name: example
    properties:
      activeDirectoryId: ${eample.id}
      skipFinalBackup: true
      storageCapacity: 32
      subnetIds:
        - ${example1.id}
      throughputCapacity: 8

The backup captures the Windows file system state, including Active Directory integration and share configurations. The fileSystemId property points to the Windows file system resource.

Back up an ONTAP volume

NetApp ONTAP volumes store application data that needs volume-level backups rather than file system backups.

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

const exampleOntapVolume = new aws.fsx.OntapVolume("example", {
    name: "example",
    junctionPath: "/example",
    sizeInMegabytes: 1024,
    storageEfficiencyEnabled: true,
    storageVirtualMachineId: test.id,
});
const example = new aws.fsx.Backup("example", {volumeId: exampleOntapVolume.id});
import pulumi
import pulumi_aws as aws

example_ontap_volume = aws.fsx.OntapVolume("example",
    name="example",
    junction_path="/example",
    size_in_megabytes=1024,
    storage_efficiency_enabled=True,
    storage_virtual_machine_id=test["id"])
example = aws.fsx.Backup("example", volume_id=example_ontap_volume.id)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleOntapVolume, err := fsx.NewOntapVolume(ctx, "example", &fsx.OntapVolumeArgs{
			Name:                     pulumi.String("example"),
			JunctionPath:             pulumi.String("/example"),
			SizeInMegabytes:          pulumi.Int(1024),
			StorageEfficiencyEnabled: pulumi.Bool(true),
			StorageVirtualMachineId:  pulumi.Any(test.Id),
		})
		if err != nil {
			return err
		}
		_, err = fsx.NewBackup(ctx, "example", &fsx.BackupArgs{
			VolumeId: exampleOntapVolume.ID(),
		})
		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 exampleOntapVolume = new Aws.Fsx.OntapVolume("example", new()
    {
        Name = "example",
        JunctionPath = "/example",
        SizeInMegabytes = 1024,
        StorageEfficiencyEnabled = true,
        StorageVirtualMachineId = test.Id,
    });

    var example = new Aws.Fsx.Backup("example", new()
    {
        VolumeId = exampleOntapVolume.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.fsx.OntapVolume;
import com.pulumi.aws.fsx.OntapVolumeArgs;
import com.pulumi.aws.fsx.Backup;
import com.pulumi.aws.fsx.BackupArgs;
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 exampleOntapVolume = new OntapVolume("exampleOntapVolume", OntapVolumeArgs.builder()
            .name("example")
            .junctionPath("/example")
            .sizeInMegabytes(1024)
            .storageEfficiencyEnabled(true)
            .storageVirtualMachineId(test.id())
            .build());

        var example = new Backup("example", BackupArgs.builder()
            .volumeId(exampleOntapVolume.id())
            .build());

    }
}
resources:
  example:
    type: aws:fsx:Backup
    properties:
      volumeId: ${exampleOntapVolume.id}
  exampleOntapVolume:
    type: aws:fsx:OntapVolume
    name: example
    properties:
      name: example
      junctionPath: /example
      sizeInMegabytes: 1024
      storageEfficiencyEnabled: true
      storageVirtualMachineId: ${test.id}

ONTAP backups use volumeId instead of fileSystemId because ONTAP organizes storage into volumes within file systems. The backup captures the volume’s data and configuration at a point in time.

Back up an OpenZFS file system

OpenZFS file systems provide ZFS features on AWS and need backups for data protection and cloning workflows.

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

const exampleOpenZfsFileSystem = new aws.fsx.OpenZfsFileSystem("example", {
    storageCapacity: 64,
    subnetIds: [exampleAwsSubnet.id],
    deploymentType: "SINGLE_AZ_1",
    throughputCapacity: 64,
});
const example = new aws.fsx.Backup("example", {fileSystemId: exampleOpenZfsFileSystem.id});
import pulumi
import pulumi_aws as aws

example_open_zfs_file_system = aws.fsx.OpenZfsFileSystem("example",
    storage_capacity=64,
    subnet_ids=[example_aws_subnet["id"]],
    deployment_type="SINGLE_AZ_1",
    throughput_capacity=64)
example = aws.fsx.Backup("example", file_system_id=example_open_zfs_file_system.id)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleOpenZfsFileSystem, err := fsx.NewOpenZfsFileSystem(ctx, "example", &fsx.OpenZfsFileSystemArgs{
			StorageCapacity: pulumi.Int(64),
			SubnetIds: pulumi.StringArray{
				exampleAwsSubnet.Id,
			},
			DeploymentType:     pulumi.String("SINGLE_AZ_1"),
			ThroughputCapacity: pulumi.Int(64),
		})
		if err != nil {
			return err
		}
		_, err = fsx.NewBackup(ctx, "example", &fsx.BackupArgs{
			FileSystemId: exampleOpenZfsFileSystem.ID(),
		})
		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 exampleOpenZfsFileSystem = new Aws.Fsx.OpenZfsFileSystem("example", new()
    {
        StorageCapacity = 64,
        SubnetIds = new[]
        {
            exampleAwsSubnet.Id,
        },
        DeploymentType = "SINGLE_AZ_1",
        ThroughputCapacity = 64,
    });

    var example = new Aws.Fsx.Backup("example", new()
    {
        FileSystemId = exampleOpenZfsFileSystem.Id,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.fsx.OpenZfsFileSystem;
import com.pulumi.aws.fsx.OpenZfsFileSystemArgs;
import com.pulumi.aws.fsx.Backup;
import com.pulumi.aws.fsx.BackupArgs;
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 exampleOpenZfsFileSystem = new OpenZfsFileSystem("exampleOpenZfsFileSystem", OpenZfsFileSystemArgs.builder()
            .storageCapacity(64)
            .subnetIds(exampleAwsSubnet.id())
            .deploymentType("SINGLE_AZ_1")
            .throughputCapacity(64)
            .build());

        var example = new Backup("example", BackupArgs.builder()
            .fileSystemId(exampleOpenZfsFileSystem.id())
            .build());

    }
}
resources:
  example:
    type: aws:fsx:Backup
    properties:
      fileSystemId: ${exampleOpenZfsFileSystem.id}
  exampleOpenZfsFileSystem:
    type: aws:fsx:OpenZfsFileSystem
    name: example
    properties:
      storageCapacity: 64
      subnetIds:
        - ${exampleAwsSubnet.id}
      deploymentType: SINGLE_AZ_1
      throughputCapacity: 64

OpenZFS backups work like Lustre and Windows backups, using fileSystemId to reference the file system. The backup preserves ZFS features like compression and deduplication settings.

Beyond these examples

These snippets focus on specific backup capabilities: file system backups for Lustre, Windows, and OpenZFS, and volume backups for ONTAP. They’re intentionally minimal rather than full backup strategies.

The examples reference pre-existing infrastructure such as FSx file systems or volumes to back up, VPC subnets for file system placement, Active Directory for Windows file systems, and storage virtual machines for ONTAP volumes. They focus on creating backups rather than provisioning the underlying storage.

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

  • Backup tagging and organization (tags)
  • Automated backup schedules (requires separate backup plan resources)
  • Cross-region backup replication
  • Backup retention policies

These omissions are intentional: the goal is to illustrate how each backup type is wired, not provide drop-in backup modules. See the FSx Backup resource reference for all available configuration options.

Let's create AWS FSx Backups

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Backup Configuration
Which FSx file systems can I back up?
You can back up Lustre, Windows, and OpenZFS file systems using fileSystemId, or ONTAP volumes using volumeId.
What's the difference between fileSystemId and volumeId?
Use fileSystemId for Lustre, Windows, and OpenZFS file systems. Use volumeId for ONTAP volumes. You can only specify one, not both.
Can I change the file system or volume being backed up after creation?
No, both fileSystemId and volumeId are immutable. You’ll need to create a new backup resource to back up a different source.
Tags & Metadata
Why aren't my file system tags being copied to the backup?
If copy_tags_to_backups is enabled on the file system and you specify tags on the backup resource, existing file system tags won’t be copied. To copy file system tags, don’t specify tags on the backup.

Using a different cloud?

Explore storage guides for other cloud providers: