πŸš€ Azure VM Replication: No More Local Downloads! (feat. Azure CLI)

Hello! When working with cloud environments, there are many times when you need to back up a Virtual Machine (VM) or replicate a VM exactly as it is at a specific point in time to create a test environment.

The common method many people use probably goes like this:

  1. Create a snapshot of the VM disk. πŸ“Έ
  2. Download the snapshot as a VHD file to your local computer. (⏳ Takes forever…)
  3. Upload the downloaded VHD file back to Blob storage. (😩 Takes forever again…)
  4. Create a new disk from the uploaded VHD, and then create a new VM from that disk.

Doesn’t this process seem a bit odd? You’re just moving data from one place in Azure to another, so why does it have to go through your computer? This method is time-consuming, wastes your computer’s network bandwidth and storage space, and has a higher chance of errors occurring in between.

So today! I will show you a very smart way to completely skip this inefficient process and replicate a VM by directly copying a snapshot to a Blob within Azure, along with an Azure CLI script.

πŸ€” Core Principle: Local Transit vs. Direct Azure

If the old method is like taking a plane from Seoul to Busan but detouring via Jeju Island (my computer), the method I’m introducing today is like taking the KTX directly. πŸš…

The core is the Azure CLI command `az storage blob copy start`. This command instructs Azure: “Azure, please copy the data yourself from location A (snapshot) to location B (Blob storage)!” The data moves directly through Azure’s fast and stable internal network, without ever touching our computer.

This is called Server-Side Copy, and it offers tremendous advantages:

  • ⚑️ Speed: Incomparably faster than local network speeds.
  • πŸ‘ Efficiency: Uses none of your computer’s resources (CPU, network, disk).
  • πŸ”’ Stability: Reliably copies large files without worrying about internet disconnections.

πŸ“œ Full Script Revealed!

Seeing is believing, right? Below is the complete Bash script that automates this entire process. Feel free to copy and use it.

#!/bin/bash

# --- User-configurable variables ---
# Please accurately enter the name of the already created resource.
resourceGroup="gasbugs_group"      # Resource Group
vmName="gasbugs"                   # Original Virtual Machine
storageAccount="storageaccountgasbugs0" # Storage account to save VHD
containerName="blob-test"          # Container to save VHD

# Set the name of the new resource as desired.
snapshotName="new-snapshot-$(date +%s)" # Snapshot name (timestamp added to prevent duplication)
newDiskName="new-disk-$(date +%s)"      # New Disk Name
newVmName="new-vm-$(date +%s)"          # New Virtual Machine Name

# --- Script execution ---
echo ">> 1. 원본 VM의 OS λ””μŠ€ν¬ IDλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€..."
osDiskId=$(az vm show --resource-group $resourceGroup --name $vmName --query "storageProfile.osDisk.managedDisk.id" -o tsv)
if [ -z "$osDiskId" ]; then echo "였λ₯˜: OS λ””μŠ€ν¬ IDλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€."; exit 1; fi
echo "   - OS Disk ID: $osDiskId"

echo -e "
>> 2. OS λ””μŠ€ν¬μ˜ μŠ€λƒ…μƒ·μ„ μƒμ„±ν•©λ‹ˆλ‹€..."
az snapshot create --resource-group $resourceGroup --name $snapshotName --source $osDiskId
echo "   - μƒμ„±λœ μŠ€λƒ…μƒ·: $snapshotName"

echo -e "
>> 3. μŠ€λƒ…μƒ·μ— μ ‘κ·Όν•  수 μžˆλŠ” μž„μ‹œ SAS URL을 μƒμ„±ν•©λ‹ˆλ‹€..."
snapshotUrl=$(az snapshot grant-access --duration-in-seconds 3600 --name $snapshotName --resource-group $resourceGroup --query "accessSas" -o tsv)
echo "   - SAS URL이 μ„±κ³΅μ μœΌλ‘œ μƒμ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€."

echo -e "
>> 4. μŠ€λƒ…μƒ·μ„ Blob Storage둜 μ„œλ²„ μΈ‘ 볡사λ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€ (둜컬 λ‹€μš΄λ‘œλ“œ μ—†μŒ)..."
# Full URL of the Blob to copy
sharedVhdUrl="https://$storageAccount.blob.core.windows.net/$containerName/$snapshotName.vhd"

