Compute Virtual Machines field-manual-complete field-manual operator-field-manual

VM custom data

VM custom data is the first-boot note you hand to a virtual machine when Azure creates it. For Linux images with cloud-init, that note can install packages, write files, configure users, or start services. For Windows, custom data is placed on disk but is not automatically executed unless you build logic to use it. It is useful for repeatable setup, but it is not a secret store, not an ongoing configuration manager, and not easy to change for an existing single VM.

Aliases
custom data, Azure VM custom data, cloud-init custom data, VM bootstrap data
Difficulty
intermediate
CLI mappings
5
Last verified
2026-05-28

Microsoft Learn

VM custom data is text or a file payload supplied to a virtual machine at creation time. Azure passes it into the guest so cloud-init, agents, or first-boot scripts can configure software, register the node, or write initial settings securely.

Microsoft Learn: Custom data and cloud-init on Azure Virtual Machines2026-05-28

Technical context

Custom data sits in the VM osProfile during provisioning. Azure accepts the content through APIs, templates, or Azure CLI, with CLI handling Base64 conversion when a file is supplied. The platform passes the data to the guest, where cloud-init or the Linux Agent may process it depending on the image and configuration. It is closely related to VM images, extensions, cloud-init logs, boot diagnostics, user data, and VM Scale Set model updates. For single VMs, custom data is effectively a provisioning-time input rather than a lifecycle configuration channel.

Why it matters

Custom data matters because first boot is the moment when a VM becomes useful or becomes another snowflake. A good custom-data file can install an agent, register a service, pull configuration, create users, or write application settings consistently across environments. A bad one can hang provisioning, expose secrets, break networking, or create VMs that look deployed but are not ready. The concept also teaches a healthy boundary: use custom data for bootstrap, then use images, extensions, configuration management, Key Vault, or pipelines for ongoing change. Treating it as permanent automation usually creates troubleshooting pain later. Review it before release. Failures compound quickly.

Where you see it

Signals, screens, and Azure surfaces where this term usually becomes operational.

Signal 01

In ARM, Bicep, or CLI deployment definitions, osProfile.customData or --custom-data points to the bootstrap content supplied during VM creation and review by platform engineers.

Signal 02

On Linux guests, operators inspect cloud-init status, /var/log/cloud-init.log, waagent logs, and generated files to confirm custom data processing after first boot successfully.

Signal 03

In deployment failures, errors often mention provisioning timeouts, invalid Base64 content, cloud-init syntax, package repository failures, or scripts that never completed successfully during bootstrap troubleshooting.

When this becomes relevant

Specific situations where this term helps solve real Azure design, operations, migration, security, reliability, cost, or governance problems.

  • Bootstrap a Linux VM with cloud-init so packages, users, files, and services are configured consistently on first boot.
  • Pass environment-specific metadata to a VM image without building a separate image for every dev, test, and production setting.
  • Test first-boot setup scripts quickly in disposable resource groups before promoting them into image or scale-set automation.
  • Diagnose provisioning failures by connecting custom-data versions with cloud-init logs and boot diagnostics evidence.
  • Avoid embedding secrets by using custom data only to trigger managed-identity retrieval from Key Vault or configuration services.

Real-world case studies

Different enterprise-style examples that show the term being used to hit measurable objectives.

Case study 01

Cybersecurity lab builds repeatable attack-range VMs

Cybersecurity lab builds repeatable attack-range VMs: VM custom data is powerful when it bootstraps repeatable environments without becoming a secret store or full configuration platform.

Scenario

A security training team created short-lived Linux VMs for hands-on detection exercises. Manual setup caused each class to see different tool versions and broken lab instructions.

Business/Technical Objectives
  • Provision each student VM with identical packages and sample data.
  • Finish bootstrap before the first exercise begins.
  • Keep credentials out of startup scripts and shared templates.
  • Destroy failed lab VMs quickly to avoid wasting class time.
Solution Using VM custom data

The lab team created a cloud-init custom-data file that installed approved packages, created exercise directories, registered the VM with monitoring, and pulled nonsecret lesson data from private storage. Secrets were retrieved at runtime through managed identity and Key Vault, not written into custom data. Instructors tested the file with az vm create in a disposable resource group before every course. Boot diagnostics and cloud-init status checks were collected automatically when a VM failed readiness. The base image contained stable dependencies, so custom data stayed small and environment-specific.

Results & Business Impact
  • Student VM readiness improved from 82 percent to 98 percent before class start.
  • Average lab build time fell from 47 minutes to 14 minutes.
  • No credentials were found in custom-data reviews after the Key Vault pattern was adopted.
  • Failed VM cleanup time dropped to under five minutes through tagged disposable resources.
Key Takeaway for Glossary Readers

VM custom data is powerful when it bootstraps repeatable environments without becoming a secret store or full configuration platform.

Case study 02

Energy analytics nodes join processing grid automatically

