Consolidates nixos, docker, raspi, and debian-configuration into a single infrastructure-as-code repo. Includes: - ansible/: full inventory + proxmox-hardening, freeipa, and raspberrypi roles (converted from debian-configuration bash scripts) - terraform/: Proxmox VMs, Dynu DNS, Pi-hole (decommissioned stub), Docker container catalog — migrated from docker/infrastructure/terraform/ - stacks/docker/, stacks/raspi/, nixos/: placeholder READMEs pending git subtree population (see implementation plan) - docs/: internal MkDocs site with architecture, network topology, runbooks, and drift-detection guide; external sanitized site - scripts/: drift-detect.sh, docs-build.sh, install-hooks.sh, check-secrets.sh - CI: secret-scan (push/PR), drift-detect (daily), docs-build (on change) - Pi-hole removed throughout — DNS is FreeIPA, DHCP is router See docs/internal/implementation-plan.md for the phased rollout after pushing to Gitea. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UvNjoxTWEDkhXsd1Dq2ETP
3.8 KiB
CLAUDE.md — infrastructure
Safety rules and working context for Claude Code in this repository.
Overall goal
Build a complete, auditable Infrastructure as Code system for the sweet.home homelab.
The end state is: every host, service, and network resource is declared in this repo;
Terraform captures and detects drift in infrastructure state; Ansible idempotently configures
non-NixOS hosts; NixOS flake manages NixOS hosts; automated CI pipelines generate internal
and external documentation daily. See docs/internal/implementation-plan.md for the phased roadmap.
Production boundary — confirm before touching
pve1.sweet.home and all VMs/LXCs running on it are production. That includes:
domain-controller.sweet.home(FreeIPA — if this goes down, auth AND DNS break for everything)docker.sweet.home(Nextcloud, Passbolt, Gitea — live data)
Always ask before running any Ansible playbook with --apply or terraform apply against
production hosts. Use --check (Ansible) or terraform plan (Terraform) for read-only
validation; these are safe to run without asking.
pve-test.sweet.home is the sandbox. VMs and containers on it can be created/destroyed
without asking. Node-level config (firewall, SSH, unattended-upgrades) still needs confirmation.
Terraform rules
- Always
terraform planbeforeterraform apply. - Never commit
.tfstateor.tfvarsfiles — they go in.gitignore. - API tokens and secrets go in
terraform.tfvars(git-ignored) or environment variables. - If
planshows unexpected destruction of real resources, stop and ask.
Ansible rules
- Always use
--check --diffbefore the first real run against any host. - The
proxmox-hardeningrole is safe to re-run (idempotent). Still confirm first. - The
freeiparole is NOT idempotent end-to-end —ipa-server-installwill refuse to run if IPA is already installed (it checks). That's fine; treat it as a guard. - Never run
ansible-playbookagainst production hosts without a--limitspecifier unless running the fullsite.ymlintentionally.
NixOS rules
- The
nixos/subdirectory is a flake. Usenix build ./nixos#<target>to validate beforenixos-rebuild switch. - Secrets are SOPS-encrypted with age. Never decrypt secrets into plaintext in the repo.
- The flake remote URL (used by the
Switch-nixalias on NixOS hosts) must be updated to point at the new Gitea URL after migration. See implementation plan Phase 4.
Stacks rules
- Changes to
stacks/docker/orstacks/raspi/take effect only when manually deployed. No automated apply runs against live containers. - Test compose changes with
docker compose config(validates interpolation) before deploying. secrets/stack-secrets.envandsecrets/*.txtare git-ignored. Never commit real secrets.
Secrets
- Pre-commit hook (installed by
scripts/install-hooks.sh) runs gitleaks before every commit. - CI also runs gitleaks on push. Both must pass.
- If gitleaks false-positives on a known-safe pattern, add it to
.gitleaks.tomlallowlist, not to the ignore-next-line comment.
Documentation pipeline
- Internal docs:
docs/internal/— full topology, credentials catalog (names only), runbooks. - External docs:
docs/external/— sanitized, no IPs, no internal hostnames, no credential refs. - Generated content lands in
docs/generated/— never edit these files by hand. - Run
./scripts/docs-build.shlocally to preview before pushing.
Directory notes
stacks/docker/andstacks/raspi/are populated viagit subtree— see implementation plan.nixos/is populated viagit subtree— the flake works from the subdirectory path.terraform/dns/wraps the Dynu provider. Read-only operations only until credentials are configured.ansible/roles/— each role has aREADME.mddescribing variables and expected host state.