az storage blob copy start 
    --account-name $storageAccount 
    --destination-blob "$snapshotName.vhd" 
    --destination-container $containerName 
    --source-uri $snapshotUrl

# Check status until copy is complete.
while true; do
    copy_status=$(az storage blob show --account-name $storageAccount --container-name $containerName --name "$snapshotName.vhd" --query "properties.copy.status" -o tsv)
    echo "   - 볡사 μƒνƒœ: $copy_status"
    if [ "$copy_status" == "success" ]; then
        echo "   - Blob 볡사가 μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€."
        break
    elif [ "$copy_status" == "failed" ]; then
        echo "였λ₯˜: Blob 볡사에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€."
        exit 1
    fi
    sleep 15
done

echo -e "
>> 5. μŠ€λƒ…μƒ·μ˜ SAS URL μ ‘κ·Ό κΆŒν•œμ„ ν•΄μ œν•©λ‹ˆλ‹€..."
az snapshot revoke-access --name $snapshotName --resource-group $resourceGroup

echo -e "
>> 6. λ³΅μ‚¬λœ VHD Blob을 μ†ŒμŠ€λ‘œ ν•˜μ—¬ μƒˆ 관리 λ””μŠ€ν¬λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€..."
az disk create --resource-group $resourceGroup --name $newDiskName --source $sharedVhdUrl
echo "   - μƒμ„±λœ λ””μŠ€ν¬: $newDiskName"

echo -e "
>> 7. μƒμ„±λœ λ””μŠ€ν¬λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒˆ 가상 머신을 μƒμ„±ν•©λ‹ˆλ‹€..."
az vm create --resource-group $resourceGroup --name $newVmName --attach-os-disk $newDiskName --os-type Linux --public-ip-address "" # Create without Public IP
echo "   - μƒμ„±λœ VM: $newVmName"

echo -e "
βœ… λͺ¨λ“  μž‘μ—…μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€."

###

πŸ”¬ Detailed Script Analysis

Let’s take a closer look at how the script works, step by step.

Step 1: Variable Configuration βš™οΈ

At the top of the script, you configure basic information such as the target VM to replicate, resource group, and storage account to save the VHD. To prevent name conflicts when running the script multiple times, `$(date +%s)` is appended to the new resource names to create unique names based on the current time.

Step 2: Snapshot Creation πŸ“Έ

After getting the OS disk ID of the source VM with `az vm show`, a point-in-time copy of the disk, i.e., a snapshot, is created using the `az snapshot create` command.

Step 3: SAS URL Generation πŸ”‘

`az snapshot grant-access` plays a crucial role. It creates a URL containing a temporary secret key that allows access to the created snapshot data for exactly 1 hour (3600 seconds), which is a SAS (Shared Access Signature) URL. This URL becomes our data’s ‘direct ticket’.

Step 4: Server-Side Copy and Status Check ☁️➑️☁️

This is the highlight of the script! The `az storage blob copy start` command is given the newly created SAS URL as `–source-uri` and the target Blob information as `–destination-blob`, etc.

As soon as the command is executed, Azure starts copying in the background. But we need to wait until the copy is finished to proceed with the next tasks, right? So, a `while` loop is used to check the copy status every 15 seconds with the `az storage blob show` command. When the status changes to ‘success’, the loop is exited, and the script moves to the next step. Pretty smart, isn’t it?

Steps 5-7: Revoke Access and Resource Creation πŸ—οΈ

Once the copy is complete, for security, the SAS URL is immediately revoked using `az snapshot revoke-access`. Now, using the URL of the VHD file safely stored in Blob storage as the source, `az disk create` is executed to create a new managed disk. Finally, using this disk as the OS disk, `az vm create` is used to create the final replicated VM, completing the entire process!

✨ Concluding Remarks

No more wasting time downloading and uploading VHD files locally every time you replicate or back up a VM. By utilizing the server-side copy method learned today, you can automate the entire process quickly and reliably with just one Azure CLI script execution.

How about using this script to create your own VM backup system or to quickly set up development/test environments?


Tags: Azure, VM, Virtual Machine, Snapshot, Blob, Storage, Azure CLI, Bash, Script, DevOps, IaC, Cloud, IT


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *