Proxmox VM Template

- 3 mins read

Launching virtual machined from cloud images is not convenient (infact I couldn’t find the right options from the web-ui) from the Proxmox web-ui. The same is possible using the qm command in Proxmox. Lot of references are available online, one of which I have followed (link provided in the references section). It is convenient to use the same approach every time and hence I have documented it in this blog for reference in future, saving myself from starting from scratch and doing the same search and landing with different results every time.

Download Image

Download the latest Ubuntu 24.04 cloud image:

wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img

Setup Environment Variables

Setup the following environment variables in a file named cloud-init.sh.

# Specifies the username to be created using Cloud-init.
export CLOUD_INIT_USER="testuser"

# Provides the path to the SSH public key for the user.
export CLOUD_INIT_SSHKEY="/home/abhi/.ssh/id_rsa.pub"

export CLOUD_INIT_IP="dhcp"
#export CLOUD_INIT_NAMESERVER="1.1.1.1"
#export CLOUD_INIT_SEARCHDOMAIN="example.com"

Setup the following environment variables related to the VM configuration in a file named vm-config.sh.

# Specifies the CPU model to be used for the VM according your environment and the desired CPU capabilities
export QEMU_CPU_MODEL="host".
export VM_CPU_SOCKETS=1
export VM_CPU_CORES=2
export VM_MEMORY=4098
# Assigns the VM to a specific resource pool for management.
#export VM_RESOURCE_POOL="CustomResourcePool" # Assigns the VM to a specific resource pool for management.

Create a file named template-config.sh with the following environment variables:

export IMAGES_PATH="/root"
export IMAGE_NAME="noble-server-cloudimg-amd64.img"
export TEMPLATE_ID=9002
export VM_NAME="ubuntu-24.04"
export VM_DISK_IMAGE="${IMAGES_PATH}/${IMAGE_NAME}"

Script for the creation of the VM

Execute the following script to create a VM as base for the template.

# Create VM. Change the cpu model
qm create ${TEMPLATE_ID} \
--name ${VM_NAME} \
--cpu ${QEMU_CPU_MODEL} \
--sockets ${VM_CPU_SOCKETS} \
--cores ${VM_CPU_CORES} \
--memory ${VM_MEMORY} \
--numa 1 \
--net0 virtio,bridge=vmbr0 \
--ostype l26 \
--agent 1 \
#--pool ${VM_RESOURCE_POOL} \
--scsihw virtio-scsi-single

# Import Disk
qm set ${TEMPLATE_ID} --scsi0 local-lvm:0,import-from=${VM_DISK_IMAGE}

# Add Cloud-Init CD-ROM drive. This enables the VM to receive customization instructions during boot.
qm set ${TEMPLATE_ID} --ide2 local-lvm:cloudinit --boot order=scsi0

# Cloud-init network-data
qm set ${TEMPLATE_ID} --ipconfig0 ip=${CLOUD_INIT_IP} #--nameserver ${CLOUD_INIT_NAMESERVER} --searchdomain ${CLOUD_INIT_SEARCHDOMAIN}

# Cloud-init user-data
qm set ${TEMPLATE_ID} --ciupgrade 1 --ciuser ${CLOUD_INIT_USER} --sshkeys ${CLOUD_INIT_SSHKEY}

# Cloud-init regenerate ISO image, ensuring that the VM will properly initialize with the desired parameters.
qm cloudinit update ${TEMPLATE_ID}

Convert the VM to a template

qm set ${TEMPLATE_ID} --name "${VM_NAME}-Template"
qm template ${TEMPLATE_ID}

After this it is convenient to use the web-ui of proxmox to clone the template to create a VM. For command line the following commands achieve the same:

export VM_ID=$(pvesh get /cluster/nextid)
qm clone ${TEMPLATE_ID} ${VM_ID}  --name ${VM_NAME}
qm start ${VM_ID}

Next target is to create an ansible script to automate this task.

Reference: