proxmox: add VM automation with OpenTofu and Ansible

Add automated workflow for building and deploying NixOS VMs on Proxmox including template2 host configuration, Ansible playbook for image building/deployment, and OpenTofu configuration for VM provisioning with cloud-init.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-31 21:54:08 +01:00
parent 7f72a72043
commit 3a464bc323
14 changed files with 519 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
---
- name: Build and deploy NixOS Proxmox template
hosts: localhost
gather_facts: false
vars:
template_name: "template2"
nixos_config: "template2"
proxmox_node: "pve1.home.2rjus.net" # Change to your Proxmox node name
proxmox_host: "pve1.home.2rjus.net" # Change to your Proxmox host
template_vmid: 9000 # Template VM ID
storage: "local-zfs"
tasks:
- name: Build NixOS image
ansible.builtin.command:
cmd: "nixos-rebuild build-image --image-variant proxmox --flake .#template2"
chdir: "{{ playbook_dir }}/.."
register: build_result
changed_when: true
- name: Find built image file
ansible.builtin.find:
paths: "{{ playbook_dir}}/../result"
patterns: "*.vma.zst"
recurse: true
register: image_files
- name: Fail if no image found
ansible.builtin.fail:
msg: "No QCOW2 image found in build output"
when: image_files.matched == 0
- name: Set image path
ansible.builtin.set_fact:
image_path: "{{ image_files.files[0].path }}"
- name: Extract image filename
ansible.builtin.set_fact:
image_filename: "{{ image_path | basename }}"
- name: Display image info
ansible.builtin.debug:
msg: "Built image: {{ image_path }} ({{ image_filename }})"
- name: Deploy template to Proxmox
hosts: proxmox
gather_facts: false
vars:
template_name: "template2"
template_vmid: 9000
storage: "local-zfs"
tasks:
- name: Get image path and filename from localhost
ansible.builtin.set_fact:
image_path: "{{ hostvars['localhost']['image_path'] }}"
image_filename: "{{ hostvars['localhost']['image_filename'] }}"
- name: Set destination path
ansible.builtin.set_fact:
image_dest: "/var/lib/vz/dump/{{ image_filename }}"
- name: Copy image to Proxmox
ansible.builtin.copy:
src: "{{ image_path }}"
dest: "{{ image_dest }}"
mode: '0644'
- name: Check if template VM already exists
ansible.builtin.command:
cmd: "qm status {{ template_vmid }}"
register: vm_status
failed_when: false
changed_when: false
- name: Destroy existing template VM if it exists
ansible.builtin.command:
cmd: "qm destroy {{ template_vmid }} --purge"
when: vm_status.rc == 0
changed_when: true
- name: Import image
ansible.builtin.command:
cmd: "qmrestore {{ image_dest }} {{ template_vmid }}"
changed_when: true
- name: Convert VM to template
ansible.builtin.command:
cmd: "qm template {{ template_vmid }}"
changed_when: true
- name: Clean up uploaded image
ansible.builtin.file:
path: "{{ image_dest }}"
state: absent
- name: Display success message
ansible.builtin.debug:
msg: "Template VM {{ template_vmid }} created successfully on {{ storage }}"