Yet Another Inventory-Driven Ansible Provisioner
Inventory-defined host provisioning: multi-NIC bridges/VLANs, optional bonding, firewalld, temporary PXE, VM create/destroy (libvirt-first, Proxmox optional).
Apache-2.0 — see LICENSE. Contributing: CONTRIBUTING.md. Security: SECURITY.md. Conduct: CODE_OF_CONDUCT.md.
| Doc | Purpose |
|---|---|
| lab-provisioning.md | Master walkthrough — empty inventory → virt01–03 → demo guests → lab-gpu01 GPU soak → cleanup (controller bck) |
| gpu-passthrough.md | lab-gpu01 GPU PT soak (see lab-provisioning.md Steps 9–10) |
| getting-started.md | Install, tags, tempxe |
| discovery-to-create.md | Main workflow — discover → prepare → create |
| prepare-safety.md | When prepare / firewalld can strand SSH |
| inventory-model.md | networks / uplinks / storages / disks |
| integrations/umkim.md | Optional hub integration contract (YAIDAP_RESULT; standalone YAIDAP unchanged) |
| KNOWN_LIMITATIONS.md | HTTP-ISO NIC coverage, Proxmox dual-NIC, RAM/OOM |
ansible-galaxy collection install -r requirements.yml
pip install -r python_requirements.txt
ansible-playbook playbooks/validate-all.yml --tags validate -i inventory/example
ansible-playbook playbooks/configure-hypervisors.yml --tags prepare -i inventory/example --limit hv01
ansible-playbook playbooks/provision-vms.yml --tags create -i inventory/example --limit vm01 \
-e cloudinit_password='CHANGE_ME'
Copy inventory/example/ and replace IPs, MACs, and keys before real use.
Reference lab demo: inventory/demo/ uses fictional
MACs, disk serials, and example.lab / example.test names — copy and replace
before real hardware. Walkthrough: lab-provisioning.md.
Phase YAML: inventory/demo/examples/.
playbooks/ tag-driven entrypoints
roles/ configure-common, configure-hypervisor, configure-provisioning, configure-tempxe, configure-router
inventory/example/ sanitized starter inventory (schema contract)
inventory/demo/ fictional reference lab for the walkthrough
docs/
Public extract. inventory/example/ is the schema contract; fields may still move.
The demo walkthrough uses fictional placeholders in inventory/demo/.
These paths were exercised on the demo lab (inventory/demo/; controller bck)
and earlier nested KVM hypervisors. Treat as greenfield-ready with the caveats
in the next section.
| Area | What works |
|---|---|
| Schema | validate-all.yml --tags validate |
| SSH discovery | discover-hosts.yml --tags check_host_details → draft host_vars + notes (Rocky 9, Debian 12 / Proxmox) |
| HV prepare | Bridges, untagged + VLAN uplinks, libvirt pools, Rocky GenericCloud image fetch (nested HV) |
| Bond uplinks | active-backup bond → bridge on nested HV; failover tested |
| firewalld | Zones/ports from uplink schema (nested HV; zone overlap still rough — see lab notes) |
| Guest lifecycle | libvirt cloud-init create / destroy; multi-disk, multi-NIC guests |
| TempXE Rocky | PXE kickstart Rocky 9 and 10 on fake bare-metal VM (lab VLAN, proxy DHCP) |
| TempXE discovery | Anaconda discovery collector → tarball in tempxe container |
| TempXE Proxmox | PXE automated install PVE 8 and 9; embedded initrd + iPXE path |
| Proxmox guests | provisioning_provider: proxmox create/destroy; empty-NIC → ip=manual |
| GPU passthrough | Bare-metal VFIO prepare + libvirt hostdev and Proxmox hostpci (prepare_gpu_passthrough; lab-gpu01 Rocky 10 then PVE 9) |
| TempXE lifecycle | tempxe_status / tempxe_start (confirm) / tempxe_stop arming |
| Physical BM PXE | Demo iron (virt01–03, lab-gpu01) via TempXE |
Code exists and was used in lab, but expect manual steps, narrow topology, or incomplete automation.
| Area | State |
|---|---|
Bare-metal prepare | Single-NIC soak PASS; dual-NIC bond mid-prepare can drop SSH — see prepare-safety.md |
| Fake-BM PXE guests | SeaBIOS + e1000 often needs pxe-e1000.rom in domain XML and /etc/qemu/bridge.conf on the hypervisor (not automated by create / prepare) |
| TempXE container | configure_tempxe builds tempxe:rocky9 and does not start it. tempxe_start runs podman run (-e tempxe_confirm=true when a host is reinstall-armed). ISO binds use :Z except iso9660 trees, which stay :ro |
| PXE discovery → inventory | collect_discovery (also on tempxe_stop) unpacks tarballs into generated/host_vars/ |
Disk by-id in kickstart | Filters + kickstart templates support disk/by-id/…; BM reinstall with by-id inventory not fully regression-tested |
| Discovery naming | PXE discovery menu still requires install_os: true (misleading; does not install OS when tempxe_discovery is set). Default reboot_after_discovery: false keeps the host in the live env until you reboot manually |
| OpenWrt ZTP | Virtualized create bootstraps LAN/WAN, optional WAN VLAN→LAN, LAN DHCP off; PXE/bare-metal templates exist |
| OpenWrt router services | DynDNS + nginx reverse proxy + ACME (configure-routers.yml). Lab soak uses Pebble; production LE needs a public hostname |
| LACP / real switches | Bond schema only; active-backup validated, LACP not |
| Item | Notes |
|---|---|
| OpenWrt router extras | WireGuard and Authelia are not in this repo (homelab-only) |
| Kubernetes / addons | Out of scope |
| Multi-hypervisor scheduling | Rocky libvirt: vm_location: least-utilized + plan-vm-placement.yml dry-run; memory-based pool from groups['hypervisors'] |
| Tempxe auto-start | Container not started by role after build |
| QEMU bridge ACL + PXE ROM | Not wired into configure-hypervisor / create yet |
New deployments: start from discovery-to-create.md and testing-strategy.md.
Jinja
49.7%
Python
25.5%
Shell
24.8%
Yet Another Inventory-Driven Ansible Provisioner
Inventory-defined host provisioning: multi-NIC bridges/VLANs, optional bonding, firewalld, temporary PXE, VM create/destroy (libvirt-first, Proxmox optional).
Apache-2.0 — see LICENSE. Contributing: CONTRIBUTING.md. Security: SECURITY.md. Conduct: CODE_OF_CONDUCT.md.
| Doc | Purpose |
|---|---|
| lab-provisioning.md | Master walkthrough — empty inventory → virt01–03 → demo guests → lab-gpu01 GPU soak → cleanup (controller bck) |
| gpu-passthrough.md | lab-gpu01 GPU PT soak (see lab-provisioning.md Steps 9–10) |
| getting-started.md | Install, tags, tempxe |
| discovery-to-create.md | Main workflow — discover → prepare → create |
| prepare-safety.md | When prepare / firewalld can strand SSH |
| inventory-model.md | networks / uplinks / storages / disks |
| integrations/umkim.md | Optional hub integration contract (YAIDAP_RESULT; standalone YAIDAP unchanged) |
| KNOWN_LIMITATIONS.md | HTTP-ISO NIC coverage, Proxmox dual-NIC, RAM/OOM |
ansible-galaxy collection install -r requirements.yml
pip install -r python_requirements.txt
ansible-playbook playbooks/validate-all.yml --tags validate -i inventory/example
ansible-playbook playbooks/configure-hypervisors.yml --tags prepare -i inventory/example --limit hv01
ansible-playbook playbooks/provision-vms.yml --tags create -i inventory/example --limit vm01 \
-e cloudinit_password='CHANGE_ME'
Copy inventory/example/ and replace IPs, MACs, and keys before real use.
Reference lab demo: inventory/demo/ uses fictional
MACs, disk serials, and example.lab / example.test names — copy and replace
before real hardware. Walkthrough: lab-provisioning.md.
Phase YAML: inventory/demo/examples/.
playbooks/ tag-driven entrypoints
roles/ configure-common, configure-hypervisor, configure-provisioning, configure-tempxe, configure-router
inventory/example/ sanitized starter inventory (schema contract)
inventory/demo/ fictional reference lab for the walkthrough
docs/
Public extract. inventory/example/ is the schema contract; fields may still move.
The demo walkthrough uses fictional placeholders in inventory/demo/.
These paths were exercised on the demo lab (inventory/demo/; controller bck)
and earlier nested KVM hypervisors. Treat as greenfield-ready with the caveats
in the next section.
| Area | What works |
|---|---|
| Schema | validate-all.yml --tags validate |
| SSH discovery | discover-hosts.yml --tags check_host_details → draft host_vars + notes (Rocky 9, Debian 12 / Proxmox) |
| HV prepare | Bridges, untagged + VLAN uplinks, libvirt pools, Rocky GenericCloud image fetch (nested HV) |
| Bond uplinks | active-backup bond → bridge on nested HV; failover tested |
| firewalld | Zones/ports from uplink schema (nested HV; zone overlap still rough — see lab notes) |
| Guest lifecycle | libvirt cloud-init create / destroy; multi-disk, multi-NIC guests |
| TempXE Rocky | PXE kickstart Rocky 9 and 10 on fake bare-metal VM (lab VLAN, proxy DHCP) |
| TempXE discovery | Anaconda discovery collector → tarball in tempxe container |
| TempXE Proxmox | PXE automated install PVE 8 and 9; embedded initrd + iPXE path |
| Proxmox guests | provisioning_provider: proxmox create/destroy; empty-NIC → ip=manual |
| GPU passthrough | Bare-metal VFIO prepare + libvirt hostdev and Proxmox hostpci (prepare_gpu_passthrough; lab-gpu01 Rocky 10 then PVE 9) |
| TempXE lifecycle | tempxe_status / tempxe_start (confirm) / tempxe_stop arming |
| Physical BM PXE | Demo iron (virt01–03, lab-gpu01) via TempXE |
Code exists and was used in lab, but expect manual steps, narrow topology, or incomplete automation.
| Area | State |
|---|---|
Bare-metal prepare | Single-NIC soak PASS; dual-NIC bond mid-prepare can drop SSH — see prepare-safety.md |
| Fake-BM PXE guests | SeaBIOS + e1000 often needs pxe-e1000.rom in domain XML and /etc/qemu/bridge.conf on the hypervisor (not automated by create / prepare) |
| TempXE container | configure_tempxe builds tempxe:rocky9 and does not start it. tempxe_start runs podman run (-e tempxe_confirm=true when a host is reinstall-armed). ISO binds use :Z except iso9660 trees, which stay :ro |
| PXE discovery → inventory | collect_discovery (also on tempxe_stop) unpacks tarballs into generated/host_vars/ |
Disk by-id in kickstart | Filters + kickstart templates support disk/by-id/…; BM reinstall with by-id inventory not fully regression-tested |
| Discovery naming | PXE discovery menu still requires install_os: true (misleading; does not install OS when tempxe_discovery is set). Default reboot_after_discovery: false keeps the host in the live env until you reboot manually |
| OpenWrt ZTP | Virtualized create bootstraps LAN/WAN, optional WAN VLAN→LAN, LAN DHCP off; PXE/bare-metal templates exist |
| OpenWrt router services | DynDNS + nginx reverse proxy + ACME (configure-routers.yml). Lab soak uses Pebble; production LE needs a public hostname |
| LACP / real switches | Bond schema only; active-backup validated, LACP not |
| Item | Notes |
|---|---|
| OpenWrt router extras | WireGuard and Authelia are not in this repo (homelab-only) |
| Kubernetes / addons | Out of scope |
| Multi-hypervisor scheduling | Rocky libvirt: vm_location: least-utilized + plan-vm-placement.yml dry-run; memory-based pool from groups['hypervisors'] |
| Tempxe auto-start | Container not started by role after build |
| QEMU bridge ACL + PXE ROM | Not wired into configure-hypervisor / create yet |
New deployments: start from discovery-to-create.md and testing-strategy.md.
Jinja
49.7%
Python
25.5%
Shell
24.8%