[nomad-step-2] S2.4 — forgejo.hcl reads admin creds from Vault via template stanza #882

Closed
opened 2026-04-16 15:26:33 +00:00 by dev-bot · 0 comments
Collaborator

Part of the Nomad+Vault migration. Step 2 — Vault policies + workload identity + secrets import. Blocked by: #879 (S2.1), #881 (S2.3).

Goal

Upgrade nomad/jobs/forgejo.hcl (from S1.1 #840) to read its admin password and (placeholder) OAuth credentials from Vault via template stanzas, using the service-forgejo role defined in S2.3. This is the first real Vault-integrated jobspec; later service jobs (Woodpecker Step 3, agents Step 4, edge Step 5) follow the same pattern.

Scope

Update nomad/jobs/forgejo.hcl:

  • Add vault {} to the job or group stanza:
    vault {
      role = "service-forgejo"
    }
    
  • Replace inline env vars that contain secrets with a template block rendering /secrets/forgejo.env:
    template {
      destination = "secrets/forgejo.env"
      env         = true
      change_mode = "restart"
      data        = <<EOT
    FORGEJO__security__SECRET_KEY={{ with secret "kv/disinto/shared/forgejo" }}{{ .Data.data.secret_key }}{{ end }}
    FORGEJO__security__INTERNAL_TOKEN={{ with secret "kv/disinto/shared/forgejo" }}{{ .Data.data.internal_token }}{{ end }}
    EOT
    }
    
  • Non-secret config (DB type, ports, ROOT_URL, disable registration) stays inline — those aren't secrets and don't need Vault.
  • Add a fallback-friendly template: if the Vault KV path doesn't yet have the key (empty factory), render a generated default and log a warning. This keeps the "no secrets imported yet" path (empty Vault) working so a fresh-LXC demo still stands up.

Seed the KV path in tools/vault-import.sh (S2.2) or a small helper tools/vault-seed-forgejo.sh so a clean install without an old-stack import still has the keys.

Acceptance criteria

  • Fresh LXC + S2.1 + S2.3 applied + seeded KV → ./bin/disinto init --backend=nomad --with forgejo deploys forgejo, alloc reaches running + healthy.
  • nomad alloc exec <forgejo> env | grep FORGEJO__security__SECRET_KEY returns the same value written to kv/disinto/shared/forgejo/secret_key (verify via vault kv get).
  • Changing the Vault KV value + nomad alloc restart <forgejo> restarts the task with new env.
  • No secret values appear in nomad job inspect forgejo output (they live only in the alloc's secrets dir).
  • nomad job validate nomad/jobs/forgejo.hcl clean.

Non-goals

  • No OAuth app registration (that's per-service; lands in Step 3 when Woodpecker needs it).
  • No data-migration import (Forgejo starts empty — mirror pulls repo content on cutover).

Labels / meta

  • [nomad-step-2] S2.4 — blocked by #879, #881.
Part of the Nomad+Vault migration. **Step 2 — Vault policies + workload identity + secrets import.** **Blocked by: #879 (S2.1), #881 (S2.3).** ## Goal Upgrade `nomad/jobs/forgejo.hcl` (from S1.1 #840) to read its admin password and (placeholder) OAuth credentials from Vault via template stanzas, using the `service-forgejo` role defined in S2.3. This is the first real Vault-integrated jobspec; later service jobs (Woodpecker Step 3, agents Step 4, edge Step 5) follow the same pattern. ## Scope Update `nomad/jobs/forgejo.hcl`: - Add `vault {}` to the job or group stanza: ``` vault { role = "service-forgejo" } ``` - Replace inline env vars that contain secrets with a `template` block rendering `/secrets/forgejo.env`: ``` template { destination = "secrets/forgejo.env" env = true change_mode = "restart" data = <<EOT FORGEJO__security__SECRET_KEY={{ with secret "kv/disinto/shared/forgejo" }}{{ .Data.data.secret_key }}{{ end }} FORGEJO__security__INTERNAL_TOKEN={{ with secret "kv/disinto/shared/forgejo" }}{{ .Data.data.internal_token }}{{ end }} EOT } ``` - Non-secret config (DB type, ports, ROOT_URL, disable registration) stays inline — those aren't secrets and don't need Vault. - Add a fallback-friendly template: if the Vault KV path doesn't yet have the key (empty factory), render a generated default and log a warning. This keeps the "no secrets imported yet" path (empty Vault) working so a fresh-LXC demo still stands up. Seed the KV path in `tools/vault-import.sh` (S2.2) or a small helper `tools/vault-seed-forgejo.sh` so a clean install without an old-stack import still has the keys. ## Acceptance criteria - Fresh LXC + S2.1 + S2.3 applied + seeded KV → `./bin/disinto init --backend=nomad --with forgejo` deploys forgejo, alloc reaches `running` + `healthy`. - `nomad alloc exec <forgejo> env | grep FORGEJO__security__SECRET_KEY` returns the same value written to `kv/disinto/shared/forgejo/secret_key` (verify via `vault kv get`). - Changing the Vault KV value + `nomad alloc restart <forgejo>` restarts the task with new env. - No secret values appear in `nomad job inspect forgejo` output (they live only in the alloc's secrets dir). - `nomad job validate nomad/jobs/forgejo.hcl` clean. ## Non-goals - No OAuth app registration (that's per-service; lands in Step 3 when Woodpecker needs it). - No data-migration import (Forgejo starts empty — mirror pulls repo content on cutover). ## Labels / meta - `[nomad-step-2] S2.4` — blocked by #879, #881.
dev-bot added the
backlog
label 2026-04-16 15:26:33 +00:00
dev-bot self-assigned this 2026-04-16 17:15:37 +00:00
dev-bot added
in-progress
and removed
backlog
labels 2026-04-16 17:15:37 +00:00
dev-bot removed their assignment 2026-04-16 17:50:37 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: disinto-admin/disinto#882
No description provided.