No description
This repository has been archived on 2026-05-13. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
  • Jinja 46.8%
  • Python 31.8%
  • Shell 11.3%
  • HCL 10.1%
Find a file
Jason Gosselin 1a8d7968d0
Some checks failed
lint / lint (push) Has been cancelled
ci: pause ansible-apply + drift-detect for monorepo Phase 3+4
Per gosseljl/infra ADR 0011: monorepo's `common` role now manages the
baseline on DDI hosts. Running both CI lanes at once causes Alloy reinstall
loops and sshd config flap.

Scheduled triggers (push-to-main + cron) removed; workflow_dispatch stays
for emergency manual runs. Scheduled triggers restore at the Phase 5
subtree merge, at which point these workflow files are deleted (the
monorepo will own them).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 20:31:48 -04:00
.forgejo ci: pause ansible-apply + drift-detect for monorepo Phase 3+4 2026-05-11 20:31:48 -04:00
ansible feat(kea-ha): switch from hot-standby to active/active load-balancing 2026-05-10 15:38:30 -04:00
docs docs(runbook): record VLAN 102 race + stop-legacy-daemon step 2026-05-10 12:13:43 -04:00
netbox/seed-data feat(inventory): single TOML source of truth for hosts/IPs/reservations 2026-05-10 14:18:56 -04:00
scripts feat(seed): add 14 NetBox A records + 3 Kea reservations for homelab services 2026-05-10 12:30:26 -04:00
terraform/proxmox fix(terraform): point lab_dns_servers at new BIND HA pair 2026-05-10 13:02:54 -04:00
tests/drift fix(drift): pass label IDs (not names) on Forgejo issue creation 2026-05-09 12:56:33 -04:00
tools feat(inventory): single TOML source of truth for hosts/IPs/reservations 2026-05-10 14:18:56 -04:00
.ansible-lint fix(lint): unblock ansible-lint on PR — naming, refactor, config skips 2026-05-10 12:51:46 -04:00
.env.example chore: scaffold homelab-ddi project (phase 1 prep) 2026-05-07 18:12:26 -04:00
.gitignore fix(ci): gate ansible-lint with .ansible-lint, install collections in CI 2026-05-08 23:15:01 -04:00
.mcp.json chore(mcp): wire NetBox MCP to live netbox-01 2026-05-07 22:51:41 -04:00
.pre-commit-config.yaml feat(pre-commit): auto-render inventory.toml on commit 2026-05-10 14:32:16 -04:00
.sops.yaml feat(phase-1): provision netbox-01 + verify NetBox stack 2026-05-07 22:19:42 -04:00
.yamllint chore(yamllint): allow extra spaces after commas in inline-flow records 2026-05-10 12:42:07 -04:00
inventory.toml feat(inventory): single TOML source of truth for hosts/IPs/reservations 2026-05-10 14:18:56 -04:00
README.md feat(pre-commit): auto-render inventory.toml on commit 2026-05-10 14:32:16 -04:00

homelab-ddi

Centralized DNS / DHCP / IPAM stack for the strscrm homelab. Replaces Technitium DNS and isc-dhcp-server.

Stack

Layer Component HA
IPAM / management NetBox 4.6 + plugins (netbox_dns, netbox_dns_bridge, netbox_kea, netbox_healthcheck_plugin) Single VM (PBS-backed)
Authoritative + recursive DNS BIND 9.20 (catalog zones, RPZ blocklists, NetBox webhook receiver) Active/active pair
DHCP Kea 3.0.3 LTS with HA hook (hot-standby), memfile per node Active/standby pair
Observability Prometheus + Alertmanager + Grafana 11.4 + Loki + blackbox + Alloy + Stork agents Single VM (Uptime Kuma probes the probe)
CI/CD Forgejo Actions on megatron runner n/a
Storage Proxmox ceph rbd pool shared across pve1/pve2/pve3

See /home/gosseljl/src/infra/CLAUDE.md (one level up from this repo) for the full design contract.

Layout

inventory.toml    # SOURCE OF TRUTH for hosts, IPs, MACs, subnets, reservations
docs/             # design docs, ADRs, runbooks, archived materials
terraform/        # Proxmox VM provisioning (bpg/proxmox provider)
ansible/          # roles + playbooks for in-VM config
netbox/           # plugins + seed data (seed-data/objects.yaml is part-generated from inventory.toml)
scripts/          # one-shot helpers (template builder, etc.)
tools/            # operator tooling (render-inventory.py, refresh-dashboards.sh)
tests/            # drift checkers + e2e tests
.forgejo/         # CI workflows

Quickstart

  1. Install prereqs: terraform (or tofu), ansible, sops, age, uvx, pre-commit.
  2. cp .env.example .env and fill in tokens.
  3. direnv allow (or source .env manually).
  4. pre-commit install — auto-renders inventory.toml on every commit and runs yamllint.
  5. Phase 1: see docs/runbooks/phase-1-evidence.md for the deployed acceptance log.

Phases

Phase Scope Status
1 NetBox + first BIND node Complete
2 Second BIND node + RPZ blocklists + catalog zones + NetBox webhook Complete
3 Kea HA pair + netbox_kea plugin (test subnet only) Complete
3.5 Forgejo Actions CI/CD + drift detection Complete
3.75 Observability stack on monitor-01 Complete
3.76 Stork agent replaces kea-exporter + bind_exporter; Alloy replaces Promtail Complete
3.77 Grafana dashboards: curated OSS imports replace hand-built set Complete
3.78 NetBox object-count textfile collector + Infinity datasource Complete
4 UniFi adoption + per-VLAN cutover on Kea In progress (VLAN 101, 103 done; 102, 104 pending)
5 Decommission Technitium + isc-dhcp-server Not started

Operator notes

  • Internal DNS suffix: infra.strscrm.io (split-horizon on an owned domain).
  • Lab management VLAN: tag 102, subnet 10.0.2.0/24, gateway 10.0.2.254, on vmbr0.
  • Test subnet: VLAN 199, 10.0.99.0/24, on vmbr1 (carries the VLAN over the Cisco PVE-STOR trunk).
  • Storage: Proxmox ceph rbd pool (shared across pve1, pve2, pve3).
  • Backups: Proxmox Backup Server (pbs storage).
  • Secrets: sops + age (see docs/secrets.md).
  • External monitoring of monitor-01: Uptime Kuma probes http://monitor-01:9090/-/healthy so a dead Prometheus is detected from outside the stack.

Common tasks

  • Add a host or reservation, or change an IP: edit inventory.toml at the repo root, then python3 tools/render-inventory.py to update netbox/seed-data/objects.yaml and ansible/roles/kea/defaults/main.yml. Commit both the TOML and the rendered YAML; CI rejects the push otherwise.
  • Refresh Grafana dashboards from upstream: tools/refresh-dashboards.sh, review the diff, commit, push, let CI deploy.
  • Cut a new VLAN over to Kea: set kea_active = true on the network in inventory.toml, render, push, then flip the relay address on the upstream router (ip dhcp relay address on Cisco NX-OS — not ip helper-address).
  • Add a new DNS zone: create the zone in NetBox; the catalog-zone consumer on the BIND nodes auto-loads it within seconds.
  • Find Proxmox guests not yet in DNS: python3 scripts/discover-undns-vms.py (read-only diff against NetBox).
  • Watch live Kea logs: ssh debian@10.0.2.232 'sudo journalctl -fu isc-kea-dhcp4-server' (or .233).