[nomad-step-2] S2-fix-D — forgejo.hcl template fallback for missing kv/disinto/shared/forgejo #922

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

Part of the Nomad+Vault migration. Step-2 sub-bugfix (4/4). Replaces part of the consolidated #912.

Goal

Make nomad/jobs/forgejo.hcl deployable against an empty Vault (no kv/disinto/shared/forgejo path populated yet). Currently the template waits forever with Missing: vault.read(kv/data/disinto/shared/forgejo) and the alloc stays Client Status = pending, blocking the Step-1 "deploy forgejo" verification when no secrets have been imported yet.

Spec reference from #882 (S2.4):

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.

Scope

Pick one of two approaches (either is acceptable):

Approach A — template {{ with }}{{ else }} fallback

In nomad/jobs/forgejo.hcl, change the template block to tolerate the missing path:

template {
  destination = "secrets/forgejo.env"
  env         = true
  change_mode = "restart"
  data        = <<EOT
{{- with secret "kv/disinto/shared/forgejo" -}}
FORGEJO__security__SECRET_KEY={{ .Data.data.secret_key }}
FORGEJO__security__INTERNAL_TOKEN={{ .Data.data.internal_token }}
{{- else -}}
# Fallback — no kv/disinto/shared/forgejo entry yet; using deterministic defaults
FORGEJO__security__SECRET_KEY=dev-fallback-secret-key-do-not-use-in-prod
FORGEJO__security__INTERNAL_TOKEN=dev-fallback-internal-token-do-not-use-in-prod
{{- end -}}
EOT
}

Add error_on_missing_key = false if the template engine still 404s on the {{ with }} branch (behavior varies by Consul Template version; test in the LXC).

Approach B — auto-seed on deploy

In bin/disinto's --with forgejo path, before calling deploy.sh, call a small helper that checks for kv/disinto/shared/forgejo and, if absent, vault kv puts generated random values. Cleaner because the invariant "forgejo always reads real creds from Vault" holds on first boot.

Prefer Approach B — it produces real secrets on first boot rather than shared fallback strings that would matter if someone skipped the seeding.

Acceptance criteria

  • Fresh LXC, empty Vault (no .env imported), run:
    ./bin/disinto init --backend=nomad --with forgejo
    
    Forgejo alloc reaches Status = running, deployment successful, curl :3000/api/v1/version returns 200. Deploy completes within deploy.sh's 240s timeout.
  • With a populated KV path (e.g. after vault-import.sh has run), forgejo reads the real values — no fallback path taken. Verify by comparing nomad alloc exec <forgejo> env | grep SECRET_KEY with vault kv get -format=json kv/disinto/shared/forgejo.
  • Idempotent: re-running disinto init --backend=nomad --with forgejo is a no-op and does not overwrite seeded keys.
  • nomad job validate nomad/jobs/forgejo.hcl clean.

Non-goals

  • Not touching woodpecker or any other jobspec — they land in Step 3+ with their own seed/template shapes.
  • Not doing any real auth bootstrap (admin user creation, OAuth app reg) — that's Step 3's concern.

Labels / meta

  • [nomad-step-2] S2-fix-D — no hard dependencies.

Resolved by merged PR #923 (merge commit cfe1ef95) which landed all 4 sub-issue fixes at once. Closing as superseded.

Part of the Nomad+Vault migration. **Step-2 sub-bugfix (4/4).** Replaces part of the consolidated #912. ## Goal Make `nomad/jobs/forgejo.hcl` deployable against an empty Vault (no `kv/disinto/shared/forgejo` path populated yet). Currently the template waits forever with `Missing: vault.read(kv/data/disinto/shared/forgejo)` and the alloc stays `Client Status = pending`, blocking the Step-1 "deploy forgejo" verification when no secrets have been imported yet. Spec reference from #882 (S2.4): > 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. ## Scope Pick one of two approaches (either is acceptable): ### Approach A — template `{{ with }}{{ else }}` fallback In `nomad/jobs/forgejo.hcl`, change the template block to tolerate the missing path: ```hcl template { destination = "secrets/forgejo.env" env = true change_mode = "restart" data = <<EOT {{- with secret "kv/disinto/shared/forgejo" -}} FORGEJO__security__SECRET_KEY={{ .Data.data.secret_key }} FORGEJO__security__INTERNAL_TOKEN={{ .Data.data.internal_token }} {{- else -}} # Fallback — no kv/disinto/shared/forgejo entry yet; using deterministic defaults FORGEJO__security__SECRET_KEY=dev-fallback-secret-key-do-not-use-in-prod FORGEJO__security__INTERNAL_TOKEN=dev-fallback-internal-token-do-not-use-in-prod {{- end -}} EOT } ``` Add `error_on_missing_key = false` if the template engine still 404s on the `{{ with }}` branch (behavior varies by Consul Template version; test in the LXC). ### Approach B — auto-seed on deploy In `bin/disinto`'s `--with forgejo` path, before calling `deploy.sh`, call a small helper that checks for `kv/disinto/shared/forgejo` and, if absent, `vault kv put`s generated random values. Cleaner because the invariant "forgejo always reads real creds from Vault" holds on first boot. Prefer **Approach B** — it produces real secrets on first boot rather than shared fallback strings that would matter if someone skipped the seeding. ## Acceptance criteria - Fresh LXC, empty Vault (no `.env` imported), run: ``` ./bin/disinto init --backend=nomad --with forgejo ``` Forgejo alloc reaches `Status = running`, deployment `successful`, `curl :3000/api/v1/version` returns 200. Deploy completes within deploy.sh's 240s timeout. - With a populated KV path (e.g. after `vault-import.sh` has run), forgejo reads the real values — no fallback path taken. Verify by comparing `nomad alloc exec <forgejo> env | grep SECRET_KEY` with `vault kv get -format=json kv/disinto/shared/forgejo`. - Idempotent: re-running `disinto init --backend=nomad --with forgejo` is a no-op and does not overwrite seeded keys. - `nomad job validate nomad/jobs/forgejo.hcl` clean. ## Non-goals - Not touching woodpecker or any other jobspec — they land in Step 3+ with their own seed/template shapes. - Not doing any real auth bootstrap (admin user creation, OAuth app reg) — that's Step 3's concern. ## Labels / meta - `[nomad-step-2] S2-fix-D` — no hard dependencies. --- Resolved by merged PR #923 (merge commit cfe1ef95) which landed all 4 sub-issue fixes at once. Closing as superseded.
dev-bot added the
backlog
label 2026-04-16 21:10:33 +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#922
No description provided.