Themelio compatibility reference. This page describes the retained Themelio implementation or its historical design. Check the parallel-operation guide before applying it to the current platform.
DD-0016: Declarative Database List in the Ansible postgres Role — Implementation
Related ADR: ADR-0016: Declarative Database List in the Ansible postgres Role
Status: Draft
Date: 2026-06-04
Authors: Thanasis Katsadas
Overview
This document specifies the refactoring of devops/ansible/roles/postgres/ to replace flat per-database Ansible variables with a postgres_databases list defined in inventory. The role will iterate over that list to validate passwords, create Kubernetes secrets, configure CNPG managed roles, and apply CNPG Database CRDs. Five database/secret-specific Jinja2 templates are replaced by two generic ones. Vault passwords are consolidated into a vault_postgres_passwords dict keyed by PostgreSQL username.
Goals and Non-Goals
Goals
- Replace all flat per-database variables with a single
postgres_databaseslist entry per database. - Consolidate five per-database Jinja2 templates into two generic ones.
- Replace seven per-database task blocks with three loops.
- Derive CNPG cluster managed roles dynamically from the list.
- Migrate vault password variables to a
vault_postgres_passwordsdict in all four environment vault files. - Define
postgres_databasesininventory/common/group_vars/all.ymlso it is shared across all environments.
Non-Goals
- Projecting database credentials into application namespaces — each service role remains responsible for that.
- Changing the CNPG cluster configuration, storage, or image settings.
- Supporting multiple CNPG clusters; the role manages one cluster named
{{ cnpg_cluster_name }}. - Migrating MLflow or Waldur per-tenant databases, which are managed by separate roles.
Design
1. postgres_databases List Schema
Each entry in the list describes one CNPG Database CRD and the Kubernetes Secret used to authenticate its owner. Required fields:
Multiple database entries may share the same user and secret_name (e.g., celery_results shares the waldur user). The role deduplicates by secret_name when creating secrets and by user when configuring CNPG managed roles.
2. Inventory Changes
inventory/common/group_vars/all.yml — add the postgres_databases list:
Each environment's vault.yml (dev, staging, local, production) — replace the two flat password vars with a dict:
The actual password values are unchanged. Only the key structure changes.
3. defaults/main.yml Changes
Remove all flat per-database variables:
Add an empty default so the role fails gracefully if the inventory omits the list:
All cnpg_* vars and databases_namespace remain unchanged.
4. tasks/main.yml Changes
Replace the two separate validation tasks, two secret creation tasks, and three database application tasks with three loops:
The Helm repository setup, CNPG operator install, and namespace creation tasks are unchanged.
5. Template Changes
Remove the five per-database templates:
gitlab-database.yml.j2waldur-database.yml.j2waldur-celery-results-database.yml.j2gitlab-db-secret.yml.j2waldur-db-secret.yml.j2
Add templates/db-secret.yml.j2:
Add templates/database.yml.j2:
Update templates/cnpg-cluster.yml.j2 — replace the hardcoded managed.roles block:
6. Adding a New Database (After Refactor)
To add a new database (e.g., for k8s-root-actor):
- Add one entry to
postgres_databasesininventory/common/group_vars/all.yml. - If it introduces a new PostgreSQL user, add the password to
vault_postgres_passwordsin each environment'svault.yml. - Run
ansible-playbook -i inventory/<env>/hosts.yml playbooks/postgres.yml.
No changes to the role itself are needed.
Testing Strategy
-
Run static checks against the changed role files:
-
Run with
--checkagainst the local inventory to validate template rendering and task structure: -
Apply against the local Minikube cluster:
-
Verify Kubernetes state:
-
Re-run the playbook to confirm idempotency (no changes reported on second run).
Deployment & Rollout
- Re-encrypt each environment's vault file to replace
vault_gitlab_db_passwordandvault_waldur_db_passwordwithvault_postgres_passwords. - Add
postgres_databasestoinventory/common/group_vars/all.yml. - Apply the role changes to
defaults/main.yml,tasks/main.yml, templates. - Run
ansible-playbook --checkagainstlocal, then apply. - Apply to
dev,staging, andproductionin sequence following the normal deployment process.
Rollback: the existing Kubernetes resources (Database CRDs, secrets, CNPG cluster) are not deleted by this change — the role only applies state: present. If rollback is needed, revert the role files and vault structure and re-run the playbook.
References
- ADR-0016: Declarative Database List in the Ansible postgres Role
- CloudNativePG Database CRD
- CloudNativePG Managed Roles
- Ansible
uniquefilter
Page source
Source snapshot · Revision f928834c8.