Skip to content

Instantly share code, notes, and snippets.

@RSully
Created August 8, 2025 03:26
Show Gist options
  • Select an option

  • Save RSully/7b65c56b90aafeec234dc4a656e29b3c to your computer and use it in GitHub Desktop.

Select an option

Save RSully/7b65c56b90aafeec234dc4a656e29b3c to your computer and use it in GitHub Desktop.
Ansible playbook for setting up a Debian cloud image to use on Proxmox. This playbook would be executed from your client machine, with the Proxmox host specified in the inventory (`-i`)
---
- hosts: all
remote_user: root
vars:
# https://cloud.debian.org/images/cloud/bookworm/
# This is the path from Debian's website
DEBIAN_IMAGE_URL: "https://cloud.debian.org/images/cloud/bookworm/20250804-2194/debian-12-generic-amd64-20250804-2194.qcow2"
DEBIAN_JSON_URL: "https://cloud.debian.org/images/cloud/bookworm/20250804-2194/debian-12-generic-amd64-20250804-2194.json"
# Note that these begin with "sha512:"
DEBIAN_IMAGE_CHECKSUM: "sha512:251161733705e529a4d24d3be41326551351c1056588811d575bc6d34f3ea5007a15a30132357be1918d15e5f46e19e776541ad4bd6edf759bde769528ac008c"
DEBIAN_JSON_CHECKSUM: "sha512:d67505de61486ffe403a6017d9d8f9dbe3e25c688d21733292baa63ace159338acc891d5d7a437a74de8736e549d2eae711bdc13745ed1a90587de6ae8e12adb"
# This is what we'll call it locally
PROXMOX_VERSION: "debian-12-20250804-2194"
PROXMOX_TEMPLATE_VMID: 9100
# This is the ROOT of where we'll be working on the Proxmox host
PROXMOX_WORKINGDIR: "/vmpool01/images/cloud-builds"
# Key for root user
SSH_KEY: "ssh-ed25519 FILLE ME IN"
# Where the template will be stored
PROXMOX_IMAGE_POOL: "vmpool01-vmdata"
tasks:
- name: Install pre-reqs
apt:
pkg:
- guestfs-tools
state: present
- name: Create image working directory
ansible.builtin.file:
path: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}"
state: directory
- name: Download Debian JSON
ansible.builtin.get_url:
url: "{{ DEBIAN_JSON_URL }}"
dest: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian.json"
checksum: "{{ DEBIAN_JSON_CHECKSUM }}"
- name: Download Debian QCOW2
ansible.builtin.get_url:
url: "{{ DEBIAN_IMAGE_URL }}"
dest: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian.qcow2"
checksum: "{{ DEBIAN_IMAGE_CHECKSUM }}"
- name: Create a larger qcow2 image
command: qemu-img create -f qcow2 -o preallocation=metadata debian-10G.qcow2 10G
args:
chdir: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}"
creates: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian-10G.qcow2"
- name: Expand the underlying filesystem
# File system can be found via:
# virt-filesystems --long -h --all -a debian.qcow2
command: virt-resize --expand /dev/sda1 debian.qcow2 debian-10G.qcow2
args:
chdir: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}"
- name: Customize the image for Proxmox
command: >
virt-customize -a debian-10G.qcow2
--run-command 'grub-install /dev/sda'
--install cloud-guest-utils,cloud-initramfs-growroot
--install qemu-guest-agent
--run-command 'systemctl enable qemu-guest-agent'
--install cifs-utils,htop,tmux
args:
chdir: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}"
- name: Shrink the image on disk
command: >
virt-sparsify --compress
debian-10G.qcow2
debian-10G-compressed.qcow2
args:
chdir: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}"
creates: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian-10G-compressed.qcow2"
- name: Remove the uncompressed copy
file:
path: "{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian-10G.qcow2"
state: absent
- name: Create temp file for public SSH key
ansible.builtin.tempfile:
state: file
suffix: temppubsshkey
register: TEMP_PUB_SSHKEY
- name: Write public key contents
ansible.builtin.lineinfile:
path: "{{ TEMP_PUB_SSHKEY.path }}"
line: "{{ SSH_KEY }}"
- name: Create Proxmox VM
command: >
qm create {{ PROXMOX_TEMPLATE_VMID }}
--name '{{ PROXMOX_VERSION }}'
--ostype l26
--machine q35
--memory 2048
--cores 2
--net0 virtio,bridge=vmbr0
--scsihw virtio-scsi-single
--agent enabled=1,fstrim_cloned_disks=1
- name: Configure cloud-init
command: >
qm set {{ PROXMOX_TEMPLATE_VMID }}
--ide2 {{ PROXMOX_IMAGE_POOL }}:cloudinit
--serial0 socket
--vga serial0
--sshkeys {{ TEMP_PUB_SSHKEY.path }}
- name: Import disk to Proxmox
command: >
qm set {{ PROXMOX_TEMPLATE_VMID }}
--scsi0 {{ PROXMOX_IMAGE_POOL }}:0,ssd=1,discard=on,iothread=1,import-from="{{ PROXMOX_WORKINGDIR }}/{{ PROXMOX_VERSION }}/debian-10G-compressed.qcow2"
--boot order=scsi0
- name: Convert Proxmox placeholder to template
command: "qm template {{ PROXMOX_TEMPLATE_VMID }}"
- name: Remove temp public key file
ansible.builtin.file:
path: "{{ TEMP_PUB_SSHKEY.path }}"
state: absent
when: TEMP_PUB_SSHKEY.path is defined
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment