OpenTofu + Ansible that provision and maintain a self-hosted Forgejo on the Pit homelab. https://forgejo.thepit.space
  • Makefile 56.4%
  • HCL 34.5%
  • Jinja 9.1%
Find a file
2026-10-10 00:04:18 +00:00
ansible fix(forgejo): admit the PR loop's LAN webhooks (ALLOWED_HOST_LIST = private) (#58) 2026-10-10 00:04:18 +00:00
docs fix(forgejo): admit the PR loop's LAN webhooks (ALLOWED_HOST_LIST = private) (#58) 2026-10-10 00:04:18 +00:00
tofu Agent workflow: branch off main, rehearse on PRE, never act on PROD, tear PRE down (#54) 2026-10-07 16:40:43 +00:00
.gitignore Ignore worktrees 2026-10-06 13:58:52 +02:00
AGENTS.md AGENTS.md: keep comments minimal; propose a docs page instead (#55) 2026-10-07 16:45:32 +00:00
GLOSSARY.md Agent workflow: branch off main, rehearse on PRE, never act on PROD, tear PRE down (#54) 2026-10-07 16:40:43 +00:00
LICENSE docs: add the docs tree — entry point, architecture, runbooks, ADRs, glossary, license (#13) 2026-10-06 11:03:37 +00:00
Makefile Agent workflow: branch off main, rehearse on PRE, never act on PROD, tear PRE down (#54) 2026-10-07 16:40:43 +00:00
README.md Agent workflow: branch off main, rehearse on PRE, never act on PROD, tear PRE down (#54) 2026-10-07 16:40:43 +00:00

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 sshd disabled in its LXC and the router forwarding WAN 22/TCP to 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.