Use consul-template for database configuration in PgBouncer instead of custom scripts
Description:
Currently, GitLab Omnibus uses a set of custom shell scripts to dynamically switch database connections in pgbouncer.
While functional, this approach has some drawbacks:
- Non-standard implementation that is harder to maintain and extend.
- No native support for configuration re-rendering on change.
- Limited flexibility for complex failover or multi-environment setups.
Problem:
- The current solution reinvents templating and reconfiguration logic that tools like
consul-templatealready handle very well. - Any changes to connection parameters require manual or custom-script reloads.
- Less predictable for users familiar with
pgbouncer+ service discovery patterns in modern infrastructure.
Proposed solution:
Replace (or at least optionally allow replacing) the custom scripts with consul-template to manage pgbouncer.ini and userlist.txt from values stored in Consul or Vault.
Example flow:
- Store DB connection parameters (host, port, user, password) in Consul or Vault KV.
- Use a
pgbouncer.ini.ctmpltemplate in Omnibus, e.g.:
[databases]
gitlabhq_production = host={{ key "db/primary/host" }} port={{ key "db/primary/port" }} user={{ key "db/user" }} password={{ key "db/password" }}
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
...
- Run
consul-templatealongsidepgbouncerto automatically render and reload configuration when values change:
consul-template \
-template "/etc/gitlab/pgbouncer.ini.ctmpl:/etc/gitlab/pgbouncer.ini:sv restart pgbouncer" \
-template "/etc/gitlab/userlist.txt.ctmpl:/etc/gitlab/userlist.txt:sv restart pgbouncer"
Benefits:
- Declarative, well-known configuration management pattern.
- Automatic reloads on DB failover or credential rotation.
- Reduced amount of GitLab-specific bash logic to maintain.
- Consistent with other service discovery / failover tooling in the ecosystem.
Backward compatibility:
- Default Omnibus behavior can remain unchanged.
- Add a configuration flag (e.g.
pgbouncer['use_consul_template'] = true) to enable the new mechanism.