Post

Creating a Custom Ubuntu Template in Proxmox with Cloud-Init

Creating a Custom Ubuntu Template in Proxmox with Cloud-Init

Table of Contents

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:

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:

  1. Navigate to your VM in the Proxmox web UI
  2. Select the “Cloud-Init” tab
  3. 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

  1. 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
  2. Network issues after deployment:
    • Verify network bridge configuration in Proxmox
    • Check Cloud-Init network settings match your infrastructure
  3. SSH key authentication fails:
    • Verify the public key format is correct
    • Check permissions on /home/user/.ssh directory in the VM
  4. 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

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.

This post is licensed under CC BY 4.0 by the author.