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_ZRSwhere 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
completionPercentreaches 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
nouuidfor 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.