Energy analytics nodes join processing grid automatically: VM custom data is best used as a small bridge between a reusable image and environment-specific registration.

Scenario

An energy analytics group deployed burst Linux VMs to process sensor backlogs after storms. Analysts lost time SSHing into new nodes to install agents and register them with the scheduler.

Business/Technical Objectives
  • Register new processing nodes without manual login.
  • Avoid baking storm-specific configuration into the base image.
  • Reduce time from VM creation to useful queue processing.
  • Capture first-boot failures before analysts notice missing capacity.
Solution Using VM custom data

The platform team moved node registration into VM custom data processed by cloud-init. The script installed a lightweight scheduler agent, wrote the regional queue endpoint, and used managed identity to fetch certificates from Key Vault. Heavy analytics libraries were already in the image, which kept first boot short. Azure CLI created test VMs with the exact custom-data file used by production automation. Boot diagnostics and cloud-init logs were sent to the operations workspace when registration failed. Nodes reported readiness only after they joined the scheduler and processed a small validation task.

Results & Business Impact
  • New node readiness time dropped from 33 minutes to 8 minutes.
  • Manual SSH setup was eliminated for storm-response processing bursts.
  • Queue backlog cleared 29 percent faster during the next severe-weather event.
  • Failed bootstrap cases were detected within four minutes through readiness checks.
Key Takeaway for Glossary Readers

VM custom data is best used as a small bridge between a reusable image and environment-specific registration.

Case study 03

Financial modeling team prevents broken first-boot scripts

Financial modeling team prevents broken first-boot scripts: VM custom data should be tested like deployment code because a small first-boot mistake can multiply across expensive compute.

Scenario

A quantitative research team used custom Linux VMs for model backtesting. A malformed cloud-init update once created twenty running VMs with no monitoring agent and no job runner.

Business/Technical Objectives
  • Validate custom data before creating large modeling batches.
  • Stop failed bootstrap attempts before they consume a full day of compute.
  • Separate image problems from script, network, and package repository failures.
  • Keep audit evidence for changes to the modeling environment.
Solution Using VM custom data

The team added a preflight process around VM custom data. Every script change was committed to source control, linted for YAML errors, and tested with one az vm create command in a sandbox subscription. The test checked cloud-init status, verified the monitoring agent, and ran a one-minute backtest job. If checks passed, the pipeline promoted the same custom-data file to the batch deployment. Boot diagnostics remained enabled so failed early startup could be reviewed without SSH. Large packages moved into the golden image, reducing the script to environment metadata and registration logic.

Results & Business Impact
  • The next malformed YAML change was caught before any production batch VMs were created.
  • Wasted compute from failed first boot fell 76 percent over two months.
  • Mean diagnosis time for bootstrap failures dropped from 65 minutes to 12 minutes.
  • Audit reviewers could trace every custom-data version to a tested commit.
Key Takeaway for Glossary Readers

VM custom data should be tested like deployment code because a small first-boot mistake can multiply across expensive compute.

Why use Azure CLI for this?

I use Azure CLI for custom data because first-boot automation must be tested exactly the way it will be deployed. CLI can create a disposable VM from the intended image with the same cloud-init file, then collect provisioning state, boot logs, and cloud-init status without hand-clicking. It also makes Base64 handling less error-prone when passing a file. After many Azure VM rollouts, I want every custom-data change tested in a small resource group before it enters image or scale-set automation. CLI gives fast feedback when YAML indentation, package repositories, network access, or permissions break initialization. Reproducibility beats tribal memory. Pipeline tests reduce surprises.

CLI use cases

  • Create a disposable VM with the exact custom-data file planned for production and verify first-boot behavior.
  • Show VM provisioning state and metadata after creation without expecting the raw custom-data payload to be returned.
  • Run a cloud-init status command inside the guest to confirm whether bootstrap finished or failed.
  • Collect boot diagnostics logs when cloud-init output indicates package, network, or script execution problems.
  • Update a VM Scale Set model customData value only after planning reimage behavior for existing instances.

Before you run CLI

  • Confirm tenant, subscription, resource group, VM name, image, OS type, provisioning agent, and whether cloud-init is supported.
  • Check custom-data size, encoding, YAML syntax, line endings, package repositories, network access, and dependency availability before deployment.
  • Remove secrets, long-lived tokens, passwords, private keys, and sensitive connection strings from the custom-data file.
  • Understand that single-VM custom data is provided at provisioning time and is not a convenient ongoing update mechanism.
  • Capture expected logs, readiness signals, and cleanup steps for failed test VMs before running automated create commands.

What output tells you

  • VM create output shows whether the Azure resource provisioned, but guest bootstrap may still be running or may have failed later.
  • VM show output confirms VM identity, provisioning state, image-related metadata, and computer name, not the full raw custom-data content.
  • Cloud-init status output tells you whether initialization is running, done, degraded, or failed with actionable module details.
  • Boot diagnostics output captures early startup and cloud-init messages when normal SSH or application monitoring is not available.
  • VMSS update output confirms the model changed, but existing instances need update or reimage behavior before receiving new custom data.

