Create Azure Recovery Services Vaults

The azure-native:recoveryservices:Vault resource, part of the Pulumi Azure Native provider, provisions a Recovery Services vault that serves as the container for Azure Backup and Site Recovery operations. This guide focuses on three capabilities: managed identity setup, alert routing configuration, and storage redundancy options.

Recovery Services vaults belong to resource groups and use managed identities to authenticate backup and recovery operations against other Azure resources. The examples are intentionally small. Combine them with your own backup policies, protected items, and replication configurations.

Create a vault with system-assigned identity

Most deployments begin by creating a vault with a system-assigned managed identity, which Azure uses to authenticate backup and recovery operations.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const vault = new azure_native.recoveryservices.Vault("vault", {
    identity: {
        type: azure_native.recoveryservices.ResourceIdentityType.SystemAssigned,
    },
    location: "West US",
    properties: {
        publicNetworkAccess: azure_native.recoveryservices.PublicNetworkAccess.Enabled,
    },
    resourceGroupName: "Default-RecoveryServices-ResourceGroup",
    sku: {
        name: azure_native.recoveryservices.SkuName.Standard,
    },
    vaultName: "swaggerExample",
});
import pulumi
import pulumi_azure_native as azure_native

vault = azure_native.recoveryservices.Vault("vault",
    identity={
        "type": azure_native.recoveryservices.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    location="West US",
    properties={
        "public_network_access": azure_native.recoveryservices.PublicNetworkAccess.ENABLED,
    },
    resource_group_name="Default-RecoveryServices-ResourceGroup",
    sku={
        "name": azure_native.recoveryservices.SkuName.STANDARD,
    },
    vault_name="swaggerExample")
package main

import (
	recoveryservices "github.com/pulumi/pulumi-azure-native-sdk/recoveryservices/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := recoveryservices.NewVault(ctx, "vault", &recoveryservices.VaultArgs{
			Identity: &recoveryservices.IdentityDataArgs{
				Type: pulumi.String(recoveryservices.ResourceIdentityTypeSystemAssigned),
			},
			Location: pulumi.String("West US"),
			Properties: &recoveryservices.VaultPropertiesArgs{
				PublicNetworkAccess: pulumi.String(recoveryservices.PublicNetworkAccessEnabled),
			},
			ResourceGroupName: pulumi.String("Default-RecoveryServices-ResourceGroup"),
			Sku: &recoveryservices.SkuArgs{
				Name: pulumi.String(recoveryservices.SkuNameStandard),
			},
			VaultName: pulumi.String("swaggerExample"),
		})
		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 vault = new AzureNative.RecoveryServices.Vault("vault", new()
    {
        Identity = new AzureNative.RecoveryServices.Inputs.IdentityDataArgs
        {
            Type = AzureNative.RecoveryServices.ResourceIdentityType.SystemAssigned,
        },
        Location = "West US",
        Properties = new AzureNative.RecoveryServices.Inputs.VaultPropertiesArgs
        {
            PublicNetworkAccess = AzureNative.RecoveryServices.PublicNetworkAccess.Enabled,
        },
        ResourceGroupName = "Default-RecoveryServices-ResourceGroup",
        Sku = new AzureNative.RecoveryServices.Inputs.SkuArgs
        {
            Name = AzureNative.RecoveryServices.SkuName.Standard,
        },
        VaultName = "swaggerExample",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.recoveryservices.Vault;
import com.pulumi.azurenative.recoveryservices.VaultArgs;
import com.pulumi.azurenative.recoveryservices.inputs.IdentityDataArgs;
import com.pulumi.azurenative.recoveryservices.inputs.VaultPropertiesArgs;
import com.pulumi.azurenative.recoveryservices.inputs.SkuArgs;
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 vault = new Vault("vault", VaultArgs.builder()
            .identity(IdentityDataArgs.builder()
                .type("SystemAssigned")
                .build())
            .location("West US")
            .properties(VaultPropertiesArgs.builder()
                .publicNetworkAccess("Enabled")
                .build())
            .resourceGroupName("Default-RecoveryServices-ResourceGroup")
            .sku(SkuArgs.builder()
                .name("Standard")
                .build())
            .vaultName("swaggerExample")
            .build());

    }
}
resources:
  vault:
    type: azure-native:recoveryservices:Vault
    properties:
      identity:
        type: SystemAssigned
      location: West US
      properties:
        publicNetworkAccess: Enabled
      resourceGroupName: Default-RecoveryServices-ResourceGroup
      sku:
        name: Standard
      vaultName: swaggerExample

