--- created: '2026-05-26' path: Sources/Homelab project: homelab-ansible tags: - ansible - proxmox - pbs - traefik - knot - docker type: project-plan --- ## Goal `homelab-ansible` is the **service + backup infrastructure** repo for the PVE-hosted homelab. Today (v0.1.0) it configures the Traefik + DNS slice. This plan captures its **expanding role** coming out of the 2026-05-25 Ansible-repo reorg: 1. Absorb the **PBS backup stack** as infrastructure-as-code (the backups already run and are restore-verified — this is IaC capture, not new infra). 2. Adopt the new **`homelab-common`** shared-roles library to kill cross-repo drift. 3. Coordinate two sibling cleanup tasks that fell out of the reorg (PBS codification here; CLI strip on the NAS). This plan references the current repo state and the sibling projects; the live decision log lives in trellis thread #580 ([[herbys-dev-setup]] / project `homelab-dev-ansible`). ## Locked Decisions - **Repo topology (decided 2026-05-25):** four Ansible repos, scoped by domain, sharing a thin baseline: - **homelab-ansible** (this) — service + backup infra. - **homelab-dev-ansible** (new) — `herbys-dev` dev workbench VM only ([[herbys-dev-setup]]). - **herbylab-nas** (GitHub `trucktrav/herbylab-nas`) — bare-metal NAS storage stack. - **workstation-ansible** (Gitea `petal-power`, formerly cli-standardization) — owns the CLI/shell concern (Fish/Starship/dotfiles) across machines ([[cli-standardization]]). - **homelab-common** (new) — shared baseline roles, consumed via `requirements.yml`. - **Hosts owned by homelab-ansible:** Knot DNS (LXC 103, 10.0.11.10), Pi-hole (LXC 104, 10.0.11.50), Traefik VM (VM 102, 10.0.21.181) + cloudflared + whoami, **and PBS (LXC 110)**. - **PBS lives here**, not in homelab-dev-ansible (corrects an earlier draft that started PBS in the dev repo). - **homelab-common is thin:** baseline OS (timezone/locale/users/sudo/SSH keys/apt + unattended-upgrades/base packages) + docker-engine install + (optional) msmtp alert role + (optional) version_check. Shell, storage, service stacks, and docker-deploy patterns all stay domain-specific. Naming convention: noun-role style (homelab-ansible's), not the NAS verb-prefix style. - **Adoption is deliberate, not big-bang:** homelab-dev-ansible is homelab-common's first consumer (greenfield); homelab-ansible and herbylab-nas retrofit onto it as scheduled one-PR-per-repo follow-ups, when next touched. - **Repo name `homelab-ansible` unchanged.** ## Open Items - Pick the **canonical baseline** for homelab-common: homelab-ansible's `common` vs the NAS `manage_linux` — they have already diverged, so this is a choice, not free extraction. - Confirm the **seed-from-greenfield → deliberate-retrofit** sequencing (proposed; pending Travis's explicit nod given his drift concern). - PBS codification must reflect reality: the off-box leg is **rsync-on-a-timer to the NAS**, NOT the originally-planned PBS native sync-job (NFS/SMB both failed against PVE+PBS). ## Phases ### Sibling task 1 — Codify PBS into homelab-ansible (IaC capture) The backups already RUN and passed a two-leg restore test: PBS in LXC 110, datastore `main`/`pbs-main` on a single-disk ZFS pool on `sda`; PVE vzdump for VM 100 at 02:30 + 22:30; PBS prune-job `pj-main` at 03:00 (keep-daily 7 / weekly 4 / monthly 6); rsync-on-timer copying the datastore to the NAS. A `proxmox-backup` role is already on homelab-ansible's own v0.2.0 roadmap. - [ ] Write `proxmox-backup` role: PBS LXC + datastore, vzdump job, prune schedule, rsync-to-NAS timer. - [ ] Bake in the operational gotchas: rsync timer must fire in a QUIET window clear of the 02:30/22:30 backups and the 03:00 prune; run an occasional PBS `verify` on the source datastore (rsync does not verify chunk integrity in flight). - [ ] Reconcile with the locked backup decisions; record that off-box transport = rsync, not PBS sync. - [ ] Validate idempotent run against the live PBS (zero changes on second pass). ### Sibling task 2 — Strip CLI out of herbylab-nas `manage_zsh` (Oh-My-Zsh + Powerlevel10k) currently lives in herbylab-nas, but shell/CLI is workstation-ansible's domain. Remove it from the NAS repo. - [ ] Remove the `manage_zsh` role and its play wiring from herbylab-nas. - [ ] Confirm nothing else in the NAS playbook depends on it. - [ ] (Optional) If the NAS shell should be managed at all, add the NAS host to workstation-ansible's inventory rather than re-homing it in the NAS repo. ### homelab-ansible's own homelab-common retrofit - [ ] Once homelab-common exists and is proven on homelab-dev-ansible, replace homelab-ansible's hand-rolled `common` with the shared baseline role (one focused PR). ## Notes - **Current repo state:** homelab-ansible v0.1.0 (Gitea `petal-power`, owner `herbyadmin`, on disk `/opt/projects/homelab/homelab-ansible`). Roles: `common`, `docker`, `compose_stack`, `knot`, `pihole`, `traefik`, `cloudflared`, `whoami`. Terraform: `bpg/proxmox` modules (`proxmox_vm`, `proxmox_lxc`) + `envs/homelab`. Docs: README, CHANGELOG, ARCHITECTURE, REBUILD, RESTORE, SECRETS, CONVENTIONS. v0.2.0 roadmap already lists the deferred `proxmox-backup` role, inventory auto-render from Terraform output, and CI. - **Related plans:** [[herbys-dev-setup]] (the dev box → homelab-dev-ansible; trellis #580), [[repo-hygiene-remediation]] (trellis #272 — herbys-dev is its Phase-0 hard gate), [[cli-standardization]] (→ workstation-ansible). - **Cross-remote sharing:** herbylab-nas is on GitHub (`trucktrav`); homelab-ansible and workstation-ansible are on Gitea (`petal-power`). `requirements.yml` accepts git URLs, so homelab-common can be consumed across both remotes. - **Cloudflare:** pinned / out of scope for now. - **Control node** for push-model runs: deferred — repo is pushed off-prem, so clone-and-run on whatever target machine is chosen at the time.