Azure – Clone a VM from a Snapshot

Posted by robd on September 09, 2022
Azure, powershell

Hello,

So something fun I’ve been working on recently is cloning a Linux Azure VM from a snapshot, for my case so I can test it for DR.

To do this you basically need to:

  1. Create a vnet for the clone if you need too (I reference it in the script)
  2. Create a snapshot of the VM
  3. Create a managed disk for the snapshot
  4. Create a VM with different name using the managed disk
  5. If needed rename the VM on the OS level to match the VM name.

Or you could use some PowerShell:

First open PowerShell and run:

Connect-AzAccount

The you need to change some of the below (look for “CHANGE THIS FOR YOUR ENVIRONMENT”):

#Existing virtual network where new virtual machine will be created, CHANGE THIS FOR YOUR ENVIRONMENT
$virtualNetworkName = 'uks-dr-test-vnet'  
  
#Resource group of the VM to be clonned from, CHANGE THIS FOR YOUR ENVIRONMENT
$oldresourceGroupName = 'UKS-VM1-DR'  
$newresourceGroupName = 'UKS-VM1-DR-TEST'  

#Region where managed disk will be created, CHANGE THIS FOR YOUR ENVIRONMENT
$location = 'UK South'  
  
#Names of source and target (new) VMs,CHANGE THIS FOR YOUR ENVIRONMENT
$sourceVirtualMachineName = 'Linux-VM1'  
$targetVirtualMachineName = 'Linux-VM1-DR'  

#Set the subscription for the current session where the commands wil execute,CHANGE THIS FOR YOUR ENVIRONMENT
Select-azSubscription -SubscriptionId '111111111-1111-1111-1111-111111111111'  
  
#Get the existing VM from which to clone from  
$sourceVirtualMachine = Get-AzVM -ResourceGroupName $oldresourceGroupName -Name $sourceVirtualMachineName  

$osdisk = Get-AzDisk -DiskName $($sourceVirtualMachine.StorageProfile.OsDisk.name) 
#Create new VM Disk Snapshot  
$snapshotconfig = New-AzSnapshotConfig -Sourceresourceid $osdisk.Id -Location $osdisk.Location -CreateOption copy  
$snapshot = New-AzSnapshot -Snapshot $snapshotconfig -SnapshotName "$($osdisk.name)-snapshot" -ResourceGroupName $oldresourceGroupName   

#Create a new OS Managed Disk from the Snapshot  
$disk = New-azDiskConfig -AccountType $osdisk.sku.Name -DiskSizeGB $($osdisk.DiskSizeGB) -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id  
$disk = New-azDisk -Disk $disk -ResourceGroupName $newresourceGroupName -DiskName "$($osdisk.name)-DR"
  
#Initialize virtual machine configuration  
$targetVirtualMachine = New-azVMConfig -VMName $targetVirtualMachineName -VMSize $($sourceVirtualMachine.HardwareProfile.VmSize)
  
#Attach Managed Disk to target virtual machine. OS type depends OS present in the disk (Windows/Linux)  
$targetVirtualMachine = Set-azVMOSDisk -VM $targetVirtualMachine -ManagedDiskId $disk.Id -CreateOption Attach -linux 

$disks = $sourceVirtualMachine.StorageProfile.DataDisks
#$disks = Get-AzDisk -ResourceGroupName $oldresourceGroupName | where {$_.managedby -like "*$sourceVirtualMachineName" -and $_.Name -like "*Datadisk*"} 
foreach ($disk in $disks){
    #Create new VM Disk Snapshot
    $datadisk = Get-AzDisk -DiskName $disk.name   
    $snapshotconfig = New-AzSnapshotConfig -SourceUri $($disk.manageddisk.id) -Location $datadisk.Location -CreateOption copy  
    $snapshot = New-AzSnapshot -Snapshot $snapshotconfig -SnapshotName "$($disk.name)_snapshot" -ResourceGroupName $oldresourceGroupName 

    #Create a new Managed Disk from the Snapshot  
    $diskconfig = New-azDiskConfig -SkuName $datadisk.sku.name -DiskSizeGB $($disk.DiskSizeGB) -Location $location -CreateOption Copy -SourceResourceId $snapshot.Id  
    $newdisk = New-azDisk -Disk $diskconfig -ResourceGroupName $newresourceGroupName -DiskName "$($datadisk.Name)-dr"   
    $targetVirtualMachine = add-AzVMDataDisk -VM $targetVirtualMachine -ManagedDiskId $newdisk.Id -lun $disk.lun -CreateOption attach 

} 

#Get Virtual Network information,CHANGE THIS FOR YOUR ENVIRONMENT
$vnet = Get-azVirtualNetwork -Name $virtualNetworkName
$subnetid = $($vnet.Subnets | where {$_.Name -like "DR_Sunet"}).id

# Create Network Interface for the VM, CHANGE THIS FOR YOUR ENVIRONMENT
$nic = New-azNetworkInterface -Name ($targetVirtualMachineName.ToLower() + '_nic') -ResourceGroupName $newresourceGroupName -Location $location -SubnetId $subnetid -PrivateIpAddress 172.45.1.252
$targetVirtualMachine = Add-azVMNetworkInterface -VM $targetVirtualMachine -Id $nic.Id  
  
#Create the virtual machine with Managed Disk attached  
New-azVM -VM $targetVirtualMachine -ResourceGroupName $newresourceGroupName -Location $location  
  
#Remove the snapshot  
Get-AzSnapshot -ResourceGroupName $oldresourceGroupName | Remove-AzSnapshot -Force

This chap does something similar too:

https://www.techmanyu.com/how-to-quickly-clone-a-vm-in-azure-c5299ff82496

Tags: , , ,

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.