Setting up Cloud Init Ubuntu Image on Proxmox
This post shows a compact, repeatable flow for creating a Cloud-Init based Ubuntu template in Proxmox so you can spin up configured VMs quickly.
Quick run: download an Ubuntu cloud image, import it into Proxmox, add a Cloud-Init drive, set boot order, convert to a template, then clone.
You will need:
- A Proxmox VE host with LVM (or other writable storage like
local-lvm) - SSH or shell access to your Proxmox host
- A public SSH key (for injecting into cloud-init)
Quick checklist
- Download cloud image
- Create a small VM (temporary)
- Import disk, attach to VM
- Add cloud-init drive and configure user/ssh
- Convert VM to template
- Clone when needed
Step-by-step
1) Download the Ubuntu cloud image
Choose the release you prefer and download the cloud image. Example (Focal):
wget https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64.img
2) Create a temporary VM to attach the image to
Adjust memory and CPU to taste — this VM will become the template.
qm create 8000 --memory 2048 --core 2 --name ubuntu-cloud --net0 virtio,bridge=vmbr0
3) Import the cloud image into storage
Import the downloaded image into a Proxmox storage pool (example uses local-lvm):
qm importdisk 8000 focal-server-cloudimg-amd64.img local-lvm
4) Attach the imported disk to the VM (SCSI recommended)
qm set 8000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-8000-disk-0
5) Add the Cloud-Init drive
qm set 8000 --ide2 local-lvm:cloudinit
6) Make the VM boot from the disk
qm set 8000 --boot c --bootdisk scsi0
7) Add a serial console (optional, helpful for headless debugging)
qm set 8000 --serial0 socket --vga serial0
Warning — do not start the VM yet. Configure cloud-init and hardware first. Starting too early can record IDs/state you may not want in your template.
8) Configure Cloud-Init fields (hostname, user, SSH key)
You can set these with the GUI or via qm set. Example CLI:
qm set 8000 --ciuser ubuntu --sshkey "$(cat ~/.ssh/id_rsa.pub)"
qm set 8000 --citype nocloud
If you want to provide a full user-data/meta-data payload for NoCloud, you can supply files or use Proxmox GUI fields.
9) Convert the VM to a template
qm template 8000
10) Clone the template whenever you need a new VM
qm clone 8000 135 --name yoshi
Tips
- Resize disks after cloning if you need per-VM different sizes; keep the template small.
- Put idempotent provisioning (Ansible, cloud-init modules) in the guest rather than baking many steps into the template.
Troubleshooting
If you accidentally booted a template (or need a fresh machine-id inside a guest):
sudo rm -f /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
Shutdown the VM and do not boot it; a new id will be generated on next boot. If it’s not generated automatically, run:
sudo systemd-machine-id-setup
If cloud-init doesn’t apply after cloning, verify the cloud-init datasource type and that Proxmox’s cloud-init fields are populated correctly for the new host.
Key Takeaways
- Cloud-init templates save hours per VM when you deploy regularly
- Never start a VM before configuring cloud-init — booting early bakes state into the template
- Keep the template minimal; use idempotent provisioning (Ansible, cloud-init modules) for post-clone customization
- Always use SCSI for the imported disk for performance
- Reset machine-id after cloning if cloud-init doesn’t apply correctly
Next
- The Proxmox Utility Toolkit — tools and scripts for VM management, backups, and automation on Proxmox
- Homelab Ops Series: API Key Management for Automated Provisioning — managing credentials homelab automation without scattered secrets