Proxmox VEIX · Virtual MachinesProvisioning
Cloud-Init, templates, and clones
What you'll learn
- Configure a VM as a Cloud-Init template
- Generate linked clones vs full clones based on use case
- Customise instances at first boot via Cloud-Init
- Manage the template lifecycle
Prerequisites
Verified against Proxmox VE 9.2.4 · Proxmox Backup Server 4.2.5 · Ceph Squid / Tentacle · Debian 13 (Trixie) · Linux kernel 7.0 (PVE 9.2 default) · 2026-08-07
Why this matters in production
Manually installing 30 VMs is not feasible. Cloud-Init + templates lets you provision VMs consistently at scale.
The pattern
flowchart LR
A[Install base OS in VM] --> B[Customise: packages, config]
B --> C[Install cloud-init guest]
C --> D[Clean up & convert to template]
D --> E[Template]
E --> F[Clone for each instance]
F --> G[Customise on first boot]
Step 1: Create a base VM
Install a base OS in a VM exactly as you would for a single instance. Apply your standard configuration: packages, users, security settings.
Step 2: Install the Cloud-Init guest
In the base VM:
apt update && apt install -y cloud-init qemu-guest-agent
dnf install -y cloud-init qemu-guest-agent
For Windows, install cloudbase-init.
Step 3: Clean up
Before converting to a template, remove machine-specific data:
cloud-init clean --logs --seed
rm -f /etc/ssh/ssh_host_*
rm -f /var/lib/dhcp/*
history -c && shutdown -h now
Step 4: Convert to a template
In the GUI: right-click the VM → “Convert to Template”. CLI:
qm template 9000
Step 5: Clone instances
GUI: right-click the template → Clone. CLI:
qm clone 9000 100 --name web-01 --full 1
qm clone 9000 101 --name web-02 --full 0
| Clone type | Storage | Speed | Use |
|---|---|---|---|
| Full | Independent copy | Slow (copies data) | Production VMs that may diverge significantly |
| Linked | Snapshot-based delta | Fast (instant) | Disposable, dev, fast scaling |
Step 6: Customise on first boot
Proxmox passes Cloud-Init configuration to the VM at boot:
qm set 101 --ciuser admin --cipassword <hash> --sshkeys /root/.ssh/id_rsa.pub --ipconfig0 ip=10.10.100.50/24,gw=10.10.100.1 --searchdomain lab.example.com --nameserver 10.10.10.1
qm cloudinit update 101 && qm start 101
Common Cloud-Init parameters:
| Parameter | Purpose |
|---|---|
ciuser | Default user to create |
cipassword | (Hashed) password |
sshkeys | SSH public keys |
ipconfig0 | Static IP / gateway |
searchdomain | DNS search domain |
nameserver | DNS server |
cicustom | Custom Cloud-Init script (meta, user, vendor) |
Production considerations
Common mistakes
- Storing plaintext passwords in Cloud-Init configuration.
- Modifying a template after conversion (it’s locked).
- Deleting the base disk of a template with linked clones.
- Forgetting to install cloud-init in the base VM.
Key takeaways
- Templates + Cloud-Init is the production way to provision at scale.
- Use
mkpasswd --method=SHA-512for password hashes. - Linked clones share storage with the template; full clones are independent.
Knowledge check
Knowledge check · 3 questions
Q1. Which command converts a VM to a template?
Q2. A linked clone keeps reading from the template base disk, so the template cannot be removed while clones of it exist.
Q3. Which command generates a password hash suitable for cipassword?
Passing score: 75%. Answers are checked in this browser.