Packer supports building VHDs in [Azure Resource Manager](https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/). Azure provides new users a [$200 credit for the first 30 days](https://azure.microsoft.com/en-us/free/); after which you will incur costs for VMs built and stored using Packer.
Unlike most Packer builders, the artifact produced by the ARM builder is a VHD (virtual hard disk), not a full virtual machine image. This means you will need to [perform some additional steps](https://github.com/Azure/packer-azure/issues/201) in order to launch a VM from your build artifact.
Azure uses a combination of OAuth and Active Directory to authorize requests to the ARM API. Learn how to [authorize access to ARM](/docs/builders/azure-setup.html).
The documentation below references command output from the [Azure CLI](https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/).
## Configuration Reference
The following configuration options are available for building Azure images. In addition to the options listed here, a
[communicator](/docs/templates/communicator.html) can be configured for this
-`subscription_id` (string) Subscription under which the build will be performed. **The service principal specified in `client_id` must have full access to this subscription.**
-`capture_container_name` (string) Destination container name. Essentially the "directory" where your VHD will be organized in Azure. The captured VHD's URL will be https://<storage_account>.blob.core.windows.net/system/Microsoft.Compute/Images/<capture_container_name>/<capture_name_prefix>.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd.
-`image_publisher` (string) PublisherName for your base image. See [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/) for details.
-`image_offer` (string) Offer for your base image. See [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/) for details.
-`image_sku` (string) SKU for your base image. See [documentation](https://azure.microsoft.com/en-us/documentation/articles/resource-groups-vm-searching/) for details.
-`temp_compute_name` (string) temporary name assigned to the VM. If this value is not set, a random value will be assigned. Knowing the resource group and VM name allows one to execute commands to update the VM during a Packer build, e.g. attach a resource disk to the VM.
-`temp_resource_group_name` (string) temporary name assigned to the resource group. If this value is not set, a random value will be assigned.
Azure VMs should be deprovisioned at the end of every build. For Windows this means executing sysprep, and for Linux this means executing the waagent deprovision process.
Please refer to the Azure [examples](https://github.com/hashicorp/packer/tree/master/examples/azure) for complete examples showing the deprovision process.
One solution is to set skip_clean to true in the provisioner. This prevents Packer from cleaning up any helper scripts uploaded to the VM during the build.
## Defaults
The Azure builder attempts to pick default values that provide for a just works experience. These values can be changed by the user to more suitable values.
* The default user name is packer not root as in other builders. Most distros on Azure do not allow root to SSH to a VM hence the need for a non-root default user. Set the ssh_username option to override the default value.
* The default VM size is Standard_A1. Set the vm_size option to override the default value.
* The default image version is latest. Set the image_version option to override the default value.
The Azure builder works under the assumption that it creates everything it needs to execute a build. When the build has
completed it simply deletes the resource group to cleanup any runtime resources. Resource groups are named using the
form `packer-Resource-Group-<random>`. The value `<random>` is a random value that is generated at every invocation of
packer. The `<random>` value is re-used as much as possible when naming resources, so users can better identify and
group these transient resources when seen in their subscription.
> The VHD is created on a user specified storage account, not a random one created at runtime. When a virtual machine
is captured the resulting VHD is stored on the same storage account as the source VHD. The VHD created by Packer must
persist after a build is complete, which is why the storage account is set by the user.
The basic steps for a build are:
1. Create a resource group.
1. Validate and deploy a VM template.
1. Execute provision - defined by the user; typically shell commands.
1. Power off and capture the VM.
1. Delete the resource group.
1. Delete the temporary VM's OS disk.
The templates used for a build are currently fixed in the code. There is a template for Linux, Windows, and KeyVault.
The templates are themselves templated with place holders for names, passwords, SSH keys, certificates, etc.
### What's Randomized?
The Azure builder creates the following random values at runtime.
* Administrator Password: a random 32-character value using the *password alphabet*.
* Certificate: a 2,048-bit certificate used to secure WinRM communication. The certificate is valid for 24-hours, which starts roughly at invocation time.
* Certificate Password: a random 32-character value using the *password alphabet* used to protect the private key of the certificate.
* Compute Name: a random 15-character name prefixed with pkrvm; the name of the VM.
* Deployment Name: a random 15-character name prefixed with pkfdp; the name of the deployment.
* KeyVault Name: a random 15-character name prefixed with pkrkv.
* OS Disk Name: a random 15-character name prefixed with pkros.
* Resource Group Name: a random 33-character name prefixed with packer-Resource-Group-.
* SSH Key Pair: a 2,048-bit asymmetric key pair; can be overriden by the user.
The default alphabet used for random values is **0123456789bcdfghjklmnpqrstvwxyz**. The alphabet was reduced (no
vowels) to prevent running afoul of Azure decency controls.
The password alphabet used for random values is **0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ**.
### Windows
The Windows implementation is very similar to the Linux build, with the exception that it deploys a template to
configure KeyVault. Packer communicates with a Windows VM using the WinRM protocol. Windows VMs on Azure default to
using both password and certificate based authentication for WinRM. The password is easily set via the VM ARM template,
but the certificate requires an intermediary. The intermediary for Azure is KeyVault. The certificate is uploaded to a
new KeyVault provisioned in the same resource group as the VM. When the Windows VM is deployed, it links to the
certificate in KeyVault, and Azure will ensure the certificate is injected as part of deployment.
The basic steps for a Windows build are:
1. Create a resource group.
1. Validate and deploy a KeyVault template.
1. Validate and deploy a VM template.
1. Execute provision - defined by the user; typically shell commands.
1. Power off and capture the VM.
1. Delete the resource group.
1. Delete the temporary VM's OS disk.
A Windows build requires two templates and two deployments. Unfortunately, the KeyVault and VM cannot be deployed at
the same time hence the need for two templates and deployments. The time required to deploy a KeyVault template is
minimal, so overall impact is small.
> The KeyVault certificate is protected using the object_id of the SPN. This is why Windows builds require object_id,
and an SPN. The KeyVault is deleted when the resource group is deleted.