Creating a Custom Ubuntu Template in Proxmox with Cloud-Init
Table of Contents
- Introduction
- Prerequisites
- Downloading the Ubuntu Cloud Image
- Creating the Virtual Machine
- Importing the Cloud Image
- Configuring Disk and Cloud-Init
- Boot Setup
- Initial VM Customization
- Cloud-Init Configuration
- Creating the Template
- Deploying VMs from the Template
- Troubleshooting
- Conclusion
Introduction
This guide details how to create a custom Ubuntu template in Proxmox Virtual Environment (PVE) using Cloud-Init for automated VM provisioning. By leveraging Cloud-Init, you can preconfigure settings like username, password, SSH keys, and network configuration, making deployment of new VMs fast and consistent.
Prerequisites
- Proxmox VE 8.0 or newer installed
- SSH access to your Proxmox host or access to the web UI
- Sufficient storage space for template creation
- Internet access to download Ubuntu cloud images
Downloading the Ubuntu Cloud Image
First, download the official Ubuntu cloud image to your Proxmox host:
1
2
3
4
5
6
7
8
# Access your Proxmox host via SSH
ssh root@your-proxmox-host
# Navigate to a temporary directory
cd /tmp
# Download the Ubuntu cloud image (for Ubuntu 24.04)
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
You can replace the URL with your preferred Ubuntu version. For other versions, visit the Ubuntu Cloud Images page.
Creating the Virtual Machine
Create a new VM in Proxmox with appropriate resources. This example uses VM ID 9000, but you can choose any unused ID:
1
2
3
4
5
6
qm create 9000 \
--name ubuntu-cloud-template \
--memory 2048 \
--cores 2 \
--net0 virtio,bridge=vmbr0 \
--description "Ubuntu Cloud Template with Cloud-Init"
Parameter explanation:
--name: Descriptive name for your template--memory: RAM allocation in MB (2GB in this example)--cores: Number of CPU cores--net0: Network interface configuration using virtio driver and vmbr0 bridge--description: Optional description for documentation
Importing the Cloud Image
Import the downloaded cloud image to your VM’s storage:
1
2
# Replace 'local-lvm' with your preferred storage location
qm importdisk 9000 /tmp/noble-server-cloudimg-amd64.img local-lvm
qm importdisk 9000: Specifies that we’re importing a disk to VM ID 9000.ubuntu-24.04-server-cloudimg-amd64.img: The path to your downloaded Ubuntu cloud image. Replace with the actual path.local-lvm: Specifies that the disk should be stored on the local LVM storage. Adjust if using a different storage type.
Configuring Disk and Cloud-Init
Configure the VM’s disk and add Cloud-Init drive:
1
2
3
4
5
6
7
8
9
10
11
# Attach the imported disk to SCSI controller
qm set 9000 --scsihw virtio-scsi-single --scsi0 local-lvm:vm-9000-disk-0
# Resize the disk to 20GB (adjust as needed)
qm resize 9000 scsi0 20G
# Add Cloud-Init CD-ROM drive
qm set 9000 --ide2 local-lvm:cloudinit
# Enable QEMU guest agent
qm set 9000 --agent enabled=1
The QEMU guest agent provides better integration between the host and guest VM, allowing for more accurate VM status reporting and clean shutdowns.
Boot Setup
Configure the boot order and console settings:
1
2
3
4
5
# Set boot from hard disk (SCSI0)
qm set 9000 --boot c --bootdisk scsi0
# Configure serial console
qm set 9000 --serial0 socket --vga serial0
Initial VM Customization
At this point, you have two options:
Option 1: Minimal Template (Recommended)
Create a minimal template without booting the VM first:
1
2
3
4
5
# Set a higher CPU and memory limit for the template
qm set 9000 --cpu host --machine q35 --ostype l26
# Enable hot-plugging features
qm set 9000 --hotplug disk,network,usb,memory,cpu
Option 2: Boot and Customize the VM
If you need to perform additional customization:
1
2
3
4
5
# Start the VM
qm start 9000
# Access the VM console
qm terminal 9000
After customizations are complete, shut down the VM:
1
2
3
4
5
# From within the VM
sudo shutdown -h now
# Or from Proxmox host
qm shutdown 9000
Cloud-Init Configuration
Configure Cloud-Init settings via the Proxmox web UI:
- Navigate to your VM in the Proxmox web UI
- Select the “Cloud-Init” tab
- Configure:
- User: Default username (e.g., “ubuntu”)
- Password: Default password
- SSH Keys: Your public SSH key for passwordless access
- IP Configuration: Choose DHCP or set static IP
- DNS Domain: Set your domain
- DNS Servers: Set your preferred DNS servers
Alternatively, configure via command line:
1
2
3
4
5
6
7
8
9
10
# Set Cloud-Init user, password and SSH key
qm set 9000 --ciuser ubuntu
qm set 9000 --cipassword "your-secure-password"
qm set 9000 --sshkeys /path/to/your/public_key.pub
# Set Cloud-Init network configuration (DHCP)
qm set 9000 --ipconfig0 ip=dhcp
# Or set static IP
# qm set 9000 --ipconfig0 ip=192.168.1.100/24,gw=192.168.1.1
Creating the Template
Once you’ve configured the VM to your liking, convert it to a template:
1
qm template 9000
Deploying VMs from the Template
To create a new VM from your template:
1
2
3
4
5
6
7
8
9
10
# Clone the template to a new VM with ID 101
qm clone 9000 101 --name ubuntu-vm-01 --full
# Customize Cloud-Init for the new VM if needed
qm set 101 --ciuser customuser
qm set 101 --cipassword "another-secure-password"
qm set 101 --ipconfig0 ip=192.168.1.101/24,gw=192.168.1.1
# Start the new VM
qm start 101
Troubleshooting
Common Issues and Solutions
- Cloud-Init not applying settings:
- Ensure the QEMU guest agent is installed in the template
- Check cloud-init logs in the VM with
cat /var/log/cloud-init.log
- Network issues after deployment:
- Verify network bridge configuration in Proxmox
- Check Cloud-Init network settings match your infrastructure
- SSH key authentication fails:
- Verify the public key format is correct
- Check permissions on
/home/user/.sshdirectory in the VM
- Slow boot times:
- Add
qm set 9000 --cicustom "vendor=local:snippets/nocloud-vendor-data.yaml"with a custom vendor data file to disable certain time-consuming cloud-init modules
- Add
Conclusion
You now have a reusable Ubuntu template with Cloud-Init in Proxmox VE that can be quickly cloned to deploy new VMs with customized configurations. This approach significantly reduces deployment time and ensures consistency across your virtual infrastructure.
For more advanced usage, explore cloud-config files and custom user-data scripts to further automate VM provisioning according to your specific requirements.