In this article I will show you how to migrate the data disks of an Azure virtual machine (in Azure Resource Manager or ARM) from a Standard Storage (HDD-based) account to a Premium Storage (SSD-based) storage account to improve performance (more IOPS and less latency).
Most organizations will choose to deploy virtual machines on Standard Storage by default; this is because Premium Storage, which offers shared SSD capacity for OS disks and/or data disks, is quite expensive compared to the relatively affordable HDD-based infrastructure. There will come a time, for some customers or machines, when you’ll find that even with some IOPS engineering on Standard Storage, you’ll face the challenge of having to migrate some or all disks of a machine to Premium Storage.
Unfortunately, there is no “click here to move disks” option for migrating disks to the faster shared storage option. This is a scenario where understanding the anatomy of an Azure virtual machine is valuable.
The normal solution for migrating a virtual machine, some or all of the disks, is to do the following:
Remember that deleting a virtual machine and keeping the disks is just removing metadata; you don’t need that metadata, which is just “hardware configuration data” because you are creating a new machine that will be attached to the new disks. The disks are where all the value of the machine is:
The process is similar to removing the disks from a one physical server and moving them to an identical physical server; a commonly used solution to resolve catastrophic server hardware failure.
Note: This process is creating a new machine with new NICs so you might need to consider re-reserving IP addresses, re-assigning per-NIC/machine network security group (NSG) policies, or similar, that you might have previously created. Perform an audit of the machine before proceeding.
There are some cases where you might want to consider a data migration. For example, your Standard Storage virtual machine might have several data disks to accumulate one or two thousand IOPS. A single smaller Premium Storage disk might offer that same performance, and it would be more affordable to have a single disk in Premium Storage than multiple disks. In that case:
You will need to:
An ARM virtual machine stores the network configuration in a NIC object. This object survives the deletion of a virtual machine and can be reused. You can get the name of the NIC object using PowerShell:
(Get-AzureRMVM -ResourceGroupName PetriMig -Name PetriMig).NetworkInterfaceIDs
In my example, the NIC object is called petrimig513; I will re-use this to connect the new virtual machine with the original virtual machine’s network profile.
In this example, I have a Basic A1 virtual machine running in Azure V2 (Azure Resource Manager or ARM) that has:
I am going to rebuild this machine as a DS-1 virtual machine where the data disk has been migrated to Premium Storage.
I logged into Azure Resource Manager via PowerShell and ran the following (PetriMig is the name of the virtual machine and the resource group):
Get-AzureRmVM -Name PetriMig -ResourceGroupName PetriMig
I paid special attention to the details under Storage Profile (shown below). Here I can see the storage account URLs of the OS disk (red) and the data disk (orange). Note the URI value of any disk that you want to move.
You will need to shut down the virtual machine:
Stop-AzureRmVM -Name PetriMig -ResourceGroupName PetriMig
Then you need to remove the virtual machine. Note that the blobs (the VHD files) that made the disks are still in the storage account after removing the machine:
Remove-AzureRmVM -Name PetriMig -ResourceGroupName PetriMig
There are two ways that you can move blobs (the VHD files, in this case) between storage accounts in Azure:
I used AzCopy to move the data disk to the Premium Storage account:
AzCopy.exe" /Source:"https://petrimigstd.blob.core.windows.net/vhds" /Dest:"https://petrimigpre.blob.core.windows.net/vhds" /SourceKey:<SecretKey1> /DestKey: <SecretKey2> /Pattern:PetriMigData.vhd
Note that I specified:
No data was downloaded or uploaded; Azure copied the file from the source storage account directly to the destination storage account.
The following PowerShell script will create a new ARM virtual machine from an existing OS disk and data disk. This script is based on a large number of incomplete snippets that I found on Microsoft sites. Change the names and URI’s to suit your requirements.
## Environment - same region and resource group as old VM $LocationName = "northeurope" $ResourceGroupName = "PetriMig" ## VM - reusing the old VM details $ComputerName = "PetriMig" $VMName = "PetriMig" ## OS Disk - using the old disk $OSDiskName = "PetriMig" $OSDiskUri = "https://petrimigstd.blob.core.windows.net/vhds/PetriMig2016325104259.vhd" $VMSize = "Standard_DS1" ## DataDisk - using the new disk $DataDiskUri = "https://petrimigpre.blob.core.windows.net/vhds/PetriMigData.vhd" ## Networking - reuse the old machine's network connection $NICObjectName = "PetriMig513" $NIC = Get-AzureRmNetworkInterface -ResourceGroupName PetriMig -Name $NICObjectName ## Build up the VM configuration using the existing disks $VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize $VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id $VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -VhdUri $OSDiskUri -name $OSDiskName -CreateOption attach -Windows -Caching "ReadWrite" $VirtualMachine = Add-AzureRmVMDataDisk -VM $VirtualMachine -Name "PetriMigData" -VhdUri $DataDiskUri -Lun 0 -CreateOption attach -DiskSizeInGB $null -Caching "ReadOnly" ## Deploy the new VM from the configuration # You can comment out the next line to test the above without creating a machine, saving loads of time. New-AzureRmVM -ResourceGroupName $ResourceGroupName -Location $LocationName -VM $VirtualMachine -Verbose
A few minutes later, I have a new DS1 virtual machine (instead of a Basic A1) that has a Premium Storage data disk.