Tutorial: Create a custom image of an Azure VM with the Azure CLI

Custom images are like marketplace images, but you create them yourself. Custom images can be used to bootstrap configurations such as preloading applications, application configurations, and other OS configurations. In this tutorial, you create your own custom image of an Azure virtual machine. You learn how to:

  • Deprovision and generalize VMs
  • Create a custom image
  • Create a VM from a custom image
  • List all the images in your subscription
  • Delete an image

This tutorial uses the CLI within the Azure Cloud Shell, which is constantly updated to the latest version. To open the Cloud Shell, select Try it from the top of any code block.

If you choose to install and use the CLI locally, this tutorial requires that you are running the Azure CLI version 2.0.30 or later. Run az --version to find the version. If you need to install or upgrade, see Install Azure CLI.

Before you begin

The steps below detail how to take an existing VM and turn it into a reusable custom image that you can use to create new VM instances.

To complete the example in this tutorial, you must have an existing virtual machine. If needed, this script sample can create one for you. When working through the tutorial, replace the resource group and VM names where needed.

Create a custom image

To create an image of a virtual machine, you need to prepare the VM by deprovisioning, deallocating, and then marking the source VM as generalized. Once the VM has been prepared, you can create an image.

Deprovision the VM

Deprovisioning generalizes the VM by removing machine-specific information. This generalization makes it possible to deploy many VMs from a single image. During deprovisioning, the host name is reset to localhost.localdomain. SSH host keys, nameserver configurations, root password, and cached DHCP leases are also deleted.


Deprovisioning and marking the VM as generalized will make source VM unusable, and it cannot be restarted.

To deprovision the VM, use the Azure VM agent (waagent). The Azure VM agent is installed on the VM and manages provisioning and interacting with the Azure Fabric Controller. For more information, see the Azure Linux Agent user guide.

Connect to your VM using SSH and run the command to deprovision the VM. With the +user argument, the last provisioned user account and any associated data are also deleted. Replace the example IP address with the public IP address of your VM.

SSH to the VM.

ssh azureuser@

Deprovision the VM.

sudo waagent -deprovision+user -force

Close the SSH session.


Deallocate and mark the VM as generalized

To create an image, the VM needs to be deallocated. Deallocate the VM using az vm deallocate.

az vm deallocate --resource-group myResourceGroup --name myVM

Finally, set the state of the VM as generalized with az vm generalize so the Azure platform knows the VM has been generalized. You can only create an image from a generalized VM.

az vm generalize --resource-group myResourceGroup --name myVM

Create the image

Now you can create an image of the VM by using az image create. The following example creates an image named myImage from a VM named myVM.

az image create \
    --resource-group myResourceGroup \
    --name myImage \
    --source myVM

Create VMs from the image

Now that you have an image, you can create one or more new VMs from the image using az vm create. The following example creates a VM named myVMfromImage from the image named myImage.

az vm create \
    --resource-group myResourceGroup \
    --name myVMfromImage \
    --image myImage \
    --admin-username azureuser \

We recommend that you limit the number of concurrent deployments to 20 VMs from a single image. If you are planning large-scale, concurrent deployments of over 20 VMs from the same custom image, you should use a Shared Image Gallery with multiple image replicas.

Image management

Here are some examples of common image management tasks and how to complete them using the Azure CLI.

List all images by name in a table format.

az image list \
    --resource-group myResourceGroup

Delete an image. This example deletes the image named myOldImage from the myResourceGroup.

az image delete \
    --name myOldImage \
	--resource-group myResourceGroup

Next steps

In this tutorial, you created a custom VM image. You learned how to:

  • Deprovision and generalize VMs
  • Create a custom image
  • Create a VM from a custom image
  • List all the images in your subscription
  • Delete an image

Advance to the next tutorial to learn about highly available virtual machines.