When deploying virtual machines (VMs) in Azure, the last thing you want is to SSH in manually every time to configure packages, users, and services. This is where CloudInit steps in — enabling zero-touch provisioning of VMs through declarative configuration. In this post, we’ll explore what CloudInit is, how it works in Azure, and how to integrate it with Bicep to automate deployments.
What is CloudInit?
CloudInit is an industry-standard method of automating the initial configuration of Linux VMs. It allows you to:
- Install packages
- Configure users and SSH keys
- Set up disk mounts
- Write configuration files
- Run scripts at first boot
This eliminates the need for post-deployment scripts or manual SSH configuration, especially in large-scale environments. If you want to find out more information you can check the official Microsoft Docs Here
For a deeper dive into the CloudInit configuration format, see the official documentation on cloud-config-data.
Why Use CloudInit in Azure?
Azure supports CloudInit natively for most Linux distributions. That means you can provide a customData
field at deployment time containing your CloudInit YAML. Azure injects this into the VM at boot time, where the Linux guest agent processes and applies it.
Benefits:
- Repeatable Deployments – Same config every time
- Zero-Touch – No manual post-deployment steps
- Security – Avoids passing secrets via shell scripts
- Scalability – Ideal for scaling out fleets of VMs
Using CloudInit with Bicep
For those who want a ready-made example you can check out the virtualMachineCloudInit folder
To use CloudInit in Bicep, you need to add the value customData
to the Virtual Machine module.
|
|
Once defined in the module, there are two methods of providing the CloudInit value: using an external YAML file or defining it inline within the Bicep file. Choose the method that best fits your workflow and version control needs.
Method One: External File
Use this method if you want to keep your CloudInit configuration separate from your Bicep code, which can make versioning and reuse easier.
|
|
Method Two: Inline CloudInit
Use this method for quick prototyping or when you want the configuration to be self-contained within the Bicep file.
|
|
Test and Validate
To troubleshoot or test CloudInit deployments:
Review logs at /var/log/cloud-init.log
and /var/log/cloud-init-output.log
Use SSH to verify file creation and service status
Use Azure Serial Console if boot fails
Final Thoughts
CloudInit is a game-changer for zero-touch VM provisioning in Azure. When paired with Bicep, it becomes a powerful part of your Infrastructure-as-Code toolkit — simplifying, scaling, and securing your deployments.
Whether you’re spinning up test environments or deploying hardened production Linux VMs, CloudInit helps ensure your infrastructure starts life exactly how you intend.