Skip to main content

Database Bootstrap Troubleshooting

Guidance for Cloud SQL application database setup after infrastructure (Terraform) provisioning and before or after Helm deployment.

Bootstrap script: scripts/bighammer_db_setup.sql in the mirrored bighammer chart package.

Related: Infrastructure — Cloud SQL, Secret Manager Secrets, Scripts Reference — bighammer_db_setup.sql

Overview

Terraform provisions:

  • Cloud SQL instance and application database (e.g. bighammer_db_<env>)
  • Database users: postgres, bh_dev_user, bh_app_user
  • GSM passwords: bh-dev-user-password, bh-app-user-password, db-postgres-password

Terraform does not create application schemas or grants. Run bighammer_db_setup.sql as the postgres user on the application database.

Terraform (instance, database, users, GSM passwords)
→ bighammer_db_setup.sql as postgres (on application database)
→ Helm deploy / pod startup

Running the bootstrap script before app deployment avoids schema ownership and permission errors.

If Helm deploys before bootstrap, pods may create schemas as the wrong user. Recovery steps are in Recovery — wrong schema ownership below.

Prerequisites

Verify before running bootstrap or debugging pod errors:

CheckExpected
Application databaseExists; name matches POSTGRES_DB in Helm values
Usersbh_dev_user, bh_app_user exist (Terraform)
GSM passwordsbh-dev-user-password, bh-app-user-password match Cloud SQL users
Helm migration userPOSTGRES_USER: bh_dev_user
Helm runtime userBH_APP_USER: bh_app_user
remoteSecrets.postgres.passwordbh-dev-user-password
Bootstrap executedFull bighammer_db_setup.sql on application database (not maintenance DB only)
Bootstrap identityScript run as postgres (password: db-postgres-password)

Credential model (dual-role)

K8s env varsDB userGSM secretPurpose
POSTGRES_USER / POSTGRES_PASSWORDbh_dev_userbh-dev-user-passwordAlembic, migrations, DDL
BH_APP_USER / BH_APP_USER_PASSWORDbh_app_userbh-app-user-passwordRuntime SQLAlchemy queries (DML)

Keycloak server DB (separate): keycloak_db_user / bh-kcdbpwd on keycloak_db_<env>.

Running bighammer_db_setup.sql

When the database and users already exist (typical Terraform flow):

  1. Connect as postgres to the application database (or connect to postgres then \connect <app_db>).
  2. Comment out CREATE DATABASE in the script.
  3. Set \connect and GRANT CONNECT ON DATABASE to your application database name (e.g. bighammer_db_<env>).
  4. Role creation (IF NOT EXISTS) is safe to run; skip if users already exist.
  5. Run the full script: schemas, bh_dev_user grants, bh_app_user grants, default privileges.
  6. Confirm CREATE EXTENSION IF NOT EXISTS vector SCHEMA catalog_db succeeds (requires postgres).

Common errors

Error / symptomWhat to checkFix
password authentication failed for user "bh_dev_user"POSTGRES_PASSWORD ExternalSecret; GSM bh-dev-user-password vs Cloud SQLAlign secret with Cloud SQL user; refresh ExternalSecret; redeploy
password authentication failed for user "bh_app_user"BH_APP_USER_PASSWORD; GSM bh-app-user-passwordAlign secret with Cloud SQL user
permission denied for schema <name> (Alembic / bh_dev_user)Schema owner; POSTGRES_USER in valuesOwner should be bh_dev_user. If bh_app_user owns schemas, see Recovery
permission denied for schema catalog_db (runtime / bh_app_user)has_schema_privilege('bh_app_user', 'catalog_db', 'USAGE')Re-run bh_app_user grants in bootstrap script as bh_dev_user
permission denied for schema celery_db at pod startupGrants on celery_dbRe-run full bootstrap grants for all six schemas
Cross-schema query fails (e.g. service reads catalog_db.*)App user USAGE on every schema the service queriesGrant USAGE on all required schemas, not only the service primary schema
must be able to SET ROLE "bh_dev_user" when changing ownershipSchemas owned by bh_app_userRun Recovery SQL as postgres
GRANT fails when run as postgresCloud SQL postgres is not a full PostgreSQL superuserFix ownership first; run grant statements as bh_dev_user
Bootstrap or REASSIGN OWNED hangsActive pod DB connectionsScale affected deployments to 0; retry
CREATE EXTENSION vector failsPermissions / extension allow-listRun as postgres on application database

Diagnostic queries

Run on the application database.

Session:

SELECT current_user, current_database();

Schema ownership (expect bh_dev_user for all application schemas):

SELECT n.nspname AS schema, r.rolname AS owner
FROM pg_namespace n
JOIN pg_roles r ON r.oid = n.nspowner
WHERE n.nspname IN (
'catalog_db', 'celery_db', 'agent_db', 'audit_db',
'keycloakapi_db', 'llm_observability_db'
)
ORDER BY 1;

App user USAGE (all should be t):

SELECT n.nspname,
has_schema_privilege('bh_app_user', n.nspname, 'USAGE') AS app_has_usage
FROM pg_namespace n
WHERE n.nspname IN (
'catalog_db', 'celery_db', 'agent_db', 'audit_db',
'keycloakapi_db', 'llm_observability_db'
)
ORDER BY 1;

Recovery — wrong schema ownership

Occurs when apps deploy before bootstrap, or when POSTGRES_USER was bh_app_user so pods created schemas owned by the runtime user.

  1. Scale down application deployments that connect to the database.
  2. As postgres on the application database:
GRANT bh_app_user TO postgres;
GRANT bh_dev_user TO postgres;
REASSIGN OWNED BY bh_app_user TO bh_dev_user;
  1. As bh_dev_user, re-run the grants sections of bighammer_db_setup.sql (bh_dev_user block, bh_app_user block, default privileges).
  2. Re-run diagnostic queries.
  3. Scale deployments back up.

Post-fix verification

  • Diagnostic queries: all schemas owned by bh_dev_user; all app_has_usage = true.
  • Pod logs: schema setup and alembic upgrade head complete without permission denied.
  • Restart affected deployments after grant changes.

Platform-managed GSM secrets

Infrastructure provisioning creates prerequisite DB and SSL secrets. Do not recreate them manually — see Platform prerequisites.

Non-platform secrets (integrations, licenses, etc.): see bh_gsm_onetime_setup.sh in the mirrored chart scripts/ folder.

TopicLink
ScriptsScripts Reference
SecretsSecret Manager Secrets
Azure equivalentAzure Database Bootstrap Troubleshooting
General troubleshootingTroubleshooting