f76fb397ab779954c8202231d26037c3850e09be
Updated the README.md file to improve readability and added notes on future improvements, such as API-based module support and automated post-deployment provisioning.
refactor ♻️: Refactored the Debian VM template and cloning tasks for improved readability and maintainability.
refactor ♻️: Refactored the Debian VM template and cloning tasks for improved readability and maintainability.
Ansible Role: Proxmox VM → Template → Clones (Cloud‑Init)
Automates the entire lifecycle of a Debian GenericCloud VM on Proxmox:
- Download the Debian image
- Create a base VM
- Optionally enable UEFI, SecureBoot, TPM 2.0, GPU passthrough
- Convert the VM into a template
- Spin up any number of Cloud‑Init clones with static or dynamic networking
Features
- ✅ Auto‑download Debian Bookworm GenericCloud image
- ✅ Create VM (CPU, RAM, networking, storage)
- ✅ DHCP or static IP support
- ✅ Cloud‑Init: users, SSH keys, passwords, timezone, packages
- ✅ Optional TPM 2.0 + SecureBoot (OVMF)
- ✅ Optional GPU passthrough or VirtIO GPU
- ✅ Optional disk resize
- ✅ Convert base VM into a template
- ✅ Create multiple clones from template
- ✅ Start clones after creation
Folder Structure
ANSIBLE_PROXMOX_VM/
├─ defaults/
│ └─ main.yml
├─ tasks/
│ └─ main.yml
├─ templates/
│ ├─ cloudinit_userdata.yaml.j2
│ └─ cloudinit_vendor.yaml.j2
└─ README.md
Requirements
- Proxmox API / Environment
- Role runs on the Proxmox host via localhost, using
qmCLI commands. - Ansible must have SSH access to the Proxmox node.
- User must have permission to run
qmcommands (root recommended). - Proxmox storage pool such as
local-lvm.
Debian Cloud Image
The image is automatically downloaded if not present:
/var/lib/vz/template/qemu/debian-genericcloud-amd64.qcow2
Variables (defaults/main.yml)
# Base VM settings
vm_id: 150
hostname: debian-template-base
memory: 4096
cores: 4
bridge: vmbr0
storage: local-lvm
mac_address: "DE:AD:BE:EF:44:55"
cpu_type: host
# Networking
ip_mode: dhcp # or 'static'
ip_address: "192.168.1.60/24"
gateway: "192.168.1.1"
dns:
- "1.1.1.1"
- "8.8.8.8"
ipconfig0: "{{ 'ip=dhcp' if ip_mode == 'dhcp' else 'ip=' + ip_address + ',gw=' + gateway }}"
# Cloud‑Init user
ci_user: debian
ci_password: "SecurePass123"
ssh_key_path: "~/.ssh/id_rsa.pub"
timezone: "Europe/Berlin"
# Disk
resize_disk: true
resize_size: "16G"
# GPU passthrough
gpu_passthrough: false
gpu_device: "0000:01:00.0"
virtio_gpu: false
# UEFI + TPM
enable_tpm: false
# Templates + Clones
make_template: true
create_clones: true
clones:
- id: 301
hostname: app01
ip: "192.168.1.81/24"
gateway: "192.168.1.1"
Usage
Include the role in a playbook
- hosts: proxmox
become: true
roles:
- ANSIBLE_PROXMOX_VM
Run directly
ansible-playbook tasks/main.yml -i inventory
Clone Creation Flow
For each clone defined in clones:
qm clone 150 <clone_id>- Set hostname & Cloud‑Init netplan
- Start the VM
Example clones section
clones:
- id: 301
hostname: app01
ip: "192.168.1.81/24"
gateway: "192.168.1.1"
Cloud‑Init Templates
templates/cloudinit_userdata.yaml.j2
Defines:
users- SSH key
- password
- timezone
- package updates
- custom commands
templates/cloudinit_vendor.yaml.j2
Defines:
- default packages
- DNS (optional)
Notes & Best Practices
- Ensure Proxmox has snippets storage enabled (
Datacenter → Storage). - If cloning fails with an invalid IP, check the format:
"192.168.1.81/24". - Both SSH keys and password login are supported (
ssh_pwauth: true). - If GPU passthrough is enabled, ensure the host kernel is configured for IOMMU.
Future Improvements (optional)
- Switch to
community.general.proxmoxAPI module instead of CLI - Validate clone IDs
- Automated post‑deployment provisioning (Ansible SSH into clones)
- Publish as a Galaxy‑ready role
Description
Languages
Jinja
100%