cloud-init and first-boot configuration
Coming from another cloud?
▸AWS·EC2 User Data
This Quake AI feature maps to AWS’s EC2 User Data.
▸Azure·Custom Data
This Quake AI feature maps to Azure’s Custom Data.
▸DigitalOcean·User Data
This Quake AI feature maps to DigitalOcean’s User Data.
▸Google Cloud·Startup Scripts
This Quake AI feature maps to Google Cloud’s Startup Scripts.
▸Hetzner·Cloud Init
This Quake AI feature maps to Hetzner’s Cloud Init.
cloud-init and first-boot configuration
cloud-init is the industry-standard first-boot agent that runs inside Linux and BSD guests. When you launch an instance, Compute (OpenStack Nova) passes user data to the guest. cloud-init reads that payload on the first boot and applies packages, users, files, and commands you declared.
Run once on first boot#
cloud-init divides work into stages (for example init, config, and final). Modules run during those stages on the first boot of a new instance ID. A normal reboot does not re-run the full first-boot pipeline.
That one-shot model is the most common support question: editing user data on a stopped instance does not retroactively change a guest that already booted. To apply new user data, create a new instance from an image or snapshot, or use configuration management after boot.
Instances record completion in /var/lib/cloud/instance/ and expose status through cloud-init status. See How to configure a VM with cloud-init for debugging commands and log paths.
User-data formats#
Nova stores the payload you supply at launch. cloud-init detects the format from headers and MIME structure.
| Format | When to use it |
|---|---|
cloud-config (#cloud-config YAML) | Declarative modules: users, packages, write_files, runcmd. Preferred for multi-step baselines. |
Shell script (#!/bin/bash or #!/bin/sh) | Imperative steps when you want a single script with full shell control. |
| MIME multipart | Combine cloud-config, scripts, and static files in one launch payload. Common in Heat and Terraform user_data templates. |
cloud-config is not a general-purpose programming language. Keep complex logic in runcmd scripts or in tools you install on the guest.
How Compute delivers user data#
On Quake AI, user data travels through the same Nova field regardless of how you launch the instance:
- Console: System Config > Advanced Options > User Data in the Create Instance wizard
- CLI:
openstack server create --user-data FILE - API:
user_dataon the server create request (base64-encoded) - OpenTofu / Heat:
user_dataon the compute resource or HeatOS::Nova::Serverproperty
The platform does not validate YAML or shell syntax before launch. Syntax errors surface in guest logs after boot.
First boot vs ongoing configuration#
| Approach | Runs when | Best for |
|---|---|---|
| cloud-init user data | First boot of a new instance | Baseline users, packages, hostname, one-time bootstrap |
| Configuration management (Ansible modules, Salt, etc.) | On demand or on a schedule | Drift correction, role-based config across fleets |
| Golden images (Packer how-to) | At image build time | Standard AMIs or images with software pre-baked |
cloud-init specializes a generic image at launch. Ansible or golden images specialize guests after launch or before you ever create an instance. Many production workflows combine them: cloud-init for bootstrap, Ansible or images for the steady state.
Related procedures#
- How to configure a VM with cloud-init: write user data, pass it from each launch method, debug failures
- How to provision a production-ready VM: end-to-end launch workflow that includes a minimal cloud-init block
- How to use the virtual machine console: serial console access when SSH is not ready
Quick answers
- Why does `openstack image save` write a 0-byte file for my boot-from-volume instance?CLI
- Why does `openstack server create` fail with "Only volume-backed servers are allowed for flavors with zero disk"?CLIAPITerraform
- Why does my project still have a 10 GiB Cinder volume after I deleted my instance?CLIAPI
Related content
Pages
Explanations
deployment