Home / Azure

AzureHow-toIntermediate

Azure managed disk snapshots: take incremental snapshots, copy them to another region and restore a disk

Take incremental snapshots before risky changes, copy them to another region with --copy-start, and build a disk or swap a VM's OS disk from a snapshot.

Deepak Bhardwaj8 min read

Applies toAzure Managed Disks (Standard HDD/SSD, Premium SSD), Windows and Linux VMs, Azure CLI 2.x

You are about to patch a VM, upgrade an application or run a schema change, and you want a fast way back if it goes wrong. Or you need a copy of a disk in another region for a test or a quick DR seed. A managed disk snapshot covers both. This guide shows the commands for each step: take the snapshot, check that it's usable, copy it to another region, then restore from it.

Warning

A snapshot is crash-consistent, the same as pulling the power cord. It is not a backup policy, and taking one snapshot per disk doesn't give you consistency across several data disks. For databases or anything spread over multiple disks, stop the app or flush to disk first, or use Azure Backup.

Full vs incremental snapshots

Full snapshot Incremental snapshot
What is stored The whole disk, every time Only the blocks changed since the previous snapshot of the same disk
Cost You pay for the full provisioned size, every time You pay for the changed data
Copy to another region No Yes, with --copy-start
Use for Old scripts, one-off copies Almost everything

Use incremental snapshots unless you have a specific reason not to. Check the current pricing page for exact rates.

1. Take an incremental snapshot

Find the disk IDs first. Here they come from the VM:

RG=rg-app-prod
VM=vm-app-01

OS_DISK_ID=$(az vm show -g $RG -n $VM --query "storageProfile.osDisk.managedDisk.id" -o tsv)
az vm show -g $RG -n $VM --query "storageProfile.dataDisks[].{lun:lun, name:name, id:managedDisk.id}" -o table

Take the snapshot and add tags, so you know later why it exists and when it can go:

az snapshot create -g $RG -n snap-${VM}-os-$(date +%Y%m%d-%H%M) \
  --source "$OS_DISK_ID" \
  --incremental true \
  --tags reason=pre-patch change=CHG0012345 deleteAfter=2026-11-16

To snapshot every disk on the VM in one go:

for ID in $(az vm show -g $RG -n $VM \
  --query "[storageProfile.osDisk.managedDisk.id, storageProfile.dataDisks[].managedDisk.id][]" -o tsv); do
  NAME=$(basename "$ID")
  az snapshot create -g $RG -n "snap-${NAME}-$(date +%Y%m%d-%H%M)" \
    --source "$ID" --incremental true --tags reason=pre-patch
done

Tip

If the disks are in a zone, the snapshot doesn't have to be. Snapshots are regional resources. Use --sku Standard_ZRS where the region supports it, so the snapshot survives a zone failure.

Check that the snapshot is ready

The resource is created almost straight away, but its data is copied in the background. Wait for completionPercent to reach 100 before you depend on it:

az snapshot show -g $RG -n snap-vm-app-01-os-20261102-0900 \
  --query "{state:provisioningState, complete:completionPercent, incremental:incremental, sizeGb:diskSizeGb}" -o table

If completionPercent is empty on an older snapshot, the background copy finished long ago. The property is mainly useful right after you create a snapshot.

2. Copy the snapshot to another region

Only incremental snapshots can be copied across regions. Azure manages the copy for you, so you don't need a SAS URL or a staging storage account. Run the command in the target resource group and set the target location:

SRC_SNAP_ID=$(az snapshot show -g $RG -n snap-vm-app-01-os-20261102-0900 --query id -o tsv)

az snapshot create -g rg-app-dr -n snap-vm-app-01-os-20261102-0900-weu \
  -l westeurope \
  --source "$SRC_SNAP_ID" \
  --incremental true \
  --copy-start true

Then track progress on the target snapshot:

az snapshot show -g rg-app-dr -n snap-vm-app-01-os-20261102-0900-weu \
  --query "{state:provisioningState, complete:completionPercent}" -o table

Rules that will catch you out:

  • Copies of snapshots from the same disk run one at a time and in creation order. Start the next copy only after the previous one has finished.
  • Don't delete the source snapshot while a copy is still running.
  • You can't create a disk from the target snapshot until completionPercent reaches 100.
  • There are limits on concurrent copies per subscription and region. Check the current limits in the documentation before you script a fleet-wide copy.

