Converting Azure Managed Disks to Unmanaged

Microsoft has introduced the ability to create managed disks in Azure a while ago. This feature takes away the manual management overhead for you to keep track of your storage account limits. Managed disks are not stored in “regular” storage accounts, but Microsoft will take care of the VHD placement and will keep track of any IOPS limitions.

For example, a Standard Size VM allows 500 IOPS per disk. The maximum IOPS for a Standard storage account is 20.000 IOPS. This means that you can host a maximum of 40 disks (OS or Data) in a Standard storage account. When you use unmanaged disks, you’ll need to keep track of this limitation yourself. When using managed disks, Microsoft will make sure the 500 IOPS per disk is available, regardless of the storage account.

The conversion of an unmanaged disk to managed is very easy; Microsoft created the ConvertTo-AzureRmVMManagedDisk CmdLet for this. But if you want to convert back from managed to unmanaged, no CmdLet or function in the Azure portal is available for the conversion (for example Azure Site Recovery; very nice feature of Azure, but it doesn’t support managed disks). Converting back to unmanaged is a bit harder, but still possible.

Converting from managed to unmanaged

Converting a managed disk to an unmanaged disk basically means you need to copy the managed VHD file to one of your storage accounts and create a VM using that copied VM. The step-by-step process to convert back to unmanaged is as follows:

  1. Get the Managed Disk object using Get-AzureRmDisk
  2. Grant Access to the Managed Disks using Grant-AzureRmDiskAccess
  3. Copy the VHD to your storage account using Start-AzureStorageBlobCopy
  4. Detach any Network Interfaces from the original VM
  5. Recreate the VM using the copied VHDs
  6. Attach the Network Interfaces

Copying the VHD to a storage account

First of all, you should retrieve the disk name using the foloowing commands:

$vm = Get-AzureRmVM -ResourceGroupName RESOURCEGROUPNAME -Name VMNAME
$vm.StorageProfile.OsDisk | Where-Object {$_.ManagedDisk -ne $null} | Select-Object Name
$vm.StorageProfile.DataDisks | Where-Object {$_.ManagedDisk -ne $null} | Select-Object Name

This retrieves all the managed disks (both OS and Data) from the defined VM. You should not the names of the disks you need to convert. Next, you have to create a storage context which can later be used to copy the VHDs (you can retrieve the storage account key using the portal, or using Get-AzureRmStorageAccountKey):

$context = New-AzureStorageContext -StorageAccountName STORAGEACCOUNTNAME -StorageAccountKey STORAGEACCOUNTKEY

Once you created the context, you can grant access and start the blob copy. To keep track of the asynchronous copy action, you can pass the output of the Start-AzureStorageBlobCopy cmdlet to a variable and later on check the status using Get-AzureStorageBlobCopyState.

$sas = Grant-AzureRmDiskAccess -ResourceGroupName RESOURCEGROUPNAME -DiskName DISKNAME -Access Read -DurationInSecond (60*60*24)
$blobcopyresult = Start-AzureStorageBlobCopy -AbsoluteUri $sas.AccessSAS -DestinationContainer "vhds" -DestinationBlob "YOURDISKNAME.vhd" -DestinationContext $context

During the copy phase, you can retrieve the status using the following command:

$blobcopyresult | Get-AzureStorageBlobCopyState

Recreating the VM

Once the copy job is done, I’d rename the old VM to eg. VMNAME_old; this way you can always switch back to the old VM if anything goes wrong. To connect the new VM to the same virtual network, you can detach the network interfaces from the old VM, so we can attach them again to the new VM. You should take note of those NICs before detaching them, so we can attach them later easily.

Recreating a VM from the copied VHD can be done using the following commands:

$vmconfig = New-AzureRmVMConfig -VMName VMNAME -VMSize "VMSIZE"
$vm = Add-AzureRmVMNetworkInterface -VM $vmConfig -Id (Get-AzureRmNetworkInterface -Name NICNAME -ResourceGroupName RESOURCEGROUPNAME).Id
$vm = Set-AzureRmVMBootDiagnostics -VM $vm -Enable -ResourceGroupName RESOURCEGROUPNAME-StorageAccountName BOOTDIAGNOSTICSSTORAGEACCOUNTNAME
$vm = Set-AzureRmVMOSDisk -VM $vm -VhdUri (Get-AzureStorageBlob -Context $context -Blob "YOURDISKNAME.vhd" -Container "vhds").ICloudBlob.uri.AbsoluteUri -CreateOption Attach -Name "YOURDISKNAME"
New-AzureRmVM -ResourceGroupName RESOURCEGROUPNAME -Location westeurope -VM $vm

Additional configuration

Note that you is possibly that you need to do some additional configuration. You’ll need to remember the following from your original VM:

  • VM Extensions
  • Availability set
  • Auto-shutdown
  • Configuration (Managed Service Identity and Azure hybrid benefit)

If you need to deploy the VM in an availability set, be sure to include this during re-creation:

$vmconfig = New-AzureRmVMConfig -VMName VMNAME -VMSize "VMSIZE" -AvailabilitySetId AVAILABILITYSETID
I hope this article was useful for you. If you have any questions, please don’t hesitate to leave a comment or contact me over email.

Leave a Reply

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

Complete the following sum: * Time limit is exhausted. Please reload CAPTCHA.