Database Cluster
This example sets up PostgreSQL with managed credentials using secret: references and vars_from for shared configuration.
PostgreSQL Module
stockpile/modules/postgresql.vgo:
name: postgresql
vars:
pg_version: "16"
pg_port: "5432"
pg_max_connections: "100"
pg_shared_buffers: 256MB
pg_effective_cache_size: 768MB
pg_work_mem: 4MB
pg_listen_addresses: localhost
resources:
- name: pg-package
type: package
package: "postgresql-{{ .Vars.pg_version }}"
state: present
when: "os_family('debian')"
- name: pg-package-rhel
type: package
package: "postgresql{{ .Vars.pg_version }}-server"
state: present
when: "!os_family('debian')"
- name: pg-config
type: file
target_path: "/etc/postgresql/{{ .Vars.pg_version }}/main/postgresql.conf"
owner: postgres
group: postgres
mode: "0644"
content: |
port = {{ .Vars.pg_port }}
max_connections = {{ .Vars.pg_max_connections }}
shared_buffers = {{ .Vars.pg_shared_buffers }}
effective_cache_size = {{ .Vars.pg_effective_cache_size }}
work_mem = {{ .Vars.pg_work_mem }}
listen_addresses = '{{ .Vars.pg_listen_addresses }}'
ssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
log_destination = 'syslog'
logging_collector = off
notify:
- pg-service
- name: pg-hba
type: file
target_path: "/etc/postgresql/{{ .Vars.pg_version }}/main/pg_hba.conf"
owner: postgres
group: postgres
mode: "0640"
content: |
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
local all all peer
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
host all all {{ .Vars.pg_allowed_cidr }} scram-sha-256
notify:
- pg-service
- name: pg-service
type: service
service: postgresql
state: running
enabled: true
Application Database Setup
stockpile/modules/app-database.vgo:
name: app-database
depends_on:
- postgresql
resources:
- name: create-app-db
type: exec
command: "psql -c \"SELECT 1 FROM pg_database WHERE datname='{{ .Vars.app_db_name }}'\" | grep -q 1 || createdb {{ .Vars.app_db_name }}"
user: postgres
unless: "psql -lqt | cut -d \\| -f 1 | grep -qw {{ .Vars.app_db_name }}"
- name: create-app-user
type: exec
command: "psql -c \"DO \\$\\$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname='{{ .Vars.app_db_user }}') THEN CREATE ROLE {{ .Vars.app_db_user }} LOGIN; END IF; END \\$\\$;\""
user: postgres
unless: "psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='{{ .Vars.app_db_user }}'\" | grep -q 1"
- name: set-app-user-password
type: exec
stdin: "secret:vigo/app/db_password"
command: "psql -c \"ALTER ROLE {{ .Vars.app_db_user }} PASSWORD '$(cat -)';\""
user: postgres
watch_secret: ["vigo/app/db_password"]
when: "changed"
- name: grant-app-privileges
type: exec
command: "psql -c \"GRANT ALL PRIVILEGES ON DATABASE {{ .Vars.app_db_name }} TO {{ .Vars.app_db_user }};\""
user: postgres
Shared Variables with vars_from
Create a shared variable file for database credentials used across multiple node entries.
stockpile/vars/db-vars.vgo:
app_db_name: myapp
app_db_user: myapp
pg_allowed_cidr: "10.0.0.0/8"
Role Definition
stockpile/roles/database-server.vgo:
name: database-server
modules:
- postgresql
- app-database
Node Assignment
stockpile/envoys/nodes.vgo:
envoys:
- match: "db-*.example.com"
environment: production
roles: [database-server]
vars_from: db-vars.vgo
vars:
pg_max_connections: "200"
pg_shared_buffers: 2GB
pg_effective_cache_size: 6GB
pg_work_mem: 16MB
pg_listen_addresses: "*"
environment_overrides:
production:
pg_max_connections: "200"
pg_shared_buffers: 4GB
pg_effective_cache_size: 12GB
staging:
pg_max_connections: "50"
pg_shared_buffers: 512MB
pg_effective_cache_size: 1536MB
Secret References
The secret: prefix in the stdin parameter of the set-app-user-password resource means:
- The server resolves
secret:vigo/app/db_passwordthrough the secrets provider at check-in time - The resolved value is passed to the agent in the policy bundle
- The agent pipes the value to the command's stdin
- The password never appears in command strings, logs, or config files
For the local secrets backend, create the secret file:
mkdir -p /srv/vigo/secrets/vigo/app
echo -n 'my-secure-password' > /srv/vigo/secrets/vigo/app/db_password
chmod 600 /srv/vigo/secrets/vigo/app/db_password