The azure-native:compute:Snapshot resource, part of the Pulumi Azure Native provider, defines Azure managed disk snapshots: point-in-time copies of disks or VHD blobs that can be replicated across regions and subscriptions. This guide focuses on four capabilities: VHD blob import, snapshot-to-snapshot copying, cross-region replication with bandwidth controls, and Elastic SAN integration.
Snapshots reference source data that must exist before creation: VHD blobs in Azure Storage, existing snapshots, or Elastic SAN volume snapshots. The examples are intentionally small. Combine them with your own storage accounts, encryption settings, and network policies.
Import an unmanaged VHD blob into a snapshot
Teams migrating from unmanaged disks often capture VHD blobs stored in Azure Storage as managed snapshots for backup or replication.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const snapshot = new azure_native.compute.Snapshot("snapshot", {
creationData: {
createOption: azure_native.compute.DiskCreateOption.Import,
sourceUri: "https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd",
},
location: "West US",
resourceGroupName: "myResourceGroup",
snapshotName: "mySnapshot1",
});
import pulumi
import pulumi_azure_native as azure_native
snapshot = azure_native.compute.Snapshot("snapshot",
creation_data={
"create_option": azure_native.compute.DiskCreateOption.IMPORT_,
"source_uri": "https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd",
},
location="West US",
resource_group_name="myResourceGroup",
snapshot_name="mySnapshot1")
package main
import (
compute "github.com/pulumi/pulumi-azure-native-sdk/compute/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewSnapshot(ctx, "snapshot", &compute.SnapshotArgs{
CreationData: &compute.CreationDataArgs{
CreateOption: pulumi.String(compute.DiskCreateOptionImport),
SourceUri: pulumi.String("https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd"),
},
Location: pulumi.String("West US"),
ResourceGroupName: pulumi.String("myResourceGroup"),
SnapshotName: pulumi.String("mySnapshot1"),
})
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 snapshot = new AzureNative.Compute.Snapshot("snapshot", new()
{
CreationData = new AzureNative.Compute.Inputs.CreationDataArgs
{
CreateOption = AzureNative.Compute.DiskCreateOption.Import,
SourceUri = "https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd",
},
Location = "West US",
ResourceGroupName = "myResourceGroup",
SnapshotName = "mySnapshot1",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.compute.Snapshot;
import com.pulumi.azurenative.compute.SnapshotArgs;
import com.pulumi.azurenative.compute.inputs.CreationDataArgs;
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 snapshot = new Snapshot("snapshot", SnapshotArgs.builder()
.creationData(CreationDataArgs.builder()
.createOption("Import")
.sourceUri("https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd")
.build())
.location("West US")
.resourceGroupName("myResourceGroup")
.snapshotName("mySnapshot1")
.build());
}
}
resources:
snapshot:
type: azure-native:compute:Snapshot
properties:
creationData:
createOption: Import
sourceUri: https://mystorageaccount.blob.core.windows.net/osimages/osimage.vhd
location: West US
resourceGroupName: myResourceGroup
snapshotName: mySnapshot1
The creationData block controls how the snapshot is created. Setting createOption to Import tells Azure to read the VHD blob from the sourceUri and convert it into a managed snapshot. When the storage account is in the same subscription, you don’t need to specify storageAccountId.
Copy a snapshot within or across subscriptions
Disaster recovery and multi-region deployments require copying snapshots to different regions or subscriptions for redundancy.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const snapshot = new azure_native.compute.Snapshot("snapshot", {
creationData: {
createOption: azure_native.compute.DiskCreateOption.Copy,
sourceResourceId: "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
location: "West US",
resourceGroupName: "myResourceGroup",
snapshotName: "mySnapshot2",
});
import pulumi
import pulumi_azure_native as azure_native
snapshot = azure_native.compute.Snapshot("snapshot",
creation_data={
"create_option": azure_native.compute.DiskCreateOption.COPY,
"source_resource_id": "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
location="West US",
resource_group_name="myResourceGroup",
snapshot_name="mySnapshot2")
package main
import (
compute "github.com/pulumi/pulumi-azure-native-sdk/compute/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewSnapshot(ctx, "snapshot", &compute.SnapshotArgs{
CreationData: &compute.CreationDataArgs{
CreateOption: pulumi.String(compute.DiskCreateOptionCopy),
SourceResourceId: pulumi.String("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1"),
},
Location: pulumi.String("West US"),
ResourceGroupName: pulumi.String("myResourceGroup"),
SnapshotName: pulumi.String("mySnapshot2"),
})
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 snapshot = new AzureNative.Compute.Snapshot("snapshot", new()
{
CreationData = new AzureNative.Compute.Inputs.CreationDataArgs
{
CreateOption = AzureNative.Compute.DiskCreateOption.Copy,
SourceResourceId = "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
Location = "West US",
ResourceGroupName = "myResourceGroup",
SnapshotName = "mySnapshot2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.compute.Snapshot;
import com.pulumi.azurenative.compute.SnapshotArgs;
import com.pulumi.azurenative.compute.inputs.CreationDataArgs;
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 snapshot = new Snapshot("snapshot", SnapshotArgs.builder()
.creationData(CreationDataArgs.builder()
.createOption("Copy")
.sourceResourceId("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1")
.build())
.location("West US")
.resourceGroupName("myResourceGroup")
.snapshotName("mySnapshot2")
.build());
}
}
resources:
snapshot:
type: azure-native:compute:Snapshot
properties:
creationData:
createOption: Copy
sourceResourceId: subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1
location: West US
resourceGroupName: myResourceGroup
snapshotName: mySnapshot2
Setting createOption to Copy initiates a full snapshot replication. The sourceResourceId points to the snapshot you’re copying from, which can be in the same subscription or a different one. Azure handles the data transfer and creates an independent snapshot in the target region.
Copy a snapshot with enhanced bandwidth
Large snapshots can take hours to copy across regions. Enhanced bandwidth provisioning accelerates the copy operation for time-sensitive migrations.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const snapshot = new azure_native.compute.Snapshot("snapshot", {
creationData: {
createOption: azure_native.compute.DiskCreateOption.CopyStart,
provisionedBandwidthCopySpeed: azure_native.compute.ProvisionedBandwidthCopyOption.Enhanced,
sourceResourceId: "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
location: "West US",
resourceGroupName: "myResourceGroup",
snapshotName: "mySnapshot2",
});
import pulumi
import pulumi_azure_native as azure_native
snapshot = azure_native.compute.Snapshot("snapshot",
creation_data={
"create_option": azure_native.compute.DiskCreateOption.COPY_START,
"provisioned_bandwidth_copy_speed": azure_native.compute.ProvisionedBandwidthCopyOption.ENHANCED,
"source_resource_id": "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
location="West US",
resource_group_name="myResourceGroup",
snapshot_name="mySnapshot2")
package main
import (
compute "github.com/pulumi/pulumi-azure-native-sdk/compute/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewSnapshot(ctx, "snapshot", &compute.SnapshotArgs{
CreationData: &compute.CreationDataArgs{
CreateOption: pulumi.String(compute.DiskCreateOptionCopyStart),
ProvisionedBandwidthCopySpeed: pulumi.String(compute.ProvisionedBandwidthCopyOptionEnhanced),
SourceResourceId: pulumi.String("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1"),
},
Location: pulumi.String("West US"),
ResourceGroupName: pulumi.String("myResourceGroup"),
SnapshotName: pulumi.String("mySnapshot2"),
})
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 snapshot = new AzureNative.Compute.Snapshot("snapshot", new()
{
CreationData = new AzureNative.Compute.Inputs.CreationDataArgs
{
CreateOption = AzureNative.Compute.DiskCreateOption.CopyStart,
ProvisionedBandwidthCopySpeed = AzureNative.Compute.ProvisionedBandwidthCopyOption.Enhanced,
SourceResourceId = "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1",
},
Location = "West US",
ResourceGroupName = "myResourceGroup",
SnapshotName = "mySnapshot2",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.compute.Snapshot;
import com.pulumi.azurenative.compute.SnapshotArgs;
import com.pulumi.azurenative.compute.inputs.CreationDataArgs;
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 snapshot = new Snapshot("snapshot", SnapshotArgs.builder()
.creationData(CreationDataArgs.builder()
.createOption("CopyStart")
.provisionedBandwidthCopySpeed("Enhanced")
.sourceResourceId("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1")
.build())
.location("West US")
.resourceGroupName("myResourceGroup")
.snapshotName("mySnapshot2")
.build());
}
}
resources:
snapshot:
type: azure-native:compute:Snapshot
properties:
creationData:
createOption: CopyStart
provisionedBandwidthCopySpeed: Enhanced
sourceResourceId: subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.Compute/snapshots/mySnapshot1
location: West US
resourceGroupName: myResourceGroup
snapshotName: mySnapshot2
The CopyStart option works like Copy but allows you to specify provisionedBandwidthCopySpeed. Setting it to Enhanced allocates additional network bandwidth to speed up the transfer. This is useful for large snapshots where standard copy speeds would cause unacceptable delays.
Create a snapshot from Elastic SAN storage
Elastic SAN provides high-performance block storage for Azure workloads. Teams can capture Elastic SAN volume snapshots as managed disk snapshots for portability.
import * as pulumi from "@pulumi/pulumi";
import * as azure_native from "@pulumi/azure-native";
const snapshot = new azure_native.compute.Snapshot("snapshot", {
creationData: {
createOption: azure_native.compute.DiskCreateOption.CopyFromSanSnapshot,
elasticSanResourceId: "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot",
},
location: "West US",
resourceGroupName: "myResourceGroup",
snapshotName: "mySnapshot",
});
import pulumi
import pulumi_azure_native as azure_native
snapshot = azure_native.compute.Snapshot("snapshot",
creation_data={
"create_option": azure_native.compute.DiskCreateOption.COPY_FROM_SAN_SNAPSHOT,
"elastic_san_resource_id": "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot",
},
location="West US",
resource_group_name="myResourceGroup",
snapshot_name="mySnapshot")
package main
import (
compute "github.com/pulumi/pulumi-azure-native-sdk/compute/v3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewSnapshot(ctx, "snapshot", &compute.SnapshotArgs{
CreationData: &compute.CreationDataArgs{
CreateOption: pulumi.String(compute.DiskCreateOptionCopyFromSanSnapshot),
ElasticSanResourceId: pulumi.String("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot"),
},
Location: pulumi.String("West US"),
ResourceGroupName: pulumi.String("myResourceGroup"),
SnapshotName: pulumi.String("mySnapshot"),
})
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 snapshot = new AzureNative.Compute.Snapshot("snapshot", new()
{
CreationData = new AzureNative.Compute.Inputs.CreationDataArgs
{
CreateOption = AzureNative.Compute.DiskCreateOption.CopyFromSanSnapshot,
ElasticSanResourceId = "subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot",
},
Location = "West US",
ResourceGroupName = "myResourceGroup",
SnapshotName = "mySnapshot",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.azurenative.compute.Snapshot;
import com.pulumi.azurenative.compute.SnapshotArgs;
import com.pulumi.azurenative.compute.inputs.CreationDataArgs;
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 snapshot = new Snapshot("snapshot", SnapshotArgs.builder()
.creationData(CreationDataArgs.builder()
.createOption("CopyFromSanSnapshot")
.elasticSanResourceId("subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot")
.build())
.location("West US")
.resourceGroupName("myResourceGroup")
.snapshotName("mySnapshot")
.build());
}
}
resources:
snapshot:
type: azure-native:compute:Snapshot
properties:
creationData:
createOption: CopyFromSanSnapshot
elasticSanResourceId: subscriptions/{subscription-id}/resourceGroups/myResourceGroup/providers/Microsoft.ElasticSan/elasticSans/myElasticSan/volumegroups/myElasticSanVolumeGroup/snapshots/myElasticSanVolumeSnapshot
location: West US
resourceGroupName: myResourceGroup
snapshotName: mySnapshot
The CopyFromSanSnapshot option converts an Elastic SAN volume snapshot into a managed disk snapshot. The elasticSanResourceId points to the Elastic SAN snapshot resource. This enables you to move data from Elastic SAN into the managed disk ecosystem for broader compatibility.
Beyond these examples
These snippets focus on specific snapshot-level features: VHD blob import and snapshot-to-snapshot copying, cross-region replication with bandwidth controls, and Elastic SAN integration. They’re intentionally minimal rather than full backup solutions.
The examples reference pre-existing infrastructure such as Azure Storage accounts with VHD blobs, and source snapshots or Elastic SAN volume snapshots. They focus on configuring the snapshot rather than provisioning everything around it.
To keep things focused, common snapshot patterns are omitted, including:
- Incremental snapshots (incremental property)
- Encryption with customer-managed keys (encryption, encryptionSettingsCollection)
- Network access policies and private endpoints (networkAccessPolicy, diskAccessId)
- SKU selection for storage tier (sku property)
These omissions are intentional: the goal is to illustrate how each snapshot feature is wired, not provide drop-in backup modules. See the Snapshot resource reference for all available configuration options.
Let's create Azure Disk Snapshots
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Immutability & Constraints
creationData, location, snapshotName, or extendedLocation after the snapshot is created. Plan these values carefully during initial creation.Snapshot Creation & Sources
createOption: Import with sourceUri pointing to the blob. If importing from a different subscription, include storageAccountId with the full resource ID of the storage account. For same-subscription imports, storageAccountId is not needed.Copy to copy a snapshot within the same region or subscription. Use CopyStart to copy a snapshot across different regions or subscriptions.createOption: CopyFromSanSnapshot with elasticSanResourceId pointing to the Elastic SAN volume snapshot resource.Performance & Optimization
provisionedBandwidthCopySpeed to Enhanced when using createOption: CopyStart for faster copy operations across regions.Storage & SKU
Standard_LRS, Premium_LRS, or Standard_ZRS. For incremental snapshots, the default behavior is to use the same SKU as the previous snapshot.networkAccessPolicy to control network access and publicNetworkAccess to control export policies. For private endpoints, configure diskAccessId with the ARM ID of a DiskAccess resource.