DEV Community

Cover image for How to automate provisioning in Proxmox Using Cloud images
Caio Campos Borges Rosa
Caio Campos Borges Rosa

Posted on

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
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  • Download the image:
# download new image
wget http://cloud-images.ubuntu.com/releases/22.04/release/${UBUNTU_IMAGE}
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
  • 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} 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Result should be a template on your Proxmox node

Image description

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}
Enter fullscreen mode Exit fullscreen mode

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

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

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

VM

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

Top comments (0)