The identity property with type SystemAssigned tells Azure to create and manage an identity for this vault automatically. The sku property sets the pricing tier (Standard is the default). The publicNetworkAccess property controls whether the vault accepts connections from public networks; set to Enabled here, it can be changed to Disabled for private endpoint scenarios.

Configure alert routing for backup and replication events

Organizations often need to control which failure types trigger alerts and whether notifications use Azure Monitor or classic email-based alerting.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const vault = new azure_native.recoveryservices.Vault("vault", {
    identity: {
        type: azure_native.recoveryservices.ResourceIdentityType.SystemAssigned,
    },
    location: "West US",
    properties: {
        monitoringSettings: {
            azureMonitorAlertSettings: {
                alertsForAllFailoverIssues: azure_native.recoveryservices.AlertsState.Disabled,
                alertsForAllJobFailures: azure_native.recoveryservices.AlertsState.Enabled,
                alertsForAllReplicationIssues: azure_native.recoveryservices.AlertsState.Enabled,
            },
            classicAlertSettings: {
                alertsForCriticalOperations: azure_native.recoveryservices.AlertsState.Disabled,
                emailNotificationsForSiteRecovery: azure_native.recoveryservices.AlertsState.Enabled,
            },
        },
        publicNetworkAccess: azure_native.recoveryservices.PublicNetworkAccess.Enabled,
    },
    resourceGroupName: "Default-RecoveryServices-ResourceGroup",
    sku: {
        name: azure_native.recoveryservices.SkuName.Standard,
    },
    vaultName: "swaggerExample",
});
import pulumi
import pulumi_azure_native as azure_native

