Move an Azure VM from Standard to Premium Storage

Server Hero
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).

Background

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:

  1. Remove the virtual machine, while keeping the disks.
  2. Move the required disks to the desired Premium Storage account.
  3. Create a new virtual machine from the existing disks.
  4. Ensure that volume letters are consistent and services and access data.

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:

  • OS
  • Programs
  • Settings
  • Data

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:

  1. Remove the virtual machine, while keeping the disks.
  2. Move the required disks to the desired Premium Storage account.
  3. Create a new virtual machine from the existing disks.
  4. Create new Premium Storage disks(s) and attach the disks.
  5. Migrate the data from the Standard Storage disks to the Premium Storage disk(s).
  6. Remove the redundant disks and ensure that volume letters are consistent.

Prerequisites

You will need to:

  • Create an Azure Premium Storage account if it does not already exist.
  • Create a container called vhds in the Premium Storage account if it does not already exist.
  • Retrieve the access keys for your source and destination storage accounts.
  • Download and install the latest version of AzCopy.
  • Perform an audit of the virtual machine – make sure to note the network configuration.

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.

Save the virtual machine's network interface details [Image Credit: Aidan Finn]
Save the virtual machine’s network interface details [Image Credit: Aidan Finn]

Remove The Original Virtual Machine

In this example, I have a Basic A1 virtual machine running in Azure V2 (Azure Resource Manager or ARM) that has:

  • An OS disk
  • One data disk

The Azure virtual machine OS and data disks on Standard Storage [Image Credit: Aidan Finn]
The Azure virtual machine OS and data disks on Standard Storage [Image Credit: Aidan Finn]
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.

Querying the storage details of an Azure VM [Image Credit: Aidan Finn]
Querying the storage details of an Azure VM [Image Credit: Aidan Finn]
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

Migrate the Disks

There are two ways that you can move blobs (the VHD files, in this case) between storage accounts in Azure:

  • Download and upload, which would take a long time.
  • Directly using AzCopy (a free tool) or the Copy Blob API.

I used AzCopy to move the data disk to the Premium Storage account:

  1. Open command prompt
  2. Browse to C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy
  3. Run the following command:
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:

  • The source storage account and container.
  • The destination storage account and container.
  • The access key for the source storage account.
  • The access key for the destination storage account.
  • The name of the blob (vhd file) being moved.

No data was downloaded or uploaded; Azure copied the file from the source storage account directly to the destination storage account.

Create a New Virtual Machine

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.