runcmd and package order in Cloud-Init

Published: (December 7, 2025 at 07:45 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Question

How can a command specified in runcmd be executed before its related package is installed via the packages module in Cloud‑Init? Which module runs first?

Example

#cloud-config
package_update: true
package_upgrade: true

runcmd:
  - systemctl enable --now qemu-guest-agent.service

packages:
  - qemu-guest-agent

This pattern is common when provisioning VMs (e.g., with Terraform’s libvirt provider on QEMU/KVM). The runcmd entry tries to enable and start qemu-guest-agent.service even though the qemu-guest-agent package has not yet been installed. The guest agent is often needed early so that tools such as Ansible’s dynamic inventory can query host information.

Why it works

The confusion stems from the way Cloud‑Init’s module stages are documented:

  • Config stage – where runcmd is listed.
  • Final stage – where packages are installed and the scripts_user module runs.

Although runcmd appears in the Config stage, the commands under runcmd are not executed immediately. Cloud‑Init treats the runcmd list as a set of scripts that are scheduled to run later, specifically by the scripts_user module in the Final stage.

Consequently, the execution order is:

  1. Package installation (packages module) – Final stage.
  2. User scripts (scripts_user module) – Final stage, which runs the commands from runcmd.

By the time scripts_user executes the systemctl enable --now qemu-guest-agent.service command, the qemu-guest-agent package has already been installed, the service file exists, and the command succeeds.

Back to Blog

Related posts

Read more »