Archived
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
77 lines
3.8 KiB
Markdown
77 lines
3.8 KiB
Markdown
# 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 plan` before `terraform apply`.
|
|
- Never commit `.tfstate` or `.tfvars` files — they go in `.gitignore`.
|
|
- API tokens and secrets go in `terraform.tfvars` (git-ignored) or environment variables.
|
|
- If `plan` shows unexpected destruction of real resources, stop and ask.
|
|
|
|
## Ansible rules
|
|
|
|
- Always use `--check --diff` before the first real run against any host.
|
|
- The `proxmox-hardening` role is safe to re-run (idempotent). Still confirm first.
|
|
- The `freeipa` role is NOT idempotent end-to-end — `ipa-server-install` will refuse to
|
|
run if IPA is already installed (it checks). That's fine; treat it as a guard.
|
|
- Never run `ansible-playbook` against production hosts without a `--limit` specifier
|
|
unless running the full `site.yml` intentionally.
|
|
|
|
## NixOS rules
|
|
|
|
- The `nixos/` subdirectory is a flake. Use `nix build ./nixos#<target>` to validate
|
|
before `nixos-rebuild switch`.
|
|
- Secrets are SOPS-encrypted with age. Never decrypt secrets into plaintext in the repo.
|
|
- The flake remote URL (used by the `Switch-nix` alias 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/` or `stacks/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.env` and `secrets/*.txt` are 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.toml` allowlist,
|
|
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.sh` locally to preview before pushing.
|
|
|
|
## Directory notes
|
|
|
|
- `stacks/docker/` and `stacks/raspi/` are populated via `git subtree` — see implementation plan.
|
|
- `nixos/` is populated via `git 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 a `README.md` describing variables and expected host state.
|