vault = azure_native.recoveryservices.Vault("vault",
    identity={
        "type": azure_native.recoveryservices.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    location="West US",
    properties={
        "monitoring_settings": {
            "azure_monitor_alert_settings": {
                "alerts_for_all_failover_issues": azure_native.recoveryservices.AlertsState.DISABLED,
                "alerts_for_all_job_failures": azure_native.recoveryservices.AlertsState.ENABLED,
                "alerts_for_all_replication_issues": azure_native.recoveryservices.AlertsState.ENABLED,
            },
            "classic_alert_settings": {
                "alerts_for_critical_operations": azure_native.recoveryservices.AlertsState.DISABLED,
                "email_notifications_for_site_recovery": azure_native.recoveryservices.AlertsState.ENABLED,
            },
        },
        "public_network_access": azure_native.recoveryservices.PublicNetworkAccess.ENABLED,
    },
    resource_group_name="Default-RecoveryServices-ResourceGroup",
    sku={
        "name": azure_native.recoveryservices.SkuName.STANDARD,
    },
    vault_name="swaggerExample")
package main

import (
	recoveryservices "github.com/pulumi/pulumi-azure-native-sdk/recoveryservices/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := recoveryservices.NewVault(ctx, "vault", &recoveryservices.VaultArgs{
			Identity: &recoveryservices.IdentityDataArgs{
				Type: pulumi.String(recoveryservices.ResourceIdentityTypeSystemAssigned),
			},
			Location: pulumi.String("West US"),
			Properties: &recoveryservices.VaultPropertiesArgs{
				MonitoringSettings: &recoveryservices.MonitoringSettingsArgs{
					AzureMonitorAlertSettings: &recoveryservices.AzureMonitorAlertSettingsArgs{
						AlertsForAllFailoverIssues:    pulumi.String(recoveryservices.AlertsStateDisabled),
						AlertsForAllJobFailures:       pulumi.String(recoveryservices.AlertsStateEnabled),
						AlertsForAllReplicationIssues: pulumi.String(recoveryservices.AlertsStateEnabled),
					},
					ClassicAlertSettings: &recoveryservices.ClassicAlertSettingsArgs{
						AlertsForCriticalOperations:       pulumi.String(recoveryservices.AlertsStateDisabled),
						EmailNotificationsForSiteRecovery: pulumi.String(recoveryservices.AlertsStateEnabled),
					},
				},
				PublicNetworkAccess: pulumi.String(recoveryservices.PublicNetworkAccessEnabled),
			},
			ResourceGroupName: pulumi.String("Default-RecoveryServices-ResourceGroup"),
			Sku: &recoveryservices.SkuArgs{
				Name: pulumi.String(recoveryservices.SkuNameStandard),
			},
			VaultName: pulumi.String("swaggerExample"),
		})
		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 vault = new AzureNative.RecoveryServices.Vault("vault", new()
    {
        Identity = new AzureNative.RecoveryServices.Inputs.IdentityDataArgs
        {
            Type = AzureNative.RecoveryServices.ResourceIdentityType.SystemAssigned,
        },
        Location = "West US",
        Properties = new AzureNative.RecoveryServices.Inputs.VaultPropertiesArgs
        {
            MonitoringSettings = new AzureNative.RecoveryServices.Inputs.MonitoringSettingsArgs
            {
                AzureMonitorAlertSettings = new AzureNative.RecoveryServices.Inputs.AzureMonitorAlertSettingsArgs
                {
                    AlertsForAllFailoverIssues = AzureNative.RecoveryServices.AlertsState.Disabled,
                    AlertsForAllJobFailures = AzureNative.RecoveryServices.AlertsState.Enabled,
                    AlertsForAllReplicationIssues = AzureNative.RecoveryServices.AlertsState.Enabled,
                },
                ClassicAlertSettings = new AzureNative.RecoveryServices.Inputs.ClassicAlertSettingsArgs
                {
                    AlertsForCriticalOperations = AzureNative.RecoveryServices.AlertsState.Disabled,
                    EmailNotificationsForSiteRecovery = AzureNative.RecoveryServices.AlertsState.Enabled,
                },
            },
            PublicNetworkAccess = AzureNative.RecoveryServices.PublicNetworkAccess.Enabled,
        },
        ResourceGroupName = "Default-RecoveryServices-ResourceGroup",
        Sku = new AzureNative.RecoveryServices.Inputs.SkuArgs
        {
            Name = AzureNative.RecoveryServices.SkuName.Standard,
        },
        VaultName = "swaggerExample",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.recoveryservices.Vault;
import com.pulumi.azurenative.recoveryservices.VaultArgs;
import com.pulumi.azurenative.recoveryservices.inputs.IdentityDataArgs;
import com.pulumi.azurenative.recoveryservices.inputs.VaultPropertiesArgs;
import com.pulumi.azurenative.recoveryservices.inputs.MonitoringSettingsArgs;
import com.pulumi.azurenative.recoveryservices.inputs.AzureMonitorAlertSettingsArgs;
import com.pulumi.azurenative.recoveryservices.inputs.ClassicAlertSettingsArgs;
import com.pulumi.azurenative.recoveryservices.inputs.SkuArgs;
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 vault = new Vault("vault", VaultArgs.builder()
            .identity(IdentityDataArgs.builder()
                .type("SystemAssigned")
                .build())
            .location("West US")
            .properties(VaultPropertiesArgs.builder()
                .monitoringSettings(MonitoringSettingsArgs.builder()
                    .azureMonitorAlertSettings(AzureMonitorAlertSettingsArgs.builder()
                        .alertsForAllFailoverIssues("Disabled")
                        .alertsForAllJobFailures("Enabled")
                        .alertsForAllReplicationIssues("Enabled")
                        .build())
                    .classicAlertSettings(ClassicAlertSettingsArgs.builder()
                        .alertsForCriticalOperations("Disabled")
                        .emailNotificationsForSiteRecovery("Enabled")
                        .build())
                    .build())
                .publicNetworkAccess("Enabled")
                .build())
            .resourceGroupName("Default-RecoveryServices-ResourceGroup")
            .sku(SkuArgs.builder()
                .name("Standard")
                .build())
            .vaultName("swaggerExample")
            .build());

    }
}
resources:
  vault:
    type: azure-native:recoveryservices:Vault
    properties:
      identity:
        type: SystemAssigned
      location: West US
      properties:
        monitoringSettings:
          azureMonitorAlertSettings:
            alertsForAllFailoverIssues: Disabled
            alertsForAllJobFailures: Enabled
            alertsForAllReplicationIssues: Enabled
          classicAlertSettings:
            alertsForCriticalOperations: Disabled
            emailNotificationsForSiteRecovery: Enabled
        publicNetworkAccess: Enabled
      resourceGroupName: Default-RecoveryServices-ResourceGroup
      sku:
        name: Standard
      vaultName: swaggerExample

