infra-sync: refuse to render dev's vault onto a host that is not dev
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
PR build (required check) / build-backend (pull_request) Has been skipped
shell-lint / shellcheck (pull_request) Successful in 6s
PR build (required check) / build-frontend (pull_request) Has been skipped
PR build (required check) / validate-observability (pull_request) Has been skipped
PR build (required check) / gate (pull_request) Successful in 1s

sync-dev rendered deploy/secrets/dev.yaml into /etc/thermograph.env
unconditionally. That path is dev's env file — and it is also BETA's, on the
box beta is still running on until the cutover completes. With the dev checkout
present, the next push to dev would have overwritten the live env file of the
environment currently serving beta.thermograph.org: its containers would keep
running (env_file is read at container start) and then come up on the next
deploy pointed at dev's database password.

The earlier run only escaped this by failing first on the missing checkout.

Gate the render on the host's own secrets-env marker, which provision-dev.sh
flips to 'dev' only after beta has vacated. Until then the job syncs the
checkout and skips the render loudly rather than failing, so the ordering is
enforced by the host's own statement of what it is rather than by remembering
to do the steps in the right order.
This commit is contained in:
Emi Griffith 2026-07-26 00:04:25 -07:00
parent d138f00a20
commit e393a7a111
2 changed files with 37 additions and 2 deletions

View file

@ -61,6 +61,30 @@ jobs:
cd /opt/thermograph-dev cd /opt/thermograph-dev
git fetch --prune origin dev git fetch --prune origin dev
git reset --hard origin/dev git reset --hard origin/dev
echo "synced to $(git log --oneline -1)"
# RENDER ONLY IF THIS HOST IS ACTUALLY DEV.
#
# dev's env file is /etc/thermograph.env — the same path beta uses,
# and during the vps1/vps2 cutover beta is STILL ON VPS1. Rendering
# unconditionally would overwrite the live env file of the
# environment currently serving beta.thermograph.org with dev's
# credentials: beta's running containers would survive (env_file is
# read at container start) and then come up wrong on its next
# deploy, pointed at dev's database password.
#
# The host marker is the box's own statement of which environment it
# is, and it is the right authority for "is it safe to write this
# file here". It flips to `dev` in provision-dev.sh, which is run
# only after beta has vacated. Until then this skips loudly rather
# than failing: the checkout sync above is still useful and correct.
marker=$(cat /etc/thermograph/secrets-env 2>/dev/null || true)
if [ "$marker" != dev ]; then
echo "!! /etc/thermograph/secrets-env says '${marker:-<unset>}', not 'dev'."
echo "!! Skipping the secrets render — this host is not dev yet, and"
echo "!! /etc/thermograph.env here belongs to '${marker:-another environment}'."
exit 0
fi
if [ -f infra/deploy/render-secrets.sh ]; then if [ -f infra/deploy/render-secrets.sh ]; then
. infra/deploy/render-secrets.sh . infra/deploy/render-secrets.sh
# SKIP_COMMON is dev's standing rule, not a preference: common.yaml # SKIP_COMMON is dev's standing rule, not a preference: common.yaml
@ -69,7 +93,6 @@ jobs:
THERMOGRAPH_SECRETS_SKIP_COMMON=1 \ THERMOGRAPH_SECRETS_SKIP_COMMON=1 \
render_thermograph_secrets /opt/thermograph-dev/infra dev /etc/thermograph.env render_thermograph_secrets /opt/thermograph-dev/infra dev /etc/thermograph.env
fi fi
echo "synced to $(git log --oneline -1)"
sync-beta: sync-beta:
if: github.ref_name == 'main' if: github.ref_name == 'main'

View file

@ -278,7 +278,19 @@ sudo bash /opt/thermograph-dev/infra/deploy/provision-dev.sh # clones if absen
``` ```
The script writes `/etc/thermograph/secrets-env` = `dev` and removes any The script writes `/etc/thermograph/secrets-env` = `dev` and removes any
`deploy-mode` marker. Then deploy: `deploy-mode` marker.
**That marker flip is load-bearing, and it is why this step comes after step 9.**
dev's env file is `/etc/thermograph.env` — the very path beta uses while beta is
still on vps1. `infra-sync`'s `sync-dev` job refuses to render unless the marker
already says `dev`, so until you run this script it syncs the checkout and skips
the render with a loud message. Flip the marker before beta has vacated and the
next dev push overwrites beta's live env file with dev's credentials; beta's
running containers survive it and then come up wrong on their next deploy.
(The checkout itself is safe to create at any time — only the render is gated.)
Then deploy:
``` ```
cd /opt/thermograph-dev cd /opt/thermograph-dev