How to automate provisioning in Proxmox Using Cloud images

How to automate provisioning in Proxmox Using Cloud images

There are many ways to create virtual machines. In this article, we aim to leverage cloud images as our primary method for automation while provisioning on Proxmox.

Cloud Images

Cloud images are pre-configured disk images designed to be used in virtualized environments, such as cloud infrastructure or virtual machine hosts. These images include minimal operating system installation and are optimized for quick deployment and scalability. They have support for quick configuration tools, we will be using cloud-init for our example.

Script

You’ll need a Proxmox Virtual Environment node with SSH access. In our script, we will perform some actions to download and prepare a cloud image.

Variable and packages
First, we set up some variables and install some useful packages we will be using in the script.

### variables
VM_TEMPLATE_ID=999
TEMPLATE_NAME=‘ubuntu-2204-template’
UBUNTU_IMAGE=‘ubuntu-22.04-server-cloudimg-amd64-disk-kvm.img’
UBUNTU_IMAGE_QCOW2=‘ubuntu-22.04.qcow2’
USERNAME=‘cap’
PASSWORD=‘12345’
MEMORY=‘4096’
CPUS=‘2’

apt update -y && apt install nano wget curl libguestfs-tools -y

Idempotency
Run a couple of commands to make our script idempotent. We want a quick way of iteration, so we will be deleting the template in case of changes.

# remove old image
rm -rfv ${UBUNTU_IMAGE}

# remove old template container – WILL DESTROY COMPLETELY
qm destroy ${VM_TEMPLATE_ID} –destroy-unreferenced-disks 1 –purge 1

Download the image:

# download new image
wget http://cloud-images.ubuntu.com/releases/22.04/release/${UBUNTU_IMAGE}

Customize the image
Add the QEMU guest agent to the image so we don’t need to install it later. Here, you can use virt-customize to add other tools and have them pre-installed on the image.

virt-customize -a ${UBUNTU_IMAGE} –install qemu-guest-agent

QEMU guest agent is a daemon installed in the guest and helps us get information about our VMs in the Proxmox environment. See more documentation on PVE docs.

Change image extension
Change the img extension on the image file to QCOW2, if you don’t rename it in some versions of proxmox qemu will not work

mv ${UBUNTU_IMAGE} ${UBUNTU_IMAGE_QCOW2}

Resize
Now we resize the image to a generic size. It doesn’t really matter now; we will configure each clone based on the template later.

Create the vm

Again, the values for resources here are not really important. Set up a generic value for memory and CPU. We are setting up a network interface. Another key configuration is the storage controller; we use virtio-scsi as it covers more use cases. To learn more about virtualization of ‘physical’ devices on the virtio family and emulated storage controllers of the virtio family, go to Virtio

qm create ${VM_TEMPLATE_ID} –memory ${MEMORY} –cores ${CPUS} –net0 virtio,bridge=vmbr0 –name ${TEMPLATE_NAME} –scsihw virtio-scsi-pci

After creating the vm we need to configure and convert to a template, so it can be cloned.

Configure the vm

We will perform in order the following configuration:

Import the image to a disk and attach to the vm
attach a cloud-init drive to the vm via ide interface
Configuring vga output for the console on serial0
Setting up dhcp for the network so we have connection
enabling the qemu agent
seting default user and password
adding ssh keys so we can have ssh access, it will use the same ssh keys from the host in witch you will be executing the script

qm set ${VM_TEMPLATE_ID} –scsi0 local-lvm:0,import-from=/root/${UBUNTU_IMAGE_QCOW2}
qm set ${VM_TEMPLATE_ID} –ide2 local-lvm:cloudinit
qm set ${VM_TEMPLATE_ID} –boot order=scsi0
qm set ${VM_TEMPLATE_ID} –serial0 socket –vga serial0
qm set ${VM_TEMPLATE_ID} –ipconfig0 ip=dhcp
qm set ${VM_TEMPLATE_ID} –agent enabled=1
qm set ${VM_TEMPLATE_ID} -ciuser ${USERNAME}
qm set ${VM_TEMPLATE_ID} -cipassword ${PASSWORD}
qm set ${VM_TEMPLATE_ID} –sshkeys ~/.ssh/authorized_keys

Converting to template

In the last step, we convert this VM to a template. A template is a VM with a frozen state used as a base for many machines. It provides a stable starting point and makes it easy for provisioning automation.

qm template ${VM_TEMPLATE_ID}

The complete script can be found on my homelab github

To run over ssh we can pipe the output via ssh running:

cat ubuntu-22.04.sh | ssh root@your-PVE-ip /bin/bash

Result should be a template on your Proxmox node

Now you can run any number of copies, we can use qemu set to configure any variable to the clone we want to change from the template.

# clone

qm clone ${VM_TEMPLATE_ID} ${VM_ID} –name ${VM_NAME}

# configure the vm
qm set ${VM_ID} –scsi1 local-lvm:40
qm set ${VM_ID} –memory ${MEMORY}
qm set ${VM_ID} –cores ${CPUS}
qm set ${VM_ID} –boot order=scsi0
qm set ${VM_ID} –serial0 socket –vga serial0
qm set ${VM_ID} –ipconfig0 ip=dhcp
qm set ${VM_ID} –agent enabled=1

# start
qm start ${VM_ID}

Running again over ssh should create a new vm based on the template:

cat clone-templates.sh | ssh root@your-PVE-ip /bin/bash

Its as fast as it gets, less than 30 seconds and you have a vm running:

Now we know how to create vms based on templates we can explore more options of remote code execution for provisioning.

Socials:

Twitter
Linkedin
Github

Photo by Arno Senoner on Unsplash

Please follow and like us:
Pin Share