The monitoringSettings property contains two alert configuration blocks. The azureMonitorAlertSettings block routes job failures and replication issues to Azure Monitor while disabling failover alerts. The classicAlertSettings block disables legacy email notifications for critical operations while enabling Site Recovery emails. Each alert type can be independently enabled or disabled.

Enable geo-redundant storage with cross-region restore

Disaster recovery strategies often require backup data to be replicated across Azure regions, with the ability to restore from a secondary region if the primary becomes unavailable.

import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";

const vault = new azure_native.recoveryservices.Vault("vault", {
    identity: {
        type: azure_native.recoveryservices.ResourceIdentityType.SystemAssigned,
    },
    location: "West US",
    properties: {
        publicNetworkAccess: azure_native.recoveryservices.PublicNetworkAccess.Enabled,
        redundancySettings: {
            crossRegionRestore: azure_native.recoveryservices.CrossRegionRestore.Enabled,
            standardTierStorageRedundancy: azure_native.recoveryservices.StandardTierStorageRedundancy.GeoRedundant,
        },
    },
    resourceGroupName: "Default-RecoveryServices-ResourceGroup",
    sku: {
        name: azure_native.recoveryservices.SkuName.Standard,
    },
    vaultName: "swaggerExample",
});
import pulumi
import pulumi_azure_native as azure_native

vault = azure_native.recoveryservices.Vault("vault",
    identity={
        "type": azure_native.recoveryservices.ResourceIdentityType.SYSTEM_ASSIGNED,
    },
    location="West US",
    properties={
        "public_network_access": azure_native.recoveryservices.PublicNetworkAccess.ENABLED,
        "redundancy_settings": {
            "cross_region_restore": azure_native.recoveryservices.CrossRegionRestore.ENABLED,
            "standard_tier_storage_redundancy": azure_native.recoveryservices.StandardTierStorageRedundancy.GEO_REDUNDANT,
        },
    },
    resource_group_name="Default-RecoveryServices-ResourceGroup",
    sku={
        "name": azure_native.recoveryservices.SkuName.STANDARD,
    },
    vault_name="swaggerExample")
package main

import (
	recoveryservices "github.com/pulumi/pulumi-azure-native-sdk/recoveryservices/v3"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := recoveryservices.NewVault(ctx, "vault", &recoveryservices.VaultArgs{
			Identity: &recoveryservices.IdentityDataArgs{
				Type: pulumi.String(recoveryservices.ResourceIdentityTypeSystemAssigned),
			},
			Location: pulumi.String("West US"),
			Properties: &recoveryservices.VaultPropertiesArgs{
				PublicNetworkAccess: pulumi.String(recoveryservices.PublicNetworkAccessEnabled),
				RedundancySettings: &recoveryservices.VaultPropertiesRedundancySettingsArgs{
					CrossRegionRestore:            pulumi.String(recoveryservices.CrossRegionRestoreEnabled),
					StandardTierStorageRedundancy: pulumi.String(recoveryservices.StandardTierStorageRedundancyGeoRedundant),
				},
			},
			ResourceGroupName: pulumi.String("Default-RecoveryServices-ResourceGroup"),
			Sku: &recoveryservices.SkuArgs{
				Name: pulumi.String(recoveryservices.SkuNameStandard),
			},
			VaultName: pulumi.String("swaggerExample"),
		})
		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 vault = new AzureNative.RecoveryServices.Vault("vault", new()
    {
        Identity = new AzureNative.RecoveryServices.Inputs.IdentityDataArgs
        {
            Type = AzureNative.RecoveryServices.ResourceIdentityType.SystemAssigned,
        },
        Location = "West US",
        Properties = new AzureNative.RecoveryServices.Inputs.VaultPropertiesArgs
        {
            PublicNetworkAccess = AzureNative.RecoveryServices.PublicNetworkAccess.Enabled,
            RedundancySettings = new AzureNative.RecoveryServices.Inputs.VaultPropertiesRedundancySettingsArgs
            {
                CrossRegionRestore = AzureNative.RecoveryServices.CrossRegionRestore.Enabled,
                StandardTierStorageRedundancy = AzureNative.RecoveryServices.StandardTierStorageRedundancy.GeoRedundant,
            },
        },
        ResourceGroupName = "Default-RecoveryServices-ResourceGroup",
        Sku = new AzureNative.RecoveryServices.Inputs.SkuArgs
        {
            Name = AzureNative.RecoveryServices.SkuName.Standard,
        },
        VaultName = "swaggerExample",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.recoveryservices.Vault;
import com.pulumi.azurenative.recoveryservices.VaultArgs;
import com.pulumi.azurenative.recoveryservices.inputs.IdentityDataArgs;
import com.pulumi.azurenative.recoveryservices.inputs.VaultPropertiesArgs;
import com.pulumi.azurenative.recoveryservices.inputs.VaultPropertiesRedundancySettingsArgs;
import com.pulumi.azurenative.recoveryservices.inputs.SkuArgs;
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 vault = new Vault("vault", VaultArgs.builder()
            .identity(IdentityDataArgs.builder()
                .type("SystemAssigned")
                .build())
            .location("West US")
            .properties(VaultPropertiesArgs.builder()
                .publicNetworkAccess("Enabled")
                .redundancySettings(VaultPropertiesRedundancySettingsArgs.builder()
                    .crossRegionRestore("Enabled")
                    .standardTierStorageRedundancy("GeoRedundant")
                    .build())
                .build())
            .resourceGroupName("Default-RecoveryServices-ResourceGroup")
            .sku(SkuArgs.builder()
                .name("Standard")
                .build())
            .vaultName("swaggerExample")
            .build());

    }
}
resources:
  vault:
    type: azure-native:recoveryservices:Vault
    properties:
      identity:
        type: SystemAssigned
      location: West US
      properties:
        publicNetworkAccess: Enabled
        redundancySettings:
          crossRegionRestore: Enabled
          standardTierStorageRedundancy: GeoRedundant
      resourceGroupName: Default-RecoveryServices-ResourceGroup
      sku:
        name: Standard
      vaultName: swaggerExample

The redundancySettings property controls how backup data is stored and replicated. Setting standardTierStorageRedundancy to GeoRedundant replicates data to a paired Azure region. The crossRegionRestore property, when Enabled, allows you to restore from the secondary region without waiting for a regional failover.

Beyond these examples

These snippets focus on specific vault-level features: managed identity configuration, alert routing and monitoring, and storage redundancy and cross-region restore. They’re intentionally minimal rather than full backup solutions.

The examples may reference pre-existing infrastructure such as Azure resource groups. They focus on configuring the vault rather than provisioning backup policies or protected items.

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

  • Resource tagging for organization and cost tracking
  • Private endpoint configuration (publicNetworkAccess set to Disabled)
  • User-assigned managed identities
  • Encryption settings and customer-managed keys

These omissions are intentional: the goal is to illustrate how each vault feature is wired, not provide drop-in backup modules. See the Recovery Services Vault resource reference for all available configuration options.

Let's create Azure Recovery Services Vaults

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Configuration & Immutability
What properties can't I change after creating a Recovery Services Vault?
The resourceGroupName and vaultName properties are immutable and cannot be changed after vault creation. Changing these requires recreating the vault.
API Versions & Compatibility
What API version does the Azure Native provider use for Recovery Services Vaults?
Version 2.x of the Azure Native provider uses API version 2024-10-01. Version 1.x used API version 2023-04-01.
How do I use a different API version for my Recovery Services Vault?
Generate a local SDK package using pulumi package add azure-native recoveryservices [ApiVersion]. Available versions include 2023-02-01, 2023-04-01, 2023-06-01, 2023-08-01, 2024-01-01, 2024-02-01, 2024-04-01, and others.
Identity & Security
What identity type should I configure for a Recovery Services Vault?
The examples demonstrate using SystemAssigned identity type, configured via the identity.type property.
Monitoring & Alerts
What's the difference between Azure Monitor alerts and Classic alerts?
Configure both via properties.monitoringSettings. Azure Monitor alerts (azureMonitorAlertSettings) cover failover issues, job failures, and replication issues. Classic alerts (classicAlertSettings) handle critical operations and site recovery email notifications.
Storage & Redundancy
How do I enable cross-region restore for my vault?
Set properties.redundancySettings.crossRegionRestore to Enabled and configure standardTierStorageRedundancy to GeoRedundant.

Using a different cloud?

Explore storage guides for other cloud providers: