Back when I was a SysAdmin one of my roles was to create and maintain server images for quick deployment, so I often had templates for customer environments. They weren't perfect but they helped to make the creating of a new virtual server a bit more streamlined and consistent. For the customers that had Hyper-V environments we tended to use System Centre Configuration Manager (SCCM) or System Center Virtual Machine Manager (SCVMM) as the creation/storage/deployment mechanism, for those that were utilising VMware we used that "convert to template" offering that is built into VMware for the creation.
Custom templates or images in the cloud
I'm sure the method I've described is familiar to you as well. However moving to the cloud and hosting your virtual machines within Azure poses the question, how do I create my images, my templates for deployment?
My answer and recommendation to this question would always be to look at using something like PowerShell, Azure Resource Manager (ARM) templates, or Terraform, or Cloud-init, or Ansible, or Packer or one of the other many scripting tools out there to automate a repeatable, consistent way to build your Azure machines. You and your team might have to learn a new way of work, might have to invest in a new tool but it will serve you in the long run.
However, if you are looking for a "like for like" solution or an interim one while your team evaluate a scripting tool or build those scripts out. There is a feature within Azure you can use and it's available via the Azure Portal as Image.
This service within Azure allows you to create an image, store it and then use it time and time again.
Azure Image High Level Process
The high level process for using this service would be:
- Build your virtual machine (VM) within Azure
- Customise your VM with the necessary changes, software installs etc that you want your image to have
- Deprovision your VM, which involves deleting machine-specific files and data
- Shut down your VM
- Generalize your VM, allowing it to be imaged for multiple deployments
- Create the image
- Create a new VM from your image
Let's break down the 7 steps in the process... (in this example I am going to be building a Linux VM)
Create the VM
The first step in the process is to create your VM that you want to use to capture your image. You can use create VM using your usual process, or use the official quickstart documentation.
Customize the VM
Once the VM has been created install the necessary software and configuration changes that you need the image to have.
Deprovision the VM
The next step is now to deprovision the VM, this will delete machine-specific files and data. This command is ran within the VM itself:
sudo waagent -deprovision+user
It will remove any machine-specific files that have been created and will clear down the last created user. It's worth noting this doesn't guarantee that everything has been cleared down and you should ensure you check there aren't any procedures you need to manually follow relating to the software or config changes you've made to the VM as well.
Shut down the VM
In order to capture the image the VM needs to be shutdown.
Generalize the VM
Generalizing the image gain helps to ensure that anything machine specific, such as say the machine Security Identified (SID) is removed.
The following Azure CLI command can be used to generalize the Linux VM:
az vm generalize --resource-group rg-image --name masterimagevm01
Create the image
Now that the image is deprovisioned, generalized and shut down we can capture the image. The command line to do that is:
az image create --resource-group rg-image --name Image --source masterimagevm01
The above command will create an image called "Image" using the "masterimagevm01" machine as it's source. It will store this image in the "rg-image" resource group. It should be a quick process for this to take place.
If you want to create the image into a new resource, separate from where you have created the master image you will need to specify the full resource ID like so:
az image create --resource-group rg-imagestorage --name myImage --source /subscriptions/00000000-aaaa-bbbb-cccc-000000000000/resourceGroups/rg-image/providers/Microsoft.Compute/virtualMachines/masterimagevm01
Create a new VM from your image
So now that the image has been captured and is stored within your Azure account the next step is to start creating virtual machines from that.
Best practice would suggest that your new virtual machine should be stored within their own resource group, to do this you will need to reference the full resource ID of the image, so your command will look something like this:
az vm create resource-group rg-newvm --name vm01 --image "/subscriptions/00000000-aaaa-bbbb-cccc-000000000000/resourceGroups/rg-imagestorage/providers/Microsoft.Compute/images/Image" --admin-username azureuser --admin-password azurepassword
The above command is just a basic command to create the VM with a username and password and associated components, such as Network Security Group (NSG), public IP address. If you have an existing infrastructure you wish to add this VM into then your command will be more complex. You can reference the az vm create documentation to understand what other parameters you would need to use to do that.
And that's the process of capturing a master image from an existing virtual machine, very similar to what you would do say in your VMware environment where you build a VM then export it to template. I personally wouldn't be using this method to build out large scale environments within Azure, I'd be taking advantage of the scripting tools, the automation, etc to build images and keep them consistent and meeting your standards, but for short term or very specific cases this method is acceptable.
The process for doing the same with Windows virtual machines can be found here.
Please do let me know if you are using the above method and any advantages/disadvantages you find from it or if you've ditch it for something else. I'd love to hear "real world" stories.