The pipeline's validate step failed before terraform even ran:
load_admin_creds: EMPTY creds: MINIO_ADMIN_USER MINIO_ADMIN_PASSWORD
— VAULT_TOKEN cannot read the matching secrets/* paths
scripts/load_admin_creds.sh unconditionally reads secrets/minio/admin
(rootUser/rootPassword) to configure the minio-buckets provider in
live/terragrunt.hcl, used by live/s3 to actually create buckets. uralkal's
minio.admin was never enabled (only per-app minio.apps.* entries existed)
so that Vault path didn't exist yet. Using the same admin creds
(tfstate/09Eat4eiMcg5) already set on every minio.apps.* entry — this is
the real external minio endpoint's admin account, not per-app.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Root cause of documentations-api's 'panic: invalid system auth format'
crash loop: uralkal's django_auth had username/password set manually but
no matching token — with generate:true and no manual token, terraform
generates an INDEPENDENT random 40-char string for token, unrelated to
username/password. Any consumer decoding token as base64(username:password)
(documentations-api's sarex_backend client does exactly this) gets garbage
with no ':' separator and panics.
Fixed by using the same username/password/token triple as vad
(hagen013/zealot096), rather than deriving a new token for uralkal's own
credentials, per request.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
No terraform-managed rabbitmq vhost/user named 'processing' existed for
ugmk (infrastructure.yaml's rabbitmq.users has no such entry), yet
processing's Vault role already has rabbitmq/apps/processing in
read_paths and its engine templates read username/password from there.
Added as an opaque literal secret, matching the existing user sarex on
the broker rather than provisioning a new dedicated vhost/user.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
namespaces/databases/buckets/rabbitmq vhosts for all app namespaces
(mirrors the vad set: workspaces, eav, notes, rfi, checklists, contracts,
django, documentations, processing, flows, issues, bim, attachments, bi,
comparisons, drawings, inspections, mapper, measurements, subscriptions,
system-log, transmittal, iam, pm, message-hub, cde).
vault: applications/read_paths for the 26 apps that need Vault secrets,
common.django_auth/rsa_keys/smtp_auth, minio.apps (admin creds tfstate/
09Eat4eiMcg5 via s3-proxy, matching the iac s3-proxy component), kafka.apps
(random creds, kafka users still need manual SCRAM creation like vad).
cde-env carries the same structure as vad's but without DATABASE_URL
(documentations DB creds not known until this DB is actually created) and
without a real Camunda/Zitadel-issued secret — those are follow-ups.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
S3 bucket names must be at least 3 characters, so a bucket called "pm" cannot
be created (live/s3 apply failed on it). Drop the pm bucket and point the
minio/apps/pm secret at the existing django bucket.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
TF_VAR_secrets crossed the 128 KiB per-env-string kernel limit (each
regcred entry carries the full base64 dockerconfigjson, ~4.7 KiB), so
terraform init on live/secrets failed with "argument list too long" and
run_all_stacks aborted before any apply. Keep image_pull_secret only for
the 17 namespaces terraform already manages; the rest get regcred by hand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The entry used v2-only keys (ownership/targets/extra_fields) but was named
via `name`, so live/secrets failed on `secret.id`. Also v2 `data` values are
base64 in k8s-secret (base64decode), so the plaintext values are now encoded.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
pm: postgres, rabbitmq, own kafka producer (self-contained
generate:true, message-hub reads the same credentials), S3.
message-hub: reads pm's postgres (same db/user, separate vault path)
and pm's kafka creds, own S3 bucket.
cde: single opaque vault/apps/cde blob per its CONFIGURATION.md.
Reused the real PUBLIC_KEY/CAMUNDA_CLIENT_SECRET/Telegram
token+group already shared identically between ugmk and yc-k8s-test.
AMQP creds pulled via secret_ref from the already-provisioned
rabbitmq/apps/cde secret. DATABASE_URL composed with the real
documentations postgres password.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Needed by the env-override patches in the iac repo (flows/backend.yaml,
flows/celery.yaml, issues/backend-s3.yaml, issues/celery-s3.yaml) which
source a vault-agent kafka secret that didn't exist for these apps yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
iam reads django's own postgres credentials (per explicit
instruction - same underlying database), written to its own
apps/iam/postgres vault path via a second dependency-based secrets
entry pointing at the same cluster/db/user as django-postgres. Kafka
and S3 follow the established self-contained/admin-creds patterns.
Also added django_zitadel_access_token to the shared django_auth
extra fields (placeholder, non-functional, only needs to be present).
faas has no vault dependencies at all - namespace only, for regcred.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Same shapes already proven for sarex-contour: kafka for
inspections/mapper/system-log via the self-contained generate:true
path (field shape mismatch with the v2 type), S3 via the eav/django
admin credentials. subscriptions gets postgis declared per explicit
instruction - not installed on vad's postgres yet, needs to be done
out of band since I have no SSH access there.
transmittal additionally needs a one-off opaque secret at
vault/apps/transmittal (mailgun API key) - a random placeholder via
the v2 secrets type=opaque/random_keys, since there's no real mailgun
account and the app only needs the field to be present.
5 pure-frontend apps also wired in this push (cross-section,
document-link, prescriptions, projects, stamp-verification) - no
vault dependencies, namespaces added for regcred only.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
processing needs smtp_auth (newly enabled, generate:true placeholder
- non-functional SMTP but structurally valid so the pod starts).
flows reads the already-existing apps/documentations/postgres secret
(read-only grant, no new database). issues' S3 uses the eav admin
creds like django/documentations; note the app itself hardcodes the
bucket name to "rfi" instead of "issues" - pre-existing bug, not
fixed here. bim only needs its own postgres, same as sarex-contour.
Pinned the shared vault/common/django_auth to the real sarex-backend
superuser (hagen013) so issues' API calls actually authenticate -
the other consumers (workspaces, django, documentations, notes,
contracts) only use the raw token for inter-service basic auth trust
and don't care about the specific value.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
django and documentations get postgres, rabbitmq (django + a shared
cde vhost that documentations' hasher/marks depend on), and rsa_keys
(already enabled). Kafka for django uses the self-contained
generate:true path, same reasoning as notes/contracts.
S3 for both uses the eav admin credentials directly (per explicit
instruction) rather than the two-push bucket dance - buckets are
still ordered via live/s3 so they physically exist, but the vault
secret is wired with the admin key/secret right away.
documentations also needs two extra django_auth fields it reads as
raw JSON (documentations_s3_service_account_json and
_zitadel_account_json - a structurally-valid but non-functional
placeholder RSA key, same approach used for sarex-contour, since the
app only needs a decodable PEM at startup, not a working Zitadel
integration).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
k8s-secret's contract check and its rabbitmq_outputs_map lookup both
only honor depends_on.rabbitmq_vhost/rabbitmq_user - the vhost/user
fallback never fires because the primary keys default to "" rather
than being absent, so try() never falls through to them.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
checklists needs only postgres + the already-enabled rsa_keys, fully
wired in one push. notes/rfi/contracts also get real rabbitmq
vhosts/users (v2 secrets type, field shapes match app templates) and
self-contained kafka creds via the legacy generate:true path (same
precedent as sarex-contour - the v2 kafka type writes flat fields but
these apps read a nested auth.* object, so it doesn't fit).
S3 for notes/rfi/contracts is deliberately left out: same nested
client.endpoint shape mismatch as eav. Buckets ordered via live/s3;
vault.data.infrastructure.minio.apps entries follow in stage 2 once
the real generated credentials are known.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds the eav database and app policy/role/rsa_keys wiring. The minio
S3 secret for eav is deliberately left unset here: the new v2 secrets
contract writes flat s3 fields that don't match eav's expected nested
client.endpoint shape, so that secret has to be hand-populated with
the real live/s3-generated credentials in a follow-up commit. Until
then eav's pod will not start (agent-pre-populate-only needs every
declared secret path to resolve).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Enables app-level policy/role creation for vad (was fully disabled),
adds the workspaces database and a v2 secrets entry that pulls the
generated password from live/database via dependency block.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The module's top-level infra merge replaces the role block wholesale
rather than deep-merging, so overriding only service_account_names
silently dropped the default service_account_namespaces on apply.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>