docs(runbooks): add "new web app" setup runbook under doc/runbooks/
Document, as a tree-docs tree, the end-to-end procedure to stand up a new web application on the Arcodange platform — a mechanic spread across the factory, tools and app repos with non-trivial ordering dependencies. Covers: Gitea repo creation (org-secret inheritance), Postgres DB + owner role (factory/postgres/iac), platform Vault declaration (gitea_cicd_<app> + policies, tools/hashicorp-vault/iac), the app Helm chart (VSO dynamic secrets via pgbouncer), the app Terraform (app_roles module), the CI workflows (tofu apply + image build, incl. the copy-pasted role pitfall), and ArgoCD registration (factory/argocd/values.yaml). Adds a naming- conventions concept page and an ordered checklist. Wires the legacy doc/adr "setup hello world web app" item and the factory README to the runbook. New docs live under doc/ (singular) per the PR #8 convention. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
96
doc/runbooks/new-web-app/05-app-terraform.md
Normal file
96
doc/runbooks/new-web-app/05-app-terraform.md
Normal file
@@ -0,0 +1,96 @@
|
||||
[Factory](../../../README.md) > [Doc](../../README.md) > [Runbooks](../README.md) > [Nouvelle application web](README.md) > **5. Terraform de l'app**
|
||||
|
||||
# 5. Le Terraform de l'application
|
||||
|
||||
> **Status:** ✅ Active
|
||||
> **Upstream:** [2. Base de données](02-database.md), [3. Vault plateforme](03-vault-platform.md)
|
||||
> **Downstream:** [4. Chart Helm](04-helm-chart.md), [6. Workflows CI](06-ci-workflows.md)
|
||||
> **Related:** [Conventions de nommage](conventions.md)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Le `iac/` du dépôt déclare les ressources Vault **propres à l'app** : un rôle Postgres dynamique (`postgres/creds/<app>`), un rôle d'authentification Kubernetes (`<app>`), et les secrets de config KV. Le gros du travail est fait par un **module partagé** (`app_roles`, dans `tools`) ; le dépôt se contente de l'appeler avec son nom et d'ajouter ses secrets spécifiques.
|
||||
|
||||
## Les trois fichiers
|
||||
|
||||
### `providers.tf` — s'authentifier à Vault avec le rôle CI de l'app
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
required_providers {
|
||||
vault = { source = "vault", version = "4.4.0" }
|
||||
}
|
||||
}
|
||||
provider "vault" {
|
||||
address = "https://vault.arcodange.lab"
|
||||
auth_login_jwt { # JWT fourni par la CI via TERRAFORM_VAULT_AUTH_JWT
|
||||
mount = "gitea_jwt"
|
||||
role = "gitea_cicd_<app>" # ← créé à l'étape 3 ; DOIT exister avant le 1er apply
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `backend.tf` — état distant sur GCS, préfixe par app
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
backend "gcs" {
|
||||
bucket = "arcodange-tf"
|
||||
prefix = "<app>/main" # ← un préfixe d'état dédié par app
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `main.tf` — appeler le module partagé + secrets de l'app
|
||||
|
||||
```hcl
|
||||
module "app_roles" {
|
||||
source = "git::ssh://git@192.168.1.202:2222/arcodange-org/tools.git//hashicorp-vault/iac/modules/app_roles?depth=1&ref=main"
|
||||
name = "<app>"
|
||||
# database = "<autre>" # optionnel ; par défaut = name
|
||||
}
|
||||
|
||||
# Exemple : secrets de config statiques de l'app, écrits dans kvv2/<app>/config
|
||||
resource "vault_kv_secret_v2" "config" {
|
||||
mount = module.app_roles.mount_paths.kvv2 # "kvv2"
|
||||
name = format("%sconfig", module.app_roles.kvv2_path_prefix) # "<app>/config"
|
||||
data_json = jsonencode({
|
||||
# … clés propres à l'app (ex. erp : DOLI_ADMIN_LOGIN/PASSWORD, DOLI_INSTANCE_UNIQUE_ID) …
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
## Ce que le module `app_roles` crée
|
||||
|
||||
[`modules/app_roles/main.tf`](https://gitea.arcodange.lab/arcodange-org/tools/src/branch/main/hashicorp-vault/iac/modules/app_roles/main.tf) :
|
||||
|
||||
| Ressource | Effet |
|
||||
|---|---|
|
||||
| `vault_database_secret_backend_role` → `postgres/creds/<app>` | À chaque demande : `CREATE ROLE "…" LOGIN PASSWORD … VALID UNTIL … ; GRANT <app>_role TO "…"`. Le user éphémère **hérite** de `<app>_role` (donc des droits sur la base). À la révocation : `REASSIGN OWNED … TO <app>_role` + `REVOKE`. |
|
||||
| `vault_kubernetes_auth_backend_role` → `<app>` | Lie le SA `<app>` du namespace `<app>` aux policies `default` + `<app>` (TTL 3600 s). C'est ce que `VaultAuth` cible (étape 4). |
|
||||
|
||||
Sorties utiles : `mount_paths` (`{k8s, pg, kvv2}`), `kvv2_path_prefix` (`<app>/`), `name`, `database`.
|
||||
|
||||
## Dépendances (à respecter)
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Ce Terraform **suppose** que deux choses existent déjà :
|
||||
> - le rôle Postgres `<app>_role` (créé à l'[étape 2](02-database.md)) — sinon le `GRANT <app>_role TO …` du rôle dynamique est invalide ;
|
||||
> - le rôle JWT `gitea_cicd_<app>` et la policy `<app>` (créés à l'[étape 3](03-vault-platform.md)) — sinon l'authentification du provider échoue / le rôle K8s ne peut référencer la policy.
|
||||
>
|
||||
> Ce `iac/` est appliqué par la CI de l'app, voir [étape 6](06-ci-workflows.md). Ne pas pousser ce dossier avant d'avoir appliqué les étapes 2 et 3.
|
||||
|
||||
## Notes / contraintes
|
||||
|
||||
- Le module est récupéré **en SSH** via le bot `tofu_module_reader` (cf. [étape 1](01-gitea-repo.md)) ; `?ref=main&depth=1` épingle la branche et limite le clone.
|
||||
- L'état est isolé par `prefix = "<app>/main"` : pas de collision entre apps dans le bucket `arcodange-tf`.
|
||||
- `erp` et `webapp` montrent deux variantes : `erp` passe par `module "app_roles"` ; `webapp` inline encore les ressources (`vault_database_secret_backend_role` + `vault_kubernetes_auth_backend_role`) — préférer le module pour une nouvelle app.
|
||||
|
||||
## Related
|
||||
|
||||
- [2. Base de données](02-database.md) — fournit `<app>_role`.
|
||||
- [3. Vault plateforme](03-vault-platform.md) — fournit `gitea_cicd_<app>` et la policy `<app>`.
|
||||
- [4. Chart Helm](04-helm-chart.md) — consomme `postgres/creds/<app>`, le rôle K8s `<app>` et `kvv2/<app>/config`.
|
||||
- [6. Workflows CI](06-ci-workflows.md) — applique ce `iac/`.
|
||||
Reference in New Issue
Block a user