Custom data and cloud-init on Azure Virtual Machines

Applies to: ✔️ Linux VMs ✔️ Windows VMs ✔️ Flexible scale sets

You might need to inject a script or other metadata into a Microsoft Azure virtual machine (VM) at provisioning time. In other clouds, this concept is often called user data. Microsoft Azure has a similar feature called custom data.

Custom data is made available to the VM during first startup or setup, which is called provisioning. Provisioning is the process where VM creation parameters (for example, host name, username, password, certificates, custom data, and keys) are made available to the VM. A provisioning agent, such as the Linux Agent or cloud-init, processes those parameters.

Pass custom data to the VM

To use custom data, you must Base64-encode the contents before passing the data to the API--unless you're using a CLI tool that does the conversion for you, such as the Azure CLI. The size can't exceed 64 KB.

In the CLI, you can pass your custom data as a file, as the following example shows. The file will be converted to Base64.

az vm create \
  --resource-group myResourceGroup \
  --name centos74 \
  --image OpenLogic:CentOS-CI:7-CI:latest \
  --custom-data cloud-init.txt \
  --generate-ssh-keys

In Azure Resource Manager, there's a base64 function:

"name": "[parameters('virtualMachineName')]",
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2019-07-01",
"location": "[parameters('location')]",
"dependsOn": [
..],
"variables": {
        "customDataBase64": "[base64(parameters('stringData'))]"
    },
"properties": {
..
    "osProfile": {
        "computerName": "[parameters('virtualMachineName')]",
        "adminUsername": "[parameters('adminUsername')]",
        "adminPassword": "[parameters('adminPassword')]",
        "customData": "[variables('customDataBase64')]"
        },

Process custom data

The provisioning agents installed on the VMs handle communication with the platform and placing data on the file system.

Windows

Custom data is placed in %SYSTEMDRIVE%\AzureData\CustomData.bin as a binary file, but it isn't processed. If you want to process this file, you'll need to build a custom image and write code to process CustomData.bin.

Linux

On Linux operating systems, custom data is passed to the VM via the ovf-env.xml file. That file is copied to the /var/lib/waagent directory during provisioning. Newer versions of the Linux Agent will also copy the Base64-encoded data to /var/lib/waagent/CustomData for convenience.

Azure currently supports two provisioning agents:

  • Linux Agent. By default, the agent won't process custom data. You need to build a custom image with the data enabled. The relevant settings are:

    • Provisioning.DecodeCustomData
    • Provisioning.ExecuteCustomData

    When you enable custom data and run a script, it will delay the VM reporting that it's ready or that provisioning has succeeded until the script has finished. If the script exceeds the total VM provisioning time allowance of 40 minutes, VM creation will fail.

    If the script fails to run, or errors happen during execution, that's not a fatal provisioning failure. You'll need to create a notification path to alert you for the completion state of the script.

    To troubleshoot custom data execution, review /var/log/waagent.log.

  • cloud-init. By default, this agent will process custom data. It accepts multiple formats of custom data, such as cloud-init configuration and scripts.

    Similar to the Linux Agent, if errors happen during execution of the configuration processing or scripts when cloud-init is processing the custom data, that's not a fatal provisioning failure. You'll need to create a notification path to alert you for the completion state of the script.

    However, unlike the Linux Agent, cloud-init doesn't wait for custom data configurations from the user to finish before reporting to the platform that the VM is ready. For more information on cloud-init on Azure, including troubleshooting, see cloud-init support for virtual machines in Azure.

FAQ

Can I update custom data after the VM has been created?

For single VMs, you can't update custom data in the VM model. But for virtual machine scale sets, you can update custom data via the REST API, the Azure CLI, or Azure PowerShell. When you update custom data in the model for a virtual machine scale set:

  • Existing instances in the scale set won't get the updated custom data until they're reimaged.
  • Existing instances in the scale set that are upgraded won't get the updated custom data.
  • New instances will receive the new custom data.

Can I place sensitive values in custom data?

We advise not to store sensitive data in custom data. For more information, see Azure data security and encryption best practices.

Is custom data made available in IMDS?

Custom data is not available in Azure Instance Metadata Service (IMDS). We suggest using user data in IMDS instead. For more information, see User data through Azure Instance Metadata Service.