Mapped Azure CLI commands

VM custom data and first-boot configuration operations

direct
az vm create --resource-group <resource-group> --name <vm-name> --image Ubuntu2204 --custom-data cloud-init.txt --generate-ssh-keys
az vmprovisionCompute
az vm show --resource-group <resource-group> --name <vm-name> --query "{provisioningState:provisioningState,vmId:vmId,osProfile:osProfile.computerName}"
az vmdiscoverCompute
az vm run-command invoke --resource-group <resource-group> --name <vm-name> --command-id RunShellScript --scripts "cloud-init status --long"
az vm run-commandsecureCompute
az vm boot-diagnostics get-boot-log --resource-group <resource-group> --name <vm-name>
az vm boot-diagnosticsdiscoverCompute
az vmss update --resource-group <resource-group> --name <vmss-name> --set virtualMachineProfile.osProfile.customData=<base64-value>
az vmssconfigureCompute

Architecture context

Architecturally, custom data is a bootstrap mechanism, not the whole configuration strategy. I use it to point a VM at durable services: package repositories, configuration endpoints, monitoring agents, domain join processes, or application installers. The base image should already contain stable prerequisites, while custom data supplies environment-specific setup that is safe to run on first boot. The architecture should define how the VM reports readiness, where logs go, and what replaces custom data for ongoing changes. In VM Scale Sets, model changes and reimage behavior must be understood because existing instances do not magically rerun new custom data without lifecycle action.

Security

Security impact is direct because custom data often tempts teams to embed passwords, tokens, SSH keys, repository credentials, or connection strings. Do not treat it as encrypted secret storage. Use managed identity, Key Vault, short-lived tokens, or a secure pull pattern instead. Any process with enough guest access may be able to inspect provisioning artifacts, and startup logs can leak command arguments. Also review who can read deployment templates, pipeline variables, and VM model properties. Custom data should be reviewed like code because it can create users, change firewall settings, install agents, and run commands with high privilege during provisioning.

Cost

Custom data has no direct Azure meter, but broken bootstrap automation creates expensive waste. VMs that fail initialization still consume compute until stopped or deleted, and repeated test deployments can create disks, public IPs, logs, and snapshots. Better custom data can reduce manual setup time and prevent configuration drift, but oversized scripts that download large packages on every VM add bandwidth, storage, and startup delay. FinOps owners should watch failed provisioning loops, abandoned test VMs, and scale-set reimages triggered by script changes. Use small disposable tests and clean up resource groups after validating custom-data behavior. Capture evidence before cleanup. Delete failed tests promptly.

Reliability

Reliability depends on custom data being idempotent enough for real operations and conservative enough not to block basic VM readiness. Cloud-init scripts can fail because repositories are unavailable, DNS is not ready, package locks exist, YAML is malformed, or a command assumes internet access that the subnet denies. A VM may show provisioned while application setup is still incomplete, so health checks and logs matter. Reliable patterns keep scripts short, fetch versioned artifacts, retry external calls, write clear logs, and fail safely. For critical fleets, bake stable dependencies into images and use custom data only for final bootstrap. Keep orchestration in deployment tooling.

Performance

Custom data affects startup performance more than steady-state runtime. Long package installs, slow repository mirrors, cross-region downloads, serial script execution, and retries against unavailable endpoints can turn a normal VM deployment into a long wait. If cloud-init continues after Azure reports the VM ready, users may hit a machine before the application is installed. Good designs pre-bake heavy dependencies into images, keep custom data focused, use nearby package sources, and write readiness files or health endpoints. Operators should measure time from VM create to usable application, not just provisioningState, because bootstrap work is often the delay. Test under production-like load.

Operations

Operators inspect custom data indirectly through deployment templates, CLI creation commands, VM model output, cloud-init status, waagent logs, boot diagnostics, run-command checks, and application readiness probes. Common jobs include testing a cloud-init file, confirming a VM used the intended image, checking why first boot failed, and proving whether setup logic or infrastructure caused an outage. Because single-VM custom data is not a convenient post-creation edit path, operators need a rebuild or configuration-management plan. Good runbooks show where the script lives, how it is versioned, and which logs prove it finished. Fresh deployment tests catch drift. Store scripts with release artifacts.

Common mistakes

  • Putting passwords, access tokens, or private keys directly into custom data because it feels convenient during provisioning.
  • Assuming Windows automatically executes custom data without building a process to read and run the file.
  • Changing a VM Scale Set customData value and expecting existing instances to rerun it without model update and reimage planning.
  • Writing a large all-purpose installer script instead of using a hardened image and a small bootstrap step.
  • Treating provisioningState succeeded as proof that cloud-init and application setup completed successfully.