[Factory](../../../README.md) > [Doc](../../README.md) > [Runbooks](../README.md) > [Nouvelle application web](README.md) > **2. Base de données** # 2. Provisionner la base de données > **Status:** ✅ Active > **Upstream:** [1. Dépôt Gitea](01-gitea-repo.md) > **Downstream:** [5. Terraform de l'app](05-app-terraform.md) > **Related:** [3. Vault plateforme](03-vault-platform.md) · [4. Chart Helm](04-helm-chart.md) · [Conventions de nommage](conventions.md) --- ## Summary La base de l'app et son **rôle propriétaire** `_role` sont créés par un Terraform **côté plateforme** (`factory/postgres/iac`), pas dans le dépôt de l'app. On ajoute simplement le nom de l'app à une liste, et la CI de `factory` applique. L'app, elle, ne se connectera **jamais** avec un mot de passe statique : elle obtiendra des identifiants éphémères de Vault (cf. [étape 4](04-helm-chart.md)) qui héritent de `_role`. ## Action Ajouter `""` au set `applications` de [`factory/postgres/iac/terraform.tfvars`](https://gitea.arcodange.lab/arcodange-org/factory/src/branch/main/postgres/iac/terraform.tfvars) : ```hcl applications = [ "webapp", "erp", "crowdsec", "plausible", "dance-lessons-coach", "", # ← ajouter ] ``` Puis pousser : la CI applique automatiquement (voir plus bas). ## Ce que ça crée [`postgres/iac/main.tf`](https://gitea.arcodange.lab/arcodange-org/factory/src/branch/main/postgres/iac/main.tf) itère `for_each` sur le set et crée, **par app** : | Ressource | Nom | Rôle | |---|---|---| | `postgresql_role` | `_role` | Rôle **non-login**, propriétaire de la base | | `postgresql_grant_role` | `_role` → `credentials_editor` (WITH ADMIN OPTION) | Laisse Vault rattacher les users dynamiques à ce rôle | | `postgresql_database` | `` | La base (owner `_role`, `template0`, `alter_object_ownership`) | | `postgresql_function` | `user_lookup()` (dans la base ``) | Authentification pgbouncer (lit `pg_shadow`) | | `postgresql_grant` | EXECUTE sur `user_lookup` → `pgbouncer_auth` | Autorise pgbouncer à résoudre les users | Extrait clé : ```hcl resource "postgresql_role" "app_role" { for_each = var.applications name = "${each.value}_role" login = false # non-login : ne sert que de "porteur de droits" } resource "postgresql_database" "app_db" { for_each = var.applications name = each.value owner = postgresql_role.app_role[each.value].name template = "template0" alter_object_ownership = true } ``` ## Comment c'est appliqué Le workflow [`factory/.gitea/workflows/postgres.yaml`](https://gitea.arcodange.lab/arcodange-org/factory/src/branch/main/.gitea/workflows/postgres.yaml) se déclenche sur tout changement de `postgres/**/*.tf` ou `*.tfvars` : ```mermaid %%{init: {'theme': 'base'}}%% flowchart LR classDef ci fill:#059669,stroke:#047857,color:#fff classDef db fill:#2563eb,stroke:#1e40af,color:#fff PUSH["push tfvars"]:::ci --> JWT["OIDC Gitea → JWT Vault
(role gitea_cicd)"]:::ci JWT --> READ["lit kvv1/postgres/credentials
→ TF_VAR_postgres_*"]:::ci READ --> APPLY["tofu apply postgres/iac"]:::ci APPLY --> DB["base ‹app› + ‹app›_role"]:::db ``` Le provider PostgreSQL pointe l'hôte `192.168.1.202` (`sslmode=disable`, `superuser=true`) et s'authentifie avec le compte `credentials_editor`, dont les identifiants sont dans Vault à `kvv1/postgres/credentials_editor/credentials`. ## Le modèle de connexion (à retenir) > [!IMPORTANT] > L'application **ne se connecte pas** directement à Postgres avec un user fixe. Elle vise **`pgbouncer.tools:5432`** et utilise des **users dynamiques courts** émis par Vault, qui héritent de `_role` (donc des droits sur la base ``). C'est l'étape 4 (chart + VSO) et l'étape 5 (rôle Vault `creds/`) qui câblent ça. Ici, on ne fait qu'établir *la base et le rôle propriétaire*. ## Notes / contraintes - `credentials_editor` est un compte unique partagé par toutes les apps, à fort privilège (il peut créer des rôles). Il sert aussi de compte de connexion au moteur Postgres de Vault (cf. [étape 3](03-vault-platform.md)). - La fonction `user_lookup()` est indispensable au mode `auth_query` de pgbouncer ; elle est `security_definer` et n'est exécutable que par `pgbouncer_auth`. ## Related - [3. Vault plateforme](03-vault-platform.md) — la connexion Vault→Postgres réutilise `credentials_editor` ; à faire en parallèle. - [5. Terraform de l'app](05-app-terraform.md) — le module `app_roles` fait `GRANT _role TO …` : il **exige** que `_role` existe déjà (créé ici). - [4. Chart Helm](04-helm-chart.md) — où la connexion `pgbouncer.tools` + creds dynamiques est configurée.