- Makefile 56.4%
- HCL 34.5%
- Jinja 9.1%
|
|
||
|---|---|---|
| ansible | ||
| docs | ||
| tofu | ||
| .gitignore | ||
| AGENTS.md | ||
| GLOSSARY.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
infra-forge
OpenTofu + Ansible that provision and maintain a self-hosted Forgejo on the Pit homelab.
OpenTofu creates the LXC Guest on the Proxmox Node, Ansible installs Forgejo on it natively, and NPM publishes it from the Edge. It exists so the lab can host its own git service — repositories, issues, pull requests and CI — instead of depending on a public one, and doubles as the worked example of the three-layer pattern (Guest, Edge, service) that the other sites copy.
Requirements
- A Proxmox VE Node reachable from the machine that runs OpenTofu, and an API token for it.
- OpenTofu
>= 1.8. - Ansible on the machine that runs the playbook.
- An admin account on the Edge (NPM), with
sshddisabled in its LXC and the router forwarding WAN22/TCPto it.
Environment variables
No secret is committed; each layer reads its own .env at run time. The names
each layer needs are below, and tofu/.env.example / tofu/npm/.env.example
show the shape.
| File | Variables |
|---|---|
tofu/.env |
PROXMOX_VE_ENDPOINT, PROXMOX_VE_API_TOKEN |
tofu/npm/.env |
NGINXPROXYMANAGER_URL, NGINXPROXYMANAGER_USERNAME, NGINXPROXYMANAGER_PASSWORD |
ansible/.env |
ANSIBLE_VAULT_PASSWORD (the gitignored ansible/vault-pass is generated from it) |
Running
The deploy is packaged as Make Targets at the repo root: make prod runs the
whole thing, and make help (or a bare make) lists the Targets and deploys
nothing.
make # list the Targets (deploys nothing)
make prod # the whole deploy: the six steps, in order, stopping on the first failure
make prod is the six steps in the order a deploy requires — snapshot, Guest,
Edge, service, verify, state-backup — one after the other, stopping on the first
failure, with each apply gated exactly as its own Target gates it. The order is
Guest, then Edge, then service: the Edge has to be published before the runner
is expected to reach it. Each step is also a Target of its own, and the read-only
and utility Targets round out the surface:
# one step at a time
make snapshot # pre-flight: a date-stamped Proxmox snapshot of the PROD Guest
make guest # Guest Stack: the LXC, with the Operator key injected
make edge # Edge Stack: the proxy host, TLS lookup and git SSH stream
make service # service layer: Forgejo installed and configured on the Guest
make verify # the external checks, from the WAN
make state-backup # post-flight: both Stacks' state, encrypted, outside the repo
# read-only — these mutate nothing
make guest-plan # the Guest Stack plan
make edge-plan # the Edge Stack plan
make service-check # the service layer's --check --diff run
# utilities
make ssh # a shell on the PROD Guest
make fmt # tofu fmt across both Stacks
make validate # tofu validate the Guest Stack
make worktree # a worktree + fresh branch off origin/main, secrets linked, state seeded
The three OpenTofu/Ansible layers the Targets wrap, the raw commands for a
machine without make, and the plan-review and environment-word gates each apply
carries, are in the deploy runbook under docs/.
Repository overview
tofu/ the Guest · tofu/npm/ the Edge · ansible/ the service · docs/ the detailed documentation.
For agents
Read AGENTS.md: the working context for this repository.
Contributing
Work on a branch and open a pull request for a human to review — nothing goes
directly to main. A pull request merges without required approvals.
License
MIT — see LICENSE.