Within Azure IaaS exists the often overlooked, yet important, subtleties of Virtual Machine (VM) Disks and Images. Both of these allow you to generate Azure IaaS VMs using differing strategies. In this post, I will clear up misunderstandings on the relationship between the two and how they map into the VM and VHD model for Azure.
Creating and Uploading VHDs
Azure VMs use Hyper-V fixed format VHDs. So if you upload a dynamically formatted VHD it will be converted to fixed format. This may cause an unexpected bloat during the upload and yield a size greater than the 127 GB disk size limit imposed for Azure IaaS VM images. Thus it is recommended that you create a fixed format VHD before you upload it to Azure and don’t rely upon the conversion from dynamic to fixed format during the upload process. VHDs can be uploaded using a PowerShell cmdlet Add-AzureVhd or using the CSUPLOAD SDK utility.
To generalize the VM Image, you must first run the Sysprep utility and check the Generalize checkbox. The Sysprep utility sterilizes a VHD by removing system-specific data. This permits you to use it generically as an image base for more than one VM instances. So if you run Sysprep on a VHD you can load it as an Azure VM Image.
Note: Make sure that file C:\windows\system32\Sysprep\unattend.xml is removed from the location before you run Sysprep. If you don’t, the VHD may never load successfully into an Azure VM in later steps when you convert the VHD to a VM image.
There are situations when you don’t want to run Sysprep on a VHD since in some cases making that disk generic can render it useless for its desired application. For instance, you may have a Domain Controller on your VHD and executing Sysprep would make it ineffective as a DC. You will also most likely not be creating duplicate VMs from an image of a DC and therefore not need to run Sysprep. If you don’t Sysprep the VHD can only load as an Azure VM Disk. This serves as a specific base type for a VM. It is not a generic image from which you will be creating multiple generic images. In summary:
- VM Disks are sterile images from Sysprep and create generic Azure VMs
- VM Disks are not sterilized with Sysprep and create unique Azure VMs
Creating Azure VM Images
To create a generic Azure VM Image from a Sysprep’d VHD you will enter the blob URL of the location where you uploaded the VHD. For a VM Image it is required that you check the box that says “I have run Sysprep on the virtual machine associated with this VHD”.
Using PowerShell you can also create a VM disk from a VHD using Add-AzureVMImage.
Creating Azure VM Disks
To create a unique Azure VM Disk from a VHD you will enter the blob URL of the location you uploaded the VHD. You are not given a Sysprep option since a VM Disk is not generic. It is based upon a specific VHD from which there will probably be only one instance. Check “The VHD contains an operating system” if this is an OS disk.
Using PowerShell you can also create a VM disk from a VHD using Add-AzureDisk.
Once you have converted the VHDs into either Azure Disks or Images you can create Azure VMs from them.
Creating Azure VMs from Azure VM Image
You can create one or more Azure VMs from an Azure VM Image. Once you create an Azure VM Image (from a VHD) you will see your image(s) by clicking My Images in the Create a Virtual Machine wizard. You select your image just like you would one of the pre-defined Platform Images from the Gallery.
Creating an Azure VM from Azure VM Disk
You can create an Azure VM from an Azure VM Disk. Once you create an Azure VM Disk (from a VHD) you will see you disk(s) by clicking My Disk in the Create a Virtual Machine wizard. You select your disk just like you would one of the pre-defined Platform Images from the Gallery.
Azure VM Best Practices
Here are a few tips when work with Azure VMs and VHDs:
- Make sure when you attempt to create an image from a VHD that if you have previously done it before you delete the Azure Cloud Service that Azure creates for you when a VM is deleted.
- Make sure you delete the link between the VHD and a VM by deleting the VM but retain the VHD. You can delete the VHD as well when doing this but you will have to upload the VHD again to blob storage which may take considerable time. Unless you are updating with a new VHD, deleting the VHD with the link is not desirable.
- Azure will create its temporary drive on the D drive. So if you are uploading a VHD with a logical D drive then D: will be renamed to the E: drive. If you have any logging or application functionality that uses the D drive as a permanent drive you will need to change the logic of your application since there is no way to change the drive letter of the Azure temp drive to anything other than D.
- If you take a VHD image that contains more than just the C: logical drive (say J: and K: drive as well) when converted to an Azure VM all logical drives will still exist in Azure. But they will be part of the one VHD file at the file system level. In other words, you won’t see one VHD for each logical disk on the volume.
- Using PowerShell you can also create a VM Image from a VHD using Add-AzureVM.
- Once a VM is created you can attach additional disks to your VM. It is a best practice for disks that will hold data, such as SQL Server and AD log files, to have them on a permanent drive that is not the main C: drive. The C: drive should be reserved for the OS and application installs. Utilize the other disks for log files and backups.
- When creating a VM as a part of a VNET, open any firewall ports on the VM to allow traffic in or out. For instance, you can open port 1433 for SQL Server to communicate with that VM
- Create the virtual machine inside an affinity group to reduce latency with storage services and any networks of which it may be configured.
Do you agree with these best practices? Are there any that I have missed? Let me know in the comments below.