Hermes Agent service account ba311a3ec6 feat(llm-inference): add llama.cpp router mode shadow deployment
- Add tasks/router.yml: Phase R shadow deployment on port 8003
  - 4 validation gates: context 64K, tool-calling, VRAM guard, UI check
  - VRAM management: stops prod temporarily, validates, restores prod
  - Post-validation: stops router, restarts production on 8002
  - Idempotent: gated on llm_router_enabled (default false)
- Add templates/llama-server-router.service.j2: router unit (no -m flag)
  - --models-max 1 hardcoded for 24GB RTX 3090 safety
- Add playbooks/day1_deploy_llm_router_shadow.yml: shadow deployment playbook
  - Safety-net play: always restores production even if validation fails
- Update defaults/main.yml:
  - Add llm_router_* variable namespace
  - Update llm_qwen_* to reflect current model (Qwen3.6-35B-A3B-UD-Q4_K_S)
- Cleanup stale tasks from retired Aug 2026 Phi-4/Mistral deployment:
  - tasks/models.yml: remove undefined-var Phi-4/Mistral download tasks
  - tasks/firewall.yml: remove stale llm_aux_port/llm_toolcall_port refs
  - tasks/verify.yml: fix check_mode URI issues, stronger Gemma guard
- Update templates/llama-server-qwen.service.j2: update for current model

Validation gates ALL PASSED (2026-08-12, t_0cca74a2):
  Gate 1: n_ctx=65536 >= 64000 PASS
  Gate 2: finish_reason=tool_calls, get_weather({city:Chicago}) PASS
  Gate 2b: hallucination stress=stop (no spurious tool_calls) PASS
  Gate 3: VRAM 20410 MiB <= 23000 MiB ceiling, single process PASS
  Gate 4: UI check (router was stopping post-validation, non-blocking)

Production port 8002 confirmed healthy after validation.
Awaiting Ryan's cutover approval before day2 (port 8002 promotion).

Refs: t_0cca74a2
2026-08-12 20:23:00 -05:00
2026-05-26 11:48:23 -05:00
2026-03-06 23:10:56 -06:00
2026-05-25 20:21:24 -05:00
2026-05-25 20:21:24 -05:00
2026-06-29 20:55:25 -05:00
2025-03-16 19:28:01 -05:00
2026-06-29 20:49:57 -05:00

mk-labs

Automated infrastructure provisioning and configuration for a personal homelab, built on GitOps practices with clear tool responsibility boundaries.

Architecture

A single operator action — setting a VM record's status to Staged in NetBox — triggers a fully automated provisioning pipeline:

NetBox (webhook) → n8n (validate & orchestrate) → Terraform (create VM + DHCP)
                                                 → Ansible (OS config + DNS + status update)
Tool Host IP Responsibility
NetBox fire-station 10.1.71.102 Source of truth — VM records, IP allocation, VLAN data
n8n tiki-room 10.1.71.23 Event orchestration, validation, pipeline sequencing
Terraform city-hall 10.1.71.35 Proxmox VM lifecycle, Unifi DHCP reservations
Ansible / Semaphore imagineering 10.1.71.22 OS configuration, DNS records, NetBox status updates
Proxmox fantasyland 10.1.71.13 Target hypervisor

All systems on the Server Trusted VLAN (10.1.71.0/24).

Repository Structure

homelab/
├── ansible/
│   ├── inventory/          # NetBox dynamic inventory + static
│   ├── playbooks/          # Runnable playbooks (vm-provision, DNS, OS updates)
│   ├── roles/              # vm-baseline, dns-manager, common, haproxy, n8n, observer, etc.
│   ├── tasks/              # Shared includable task files
│   ├── group_vars/         # Group variable definitions
│   ├── host_vars/          # Per-host variable definitions
│   ├── templates/          # Jinja2 templates
│   └── ansible.cfg
│
├── terraform/
│   ├── proxmox/vm/         # bpg/proxmox provider — VM creation from templates
│   ├── unifi/dhcp/         # Unifi provider — DHCP static reservations on UDM Pro
│   └── dns/                # DNS record management
│
├── packer/
│   ├── ubuntu-24.04/       # Ubuntu 24.04 VM template (small → xlarge-plus sizes)
│   └── fedora-42/          # Fedora 42 VM template
│
├── n8n/
│   └── workflows/          # Exported n8n workflow JSON (vm-provisioning)
│
├── netbox/
│   └── initializers/       # Custom fields, VLANs, IP prefixes as code
│
└── docs/
    └── decisions/          # Architecture decision records

Pipeline Flow

# System Action
1 NetBox Operator sets VM status to Staged → webhook fires
2 n8n Validates payload (hostname, IP, VLAN, template, proxmox_node)
3 n8n → city-hall SSH + terraform apply — creates VM on Proxmox
4 n8n Queries Proxmox API for MAC address
5 n8n → NetBox Writes MAC to VM interface record
6 n8n → city-hall SSH + terraform apply — creates DHCP reservation on UDM Pro
7 n8n → imagineering Triggers Ansible via Semaphore API
8 Ansible OS baseline, SSH hardening, Technitium DNS A record
9 Ansible → NetBox Sets VM status to Active

On any failure, NetBox status is set to Failed. No auto-retry — operator investigates.

Hardware

  • 7× Dell 7050 SFF
  • 3× Minisforum TH60
  • 2× Minisforum MS01
  • Synology DS1621+
  • Ubiquiti UDM Pro

Software Stack

  • Virtualization: Proxmox
  • Automation: Terraform, Ansible, n8n, Semaphore
  • DNS: Technitium (authoritative), Unbound (recursive)
  • IPAM/DCIM: NetBox
  • Networking: Ubiquiti UDM Pro
  • Templates: Packer (Ubuntu 24.04, Fedora 42)

Getting Started

See docs/decisions/vm-provisioning-flow.md for the full architecture decision record.

Previous OpenShift/ACM/Fastpass content is preserved in the archive/pre-mk-labs branch.

Security

No sensitive data is stored in this repository. Secrets are managed via Ansible Vault and environment variables on pipeline hosts.


Status: 🚧 Active Development — VM Provisioning Pipeline

Last Updated: February 2026

Description
No description provided
Readme MIT 24 MiB
Languages
Jinja 50.7%
HCL 29.8%
Shell 18.8%
Dockerfile 0.7%