Content-change pass following the extraction from the app monorepo (this repo
now stands alone, sourced via git filter-repo to preserve history):
- terraform/variables.tf, secrets.tf, modules/thermograph-host: remove every
app-secret Terraform variable (postgres_password, auth_secret, VAPID keys,
registry_token, Discord/SMTP creds, ...) and the random_password/random_id
generators. The SOPS+age vault (deploy/secrets/*.yaml) is now the sole
source of app secrets, rendered at deploy time by deploy/render-secrets.sh;
Terraform renders only a non-secret /etc/thermograph-topology.env (sizing,
routing) via the renamed thermograph-topology.env.tftpl template.
- hosts gains a required app_image_tag field: the host's own checkout is now
this infra repo, not the app repo, so there is no "current commit" to
derive an image tag from — every host pins one explicitly. repo_url now
points at this repo (private; typically needs an embedded read token).
- deploy.sh: IMAGE_TAG is now required from the environment instead of
derived via `git rev-parse HEAD` of the (now infra-repo) checkout, which
would have silently resolved to the wrong or a nonexistent tag.
- New terraform/modules/gcp-host: creates a GCE VM + minimal VPC/firewall
only, then feeds its IP into the same thermograph-host module every
SSH-managed host already uses — one provisioning path regardless of how a
host came to exist. var.gcp_hosts defaults to {}, so no google_* resource
is planned and the provider is never invoked without it (verified: plan
and validate succeed with no GCP credentials configured).
- terraform/README.md, ACCESS.md (renamed from INFRA.md), README.md: updated
for the new secrets model, the GCP scaffold, and this repo's own identity.
Verified: terraform fmt/validate/init clean; plan succeeds against realistic
dummy hosts (prod+beta shape) and against a populated gcp_hosts entry (plans
6 resources with no live credentials, confirming the composition wires
correctly end to end).
33 lines
1.6 KiB
Text
33 lines
1.6 KiB
Text
# /etc/thermograph-topology.env — RENDERED BY TERRAFORM. Do not edit on the host;
|
|
# change the tfvars and re-apply. Non-secret sizing/routing config ONLY; every app
|
|
# secret (POSTGRES_PASSWORD, THERMOGRAPH_AUTH_SECRET, VAPID keys, REGISTRY_TOKEN,
|
|
# Discord/SMTP creds, ...) lives in /etc/thermograph.env instead, rendered at deploy
|
|
# time from the SOPS+age vault by deploy/render-secrets.sh (see deploy.sh). Both
|
|
# files are sourced before `docker compose` runs — this one first, so a same-named
|
|
# vault value (there shouldn't be one) would still win.
|
|
|
|
# Port uvicorn binds inside the container (compose publishes it on the host).
|
|
PORT=${app_port}
|
|
|
|
# --- Container sizing (consumed by docker-compose.yml interpolation) -------------
|
|
# Terraform sizes the containers per host. Defaults in compose are 4 / 4 / 2 / 8g.
|
|
WORKERS=${workers}
|
|
APP_CPUS=${app_cpus}
|
|
DB_CPUS=${db_cpus}
|
|
DB_MEMORY=${db_memory}
|
|
# "latest-pg18" (the default) matches today's behavior. Pin an exact minor before
|
|
# any host of this stack could ever replicate with another (docker-compose.yml).
|
|
TIMESCALEDB_TAG=${timescaledb_tag}
|
|
%{ if openmeteo ~}
|
|
|
|
# --- Self-hosted Open-Meteo archive (docker-compose.openmeteo.yml) ---------------
|
|
# Host rclone mount of the ERA5 object-storage bucket; the overlay bind-mounts it
|
|
# into the Open-Meteo containers. THERMOGRAPH_ARCHIVE_URL is set by the overlay.
|
|
OM_DATA_DIR=${om_data_dir}
|
|
%{ endif ~}
|
|
|
|
# --- Serving --------------------------------------------------------------------
|
|
THERMOGRAPH_BASE=${base}
|
|
THERMOGRAPH_BASE_URL=${base_url}
|
|
# Secure cookie is only sent over HTTPS: 1 behind Caddy TLS, 0 on a plain-HTTP host.
|
|
THERMOGRAPH_COOKIE_SECURE=${cookie_secure}
|