A #cloud-config file reads like a script from top to bottom, but cloud-init does not run it that way. Users and files exist before packages are installed, runcmd runs near the very end, and on the next boot almost nothing runs at all.
Knowing the order explains the usual surprises: a command that runs before its package exists, or a change to user-data that has no effect on a server that already booted.
Explore it
Detect
ds-identifyLocal
cloud-init-local.serviceNetwork
cloud-init-network.servicebootcmdRunswrite_filesRunsusersRunsssh_authorized_keysRuns
Config
cloud-config.serviceruncmdWrites the script
Final
cloud-final.servicepackagesRunsruncmdRunsfinal_messageRuns
First boot: 8 of 8 modules run.
Step by step
Early in boot,
ds-identifychecks which platform the server runs on and enables cloud-init. In the Local stage (cloud-init-local.service) cloud-init finds the local datasource, reads the instance ID and, on a first boot, writes the network configuration before the network comes up.Once the network is up, the Network stage (
cloud-init-network.service) processes the user-data and runs the first modules:bootcmd,write_files,usersand the SSH keys. Your user and its key exist from here on.The Config stage (
cloud-config.service) runs the configuration modules.runcmdis one of them, but it only writes your commands to a script; nothing in it runs yet.The Final stage (
cloud-final.service) runs last in boot. It installspackages, thenscripts_userruns theruncmdscript, and the final message is logged. A command inruncmdcan rely on the packages being installed.On a reboot the instance ID matches the cached one, so it is not a first boot. Modules that run once per instance (users, files, packages,
runcmd) are skipped; only per-boot modules such asbootcmdrun again. Editing user-data on a running server changes nothing until a new instance boots orcloud-init cleanresets the cache.
Example values The modules shown are the defaults of Ubuntu's cloud.cfg; other distributions can order them differently.
What the diagram shows
The diagram is a timeline of the five boot stages, Detect, Local, Network, Config and Final, each with its systemd unit and the modules it runs for the user-data keys bootcmd, write_files, users, ssh_authorized_keys, runcmd, packages and final_message. The current stage is highlighted.
A control switches between the first boot and a later boot of the same instance. On a later boot, every module that runs once per instance is marked "skipped"; bootcmd and final_message still run.
Try it in the tool
What this does not cover
Older cloud-init versions name the Network stage's unit cloud-init.service. Boothooks, vendor-data and part-handlers are left out, and manual_cache_clean changes how a first boot is detected.
Related pages
Sources
How ANAROQ sources its data and numbers is described in the methodology. Read the methodology