- Python 35.2%
- Jinja 29.4%
- HCL 25.7%
- JavaScript 3.8%
- Just 3.1%
- Other 2.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .forgejo/workflows | ||
| ansible | ||
| dns | ||
| docs | ||
| images/debian | ||
| opentofu | ||
| scripts | ||
| services | ||
| tests | ||
| .env | ||
| .env.example | ||
| .gitignore | ||
| .sops.yaml | ||
| AGENTS.md | ||
| ansible-refactoring-plan.md | ||
| assh.yml | ||
| justfile | ||
| README.md | ||
Infrastructure Monorepo
OpenTofu provisions the Proxmox infrastructure; Ansible configures guests. The root justfile provides the command interface.
Layout
| Directory | Ownership |
|---|---|
opentofu/ |
Guests, storage registration, HA, backup jobs, seed and inventory |
dns/ |
Static Porkbun DNS records in an independent state |
images/debian/ |
Direct Packer builds and explicitly approved template catalog |
ansible/ |
Guest software, configuration and generated inventory consumers |
services/ |
Workload configuration and operational SKILL.md guides |
docs/ |
Architecture, operations/recovery instructions and deferred work |
Both OpenTofu roots use locked remote S3 state in Garage. Keep independent restricted recovery copies; state and plan artifacts contain credentials.
Prerequisites and secrets
Install just >=1.59, OpenTofu >=1.13 and <2.0, Python 3, Ansible, SOPS/age,
and an SSH client. Image builds additionally require Packer >=1.14 and <2.0.
Keep the age key at ~/.config/age/keys.txt; agent-run playbooks pass the
existing Vault password file directly to Ansible without reading it.
just --list
just secrets-decrypt
The encrypted .env remains the source for .env.local. Just loads only the
plaintext local file through a small compatibility adapter in the existing
Python workflow helper. It quotes the legacy bare JSON SSH-key array in memory,
without rewriting either file or interpreting their contents as shell code.
Recipe listing and initial decryption work before .env.local exists.
Never print the adapter's dotenv output; it contains credentials.
Provision and configure
Proxmox and public DNS use independent state. See the operations and recovery guide.
just tofu-init
just tofu-plan
# Review the saved plan and obtain deployment authorization first.
just tofu-apply
just ansible-deps
just ansible-check --limit openclaw
# Requires separate authorization for guest configuration.
just ansible-site-limit openclaw
The apply recipe consumes the exact saved plan and rejects modified artifacts
or changed configuration. just tofu-plan-offline is an unsaved stale-state
preview. Generated inventory comes from state outputs; the Ansible recipes
regenerate it before check/site/role runs and preserve stopped-host filtering.
Command interface
Taskfile has been replaced. Names use hyphens and arguments are positional;
there are no CLI_ARGS=... strings or wildcard recipe names to construct.
just tofu-cli show .artifacts/reviewed.plan
just tofu-state-backup /absolute/independent/infrastructure.tfstate
just dns-plan
just ansible-update zigbee2mqtt
just ansible-role pihole --limit pihole
just ssh-forget openclaw
just image-build images/debian/build.pkrvars.hcl
Arguments with spaces or shell metacharacters remain literal arguments. The
old refresh aliases are unnecessary: planning refreshes by default and applying
uses the reviewed saved artifact. just home-deploy applies that plan and then
configures all hosts, requiring explicit authorization for both operations.
Local checks
just tofu-init
just dns-init
just check
Checks validate both roots, run mocked OpenTofu contracts and Python workflow/ recipe tests. Recipe integration tests use fake executables; they do not apply plans, decrypt real secrets or deploy services. Check/live-service results remain separate from first-image boot evidence. Image builds use direct Packer commands and a separate Ansible smoke playbook; see the architecture decision.
Operations
- OpenTofu operations, state ownership and backend recovery
- Ansible deployment and maintenance
- Proxmox and image operations
- On-demand Debian images
Consult a workload's services/<name>/SKILL.md before changing or diagnosing it.
Commits, applies, image builds/tests and deployments require explicit reviewed
authorization; changing the command runner does not grant it.