Given VMWare seems to have imploded, the new hotness is Proxmox. And it really is good, especially for a homelabber (no more vcenter!). But, the one thing I always struggled with was creating a template I could use to create a new machine in seconds. So, this guide should show you how to use ansible to create templates in seconds.
Creating a Template
This is what we need to create in Ansible. As a note, because Proxmox clusters need unique IDs for machines across hosts, we can add a unique value to the VMID if we just increment it for each host.
Also, this is 99% from this guy, massive props, I didnt realise it was this easily scriptable: https://github.com/UntouchedWagons/Ubuntu-CloudInit-Docs
---
- hosts: all
vars:
base_value: 9000
tasks:
- name: Set incremented value for each host
set_fact:
VMID: "{{ base_value | int + ansible_play_hosts.index(inventory_hostname) + 1 }}"
- name: Create a shell script with the incremented VMID
template:
src: ./scripts/create-ubuntu-2404-template.sh.j2
dest: /tmp/create-ubuntu-2404-template.sh
mode: '0755'
- name: Execute the script
shell: /tmp/create-ubuntu-2404-template.sh
This is the script we run to create the VM template in proxmox. Place it in a folder and file called ./scripts/create-ubuntu-2404-template.sh.j2
. It will setup a machine template and create a template we can use to create VMs. Tweak anything below as you see fit. In particular, the place to pickup the SSH authorised key for access.
#! /bin/bash
VMID={{ VMID }}
STORAGE=local-lvm
set -x
wget -qN https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
qemu-img resize noble-server-cloudimg-amd64.img 128G
qm destroy $VMID
qm create $VMID --name "ubuntu-2404-template" --ostype l26 \
--memory 2048 --balloon 0 \
--agent 1 \
--bios ovmf --machine q35 --efidisk0 $STORAGE:0,pre-enrolled-keys=0 \
--cpu host --cores 2 --numa 1 \
--vga serial0 --serial0 socket \
--net0 virtio,bridge=vmbr0,mtu=1
qm importdisk $VMID noble-server-cloudimg-amd64.img $STORAGE
qm set $VMID --scsihw virtio-scsi-pci --virtio0 $STORAGE:vm-$VMID-disk-1,discard=on
qm set $VMID --boot order=virtio0
qm set $VMID --ide2 $STORAGE:cloudinit
mkdir -p /var/lib/vz/snippets
cat << EOF | tee /var/lib/vz/snippets/ubuntu.yaml
#cloud-config
runcmd:
- apt-get update
- apt-get install -y qemu-guest-agent
- systemctl enable ssh
- reboot
# Taken from https://forum.proxmox.com/threads/combining-custom-cloud-init-with-auto-generated.59008/page-3#post-428772
EOF
qm set $VMID --cicustom "vendor=local:snippets/ubuntu.yaml"
qm set $VMID --ciuser $USER
qm set $VMID --sshkeys ~/.ssh/authorized_keys
qm set $VMID --ipconfig0 ip=dhcp
qm template $VMID
Deployment
Run it like this. Make a hosts file (say you have 3 proxmox machines that all need a template)
192.168.1.100 ansible_ssh_user=root ansible_ssh_private_key_file=~/.ssh/ssh
192.168.1.101 ansible_ssh_user=root ansible_ssh_private_key_file=~/.ssh/ssh
192.168.1.102 ansible_ssh_user=root ansible_ssh_private_key_file=~/.ssh/ssh
Then run like so
ansible-playbook -i hosts playbook.yml
We should get some templates!