3. Restore: create a new disk from a snapshot

This is the safe way to start. Build a new disk and leave the original alone:

SNAP_ID=$(az snapshot show -g $RG -n snap-vm-app-01-os-20261102-0900 --query id -o tsv)

az disk create -g $RG -n disk-${VM}-os-restored \
  --source "$SNAP_ID" \
  --sku Premium_LRS \
  --zone 1

If the VM is zonal, the new disk must be in the same zone as the VM. The new disk can also use a different SKU from the original.

Option A: attach it as a data disk to recover files

This is the best choice when you only need a config file or a folder back:

az vm disk attach -g $RG --vm-name vm-utility-01 --name disk-${VM}-os-restored

Mount it on the utility VM, copy the files out, then detach it with az vm disk detach and delete it.

Caution

Attaching a restored Linux disk to a VM that was built from the same image can cause duplicate filesystem UUIDs or LVM volume group names. Mount it by device path and with nouuid for XFS, and don't add it to /etc/fstab.

Option B: swap the VM's OS disk

Use this to roll the whole VM back. The VM keeps its NICs, IP addresses and extensions. Only the OS disk changes.

az vm deallocate -g $RG -n $VM

NEW_OS_ID=$(az disk show -g $RG -n disk-${VM}-os-restored --query id -o tsv)
az vm update -g $RG -n $VM --os-disk "$NEW_OS_ID"

az vm start -g $RG -n $VM

The old OS disk stays in the resource group, detached. Keep it until the rollback is confirmed, because it's your way forward again if the rollback was the wrong call.

Warning

Swapping the OS disk also rolls back anything written to it after the snapshot: logs, local queues, files uploaded to the OS drive. If the VM uses Azure Disk Encryption, check that the key in Key Vault still exists before you swap the disk.

4. Export a snapshot as a VHD (when you need the file)

To move a disk to another tenant or out of Azure, generate a time-limited read SAS URL:

SAS=$(az snapshot grant-access -g $RG -n snap-vm-app-01-os-20261102-0900 \
  --duration-in-seconds 3600 --query accessSas -o tsv)

azcopy copy "$SAS" "https://stexport01.blob.core.windows.net/vhds/vm-app-01-os.vhd"

az snapshot revoke-access -g $RG -n snap-vm-app-01-os-20261102-0900

Anyone who has the SAS URL can read the whole disk while it's valid. Keep the duration short, and revoke access once the copy has finished.

Common errors

Symptom Likely cause Fix
Disk create fails right after you take the snapshot Background copy not finished Wait for completionPercent to reach 100
--copy-start rejected Source is a full snapshot Take an incremental snapshot and copy that
Cross-region copy fails or stays queued Another copy from the same disk is still running Wait for it to finish, then copy in creation order
az vm update --os-disk fails VM not deallocated, or the disk is in a different zone Deallocate the VM; recreate the disk in the VM's zone
Restored Linux disk won't mount next to the original Duplicate UUID or VG name Mount with nouuid (XFS) or rename the VG
Snapshot can't be deleted SAS export still active az snapshot revoke-access, then delete

Prevent it next time

Snapshots pile up and cost money quietly. Tag every snapshot with a deleteAfter date and review them every week:

az snapshot list --query "[].{name:name, rg:resourceGroup, created:timeCreated, incremental:incremental, deleteAfter:tags.deleteAfter, gb:diskSizeGb}" -o table

The same list across every subscription, from Azure Resource Graph:

resources
| where type == "microsoft.compute/snapshots"
| extend created = todatetime(properties.timeCreated), deleteAfter = tostring(tags.deleteAfter)
| where created < ago(14d)
| project name, resourceGroup, subscriptionId, created, deleteAfter,
          incremental = tobool(properties.incremental), sizeGb = toint(properties.diskSizeGB)
| order by created asc
  • Make "take an incremental snapshot of every disk" a scripted step in your change template, not something people remember on the night.
  • For recurring protection with retention, use Azure Backup or Azure Disk Backup rather than cron jobs that call az snapshot create.
  • Practise the OS-disk swap on a non-production VM once, so the first time you run it isn't during an incident.