Proxmox VM Template and Clone
Build an Ubuntu cloud-init template once, clone it into new VMs in seconds, resize the disk, and configure each VM with Ansible.
Documentation: Proxmox Cloud-Init Support · qm(1)
Goal #
qm clone produces a running Ubuntu VM with your user, SSH key, hostname and IP set automatically, ready for an Ansible run.
Prerequisites #
- A Proxmox VE node with a storage that holds VM disks (
local-lvmbelow) and a bridge (vmbr0) (Proxmox VE Overview and Install, Proxmox Storage) - Shell access on the node (
root), and an SSH key on your workstation - Free VMIDs:
9000for the template,120for the first clone - For the guest agent:
libguestfs-toolson the node (apt install libguestfs-tools) if you customise the image
Steps #
1. Download and prepare the image #
cd /var/lib/vz/template
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
sudo virt-customize -a noble-server-cloudimg-amd64.img --install qemu-guest-agentSkip virt-customize if you install the agent through cloud-init user-data instead (Proxmox Cloud-Init Templates).
2. Create the template VM #
qm create 9000 --name ubuntu-2404-template --memory 2048 --cores 2 \
--net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci --ostype l26
qm set 9000 --scsi0 local-lvm:0,import-from=/var/lib/vz/template/noble-server-cloudimg-amd64.img
qm set 9000 --ide2 local-lvm:cloudinit
qm set 9000 --boot order=scsi0
qm set 9000 --serial0 socket --vga serial0
qm set 9000 --agent enabled=1--scsi0 <STORAGE>:0,import-from= imports the image in one step on current Proxmox VE. On older releases use qm importdisk and attach the resulting disk (Proxmox qm and pct).
3. Set the cloud-init defaults and convert to a template #
qm set 9000 --ciuser <USER> --sshkeys ~/.ssh/id_ed25519.pub
qm set 9000 --ipconfig0 ip=dhcp
qm template 9000--sshkeys takes a path to a file on the node: copy your public key there first. Avoid --cipassword; use keys.
4. Clone #
qm clone 9000 120 --name web01 --full
qm set 120 --ipconfig0 ip=192.0.2.120/24,gw=192.0.2.1 --nameserver 192.0.2.53 --searchdomain example.com
qm set 120 --memory 4096 --cores 4--full makes an independent copy. Without it you get a fast linked clone that depends on the template and cannot be removed while clones exist.
5. Resize the disk, then start #
qm disk resize 120 scsi0 +30G
qm start 120The cloud image grows its root partition and filesystem on first boot (growpart). The disk can only grow, never shrink.
6. Check the guest #
qm agent 120 ping # exits 0 once the guest agent responds
qm guest cmd 120 network-get-interfaces # IPs reported by the guest
ssh <USER>@192.0.2.120
df -h /After changing cloud-init values on an existing clone run qm cloudinit update 120 (the guest applies them only on the next boot of a fresh instance). qm cloudinit dump 120 user shows what the guest receives.
7. Provision with Ansible #
Inventory inventory.ini:
[web]
web01 ansible_host=192.0.2.120 ansible_user=<USER>ansible -i inventory.ini web -m ping
ansible-playbook -i inventory.ini site.yml --check --diff
ansible-playbook -i inventory.ini site.ymlApply the hardening steps from New Server Checklist as a role, so every clone ends up identical (Ansible Cheat-Sheet, Ansible-Playbook Cheat-Sheet).
8. Optional: back up and protect #
Add the VM to a backup job (vzdump) and start it on boot: qm set 120 --onboot 1 (Proxmox Backup and Restore). Allow only the needed ports in Proxmox Firewall.
Verify #
qm status 120 # status: running
qm config 120 | grep -E 'scsi0|ipconfig0|agent'
ssh <USER>@192.0.2.120 'hostname; lsblk; cloud-init status'cloud-init status should report done. Check the logs in /var/log/cloud-init.log if not.
Rollback / Cleanup #
- Remove a clone:
qm stop 120 && qm destroy 120 --purge. - Rebuild the template: remove it with
qm destroy 9000(only after all linked clones are gone) and repeat steps 1 to 3. - Delete the downloaded image:
rm /var/lib/vz/template/noble-server-cloudimg-amd64.img. - Clones that all share one template SSH key and machine-id behave oddly if you boot the template itself before converting it. Never start the template before
qm template.
Related Sheets #
- Proxmox Cloud-Init Templates · Proxmox qm and pct · Proxmox Storage · Proxmox Networking
- Proxmox Backup and Restore · Proxmox Firewall · Proxmox Troubleshooting and One-Liners · Proxmox VE Overview and Install
- Ansible Cheat-Sheet · Ansible-Playbook Cheat-Sheet · Terraform · OpenSSH Cheat-Sheet
- New Server Checklist · K3s Cluster from Scratch
- Backup Strategy · VLANs · Bash · CI/CD Overview