tracksolid_timescale_grafan.../10_pgbouncer_auth.sql
David Kiania e811dd8f34
Some checks are pending
Static Analysis / static (push) Waiting to run
Tests / test (push) Waiting to run
feat(infra): add pgbouncer sidecar to cap tracksolid_db connections
Phase 1 of the pgbouncer + pgAdmin rollout (runbook:
260507_pgbouncer_deployment.md). pgAdmin4 on the maintainer's laptop has
been exhausting tracksolid_db's max_connections, cascading to pgcli and
operations. Adds an internal-only pgbouncer service in transaction mode
with a small backend pool (default 15) so admin-tool sprawl can no
longer starve the ingest pipeline.

No client cutover this round - ingest, Grafana, webhook, and backup all
keep talking to timescale_db:5432 directly. SCRAM passthrough is wired
via a new pgbouncer role + public.user_lookup() function (migration 10).
The role is created with a placeholder password; sync_role_passwords()
in run_migrations.py replaces it from PGBOUNCER_AUTH_PASSWORD on every
container startup, mirroring the existing grafana_ro convention.

Requires PGBOUNCER_AUTH_PASSWORD to be set in .env before deploy.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 13:21:35 +03:00

32 lines
1 KiB
PL/PgSQL

-- 10_pgbouncer_auth.sql
-- pgbouncer SCRAM passthrough auth: dedicated role + user_lookup() function.
-- Runbook: 260507_pgbouncer_deployment.md
--
-- Idempotent. Re-applying is a no-op:
-- * Role created only when missing (placeholder password, replaced on every
-- container startup by run_migrations.py:sync_role_passwords from
-- PGBOUNCER_AUTH_PASSWORD).
-- * Function uses CREATE OR REPLACE.
-- * GRANT/REVOKE are safe to re-run.
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'pgbouncer') THEN
CREATE ROLE pgbouncer LOGIN PASSWORD 'SET_PASSWORD_IN_ENV';
END IF;
END
$$;
CREATE OR REPLACE FUNCTION public.user_lookup(in_user text,
OUT uname text, OUT phash text) RETURNS record AS $$
BEGIN
SELECT usename, passwd
FROM pg_catalog.pg_shadow
WHERE usename = in_user
INTO uname, phash;
RETURN;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
REVOKE ALL ON FUNCTION public.user_lookup(text) FROM public;
GRANT EXECUTE ON FUNCTION public.user_lookup(text) TO pgbouncer;