How cloud-init runs on the first boot

cloud-init applies your user-data in five boot stages, and most of it only once per instance. Step through the stages, see where each key of a #cloud-config runs, and what runs again after a reboot.

Published 13 October 2026

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

Boot
cloud-init boot stages Example values
  1. Detect ds-identify

    No user-data modules

  2. Local cloud-init-local.service

    No user-data modules

  3. Network cloud-init-network.service

    • bootcmd Runs bootcmd, every boot
    • write_files Runs write_files, once per instance
    • users Runs users_groups, once per instance
    • ssh_authorized_keys Runs ssh, once per instance
  4. Config cloud-config.service

    • runcmd Writes the script runcmd, once per instance
  5. Final cloud-final.service

    • packages Runs package_update_upgrade_install, once per instance
    • runcmd Runs scripts_user, once per instance
    • final_message Runs final_message, every boot

First boot: 8 of 8 modules run.

Step by step

  1. Early in boot, ds-identify checks 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.

  2. Once the network is up, the Network stage (cloud-init-network.service) processes the user-data and runs the first modules: bootcmd, write_files, users and the SSH keys. Your user and its key exist from here on.

  3. The Config stage (cloud-config.service) runs the configuration modules. runcmd is one of them, but it only writes your commands to a script; nothing in it runs yet.

  4. The Final stage (cloud-final.service) runs last in boot. It installs packages, then scripts_user runs the runcmd script, and the final message is logged. A command in runcmd can rely on the packages being installed.

  5. 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 as bootcmd run again. Editing user-data on a running server changes nothing until a new instance boots or cloud-init clean resets 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

Open cloud-init Generator for Ubuntu 24.04

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.

Sources

How ANAROQ sources its data and numbers is described in the methodology. Read the methodology

All explainers