Skip to content

Cloud Init PVE

cloud-init-pve implements the functionality of cloud-init, but focused on the configuration that Proxmox Virtual Environment makes available. It also tries to limit the impact of changes to the configuration after initial setup — for example, when updating the password, or changing the IP address of a VM.

It runs inside the guest and reads the same NoCloud config drive (the cidata volume, containing user-data and network-config) that real cloud-init would, so it works with any VM Proxmox generates cloud-init data for — no qm access from inside the guest required.

See Configuration for the /etc/cloud-init-pve.yaml file that controls which parts of the cloud-init data are applied and how, Cloud-Init Data for exactly which cloud-init fields are recognized, Backends for what the built-in backends do and how to write a custom one, and Running via systemd for example units and how boot-time and network-dependent config are split.

Quick start

Download a release for Linux/amd64 — currently the only platform built — from Releases:

  • .deb: apt install ./cloud-init-pve-<version>-amd64.deb. Everything the builtin backends shell out to (useradd, chpasswd, mount, apt-get, systemd) is already part of a base Debian install, so there is nothing further to install. This also installs the example systemd units (see Running via systemd) to /lib/systemd/system/ and enables them, without starting them.
  • .tar.gz: a plain binary — extract it onto $PATH yourself.

Or build from source (Go 1.26+): go build ./cmd/cloud-init-pve.

Run it as root (creating users, mounting the config drive, and writing network/systemd config all require it):

cloud-init-pve

With no arguments it reads /etc/cloud-init-pve.yaml (or applies the documented defaults if that file doesn't exist), locates and mounts the cloud-init config drive, applies the configured backends, and records what it applied to /var/lib/cloud-init-pve/cloud-init-data.yaml so the next run can tell what changed. If there's no cloud-init config drive attached at all, this is a no-op, not an error.

Use -config / -state to point at different paths:

cloud-init-pve -config /etc/cloud-init-pve.yaml -state /var/lib/cloud-init-pve/cloud-init-data.yaml

Running it by hand like this does everything in one call — network, FQDN, users, and (on the first boot) the package upgrade. To run it automatically at boot, see Running via systemd: the package upgrade needs a working network, so it's normally split into its own -stage=final invocation ordered after the network actually comes up, separate from the -stage=boot invocation that runs everything else as early as possible.