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:
2026-05-31 17:22:30 +02:00
parent 54b3092305
commit 8330d82225
14 changed files with 1048 additions and 3 deletions

View File

@@ -0,0 +1,104 @@
[Factory](../../../README.md) > [Doc](../../README.md) > [Runbooks](../README.md) > **Nouvelle application web**
# Mettre en service une nouvelle application web
> **Last Updated:** 2026-05-31
> **Status:** ✅ Procédure courante
> **Related:** [Conventions de nommage](conventions.md) · [Checklist](08-checklist.md) · [ADR CI/CD](../../adr/03_cicd_gitea_action_argocd.md) · [ADR Vault](../../adr/04_tool_hashicorp_vault.md)
## C'est quoi ?
Ce runbook décrit, de zéro, comment faire vivre une nouvelle application web sur la plateforme Arcodange. Le pattern est **GitOps** : l'app habite son propre dépôt Gitea, sa base de données et ses accès Vault sont provisionnés par Terraform/OpenTofu, et **ArgoCD** déploie son chart Helm dans un namespace dédié. Les identifiants Postgres ne sont jamais écrits en clair : ils sont générés à la volée par Vault et injectés dans le pod par le **Vault Secrets Operator (VSO)**.
La mécanique est répartie sur **trois dépôts** — le dépôt plateforme [`factory`](https://gitea.arcodange.lab/arcodange-org/factory), le dépôt des services partagés [`tools`](https://gitea.arcodange.lab/arcodange-org/tools), et le **nouveau dépôt de l'app** — avec des **dépendances d'ordre** strictes (voir plus bas). Les exemples de référence sont [`erp`](https://gitea.arcodange.lab/arcodange-org/erp) (image publique + DB) et [`webapp`](https://gitea.arcodange.lab/arcodange-org/webapp) (image maison + DB).
**Sert à :**
1. Créer un dépôt Gitea et son squelette (`chart/`, `iac/`, `.gitea/workflows/`).
2. Provisionner la base de données, son rôle propriétaire, et les accès Vault (statiques + dynamiques).
3. Déployer l'app via ArgoCD et l'exposer derrière Traefik (interne `.lab` ou public `.fr` + CrowdSec).
## Carte de bout en bout
```mermaid
%%{init: {'theme': 'base'}}%%
flowchart TB
classDef step fill:#2563eb,stroke:#1e40af,color:#fff
classDef plat fill:#059669,stroke:#047857,color:#fff
classDef gitops fill:#7c3aed,stroke:#6d28d9,color:#fff
classDef run fill:#b45309,stroke:#92400e,color:#fff
REPO["1 · Dépôt Gitea<br>arcodange-org/app"]:::step
DB["2 · factory/postgres/iac<br>base app + rôle app_role"]:::plat
VAULT["3 · tools/hashicorp-vault/iac<br>gitea_cicd_app + policies app / app-ops"]:::plat
CONTENT["4·5·6 · chart/ + iac/ + .gitea/<br>push → CI build image &amp; tofu apply"]:::step
ARGO["7 · factory/argocd/values.yaml<br>→ Application ArgoCD (ns app)"]:::gitops
POD["Runtime · Pod(SA app) → VSO → Vault<br>creds/app → pgbouncer.tools → base app"]:::run
REPO --> DB
REPO --> VAULT
DB --> CONTENT
VAULT --> CONTENT
CONTENT --> ARGO
ARGO --> POD
```
## Ordre des opérations (le point le plus important)
> [!IMPORTANT]
> Les étapes ne sont pas interchangeables. Le rôle JWT de CI `gitea_cicd_<app>` (étape 3) et le rôle Postgres `<app>_role` (étape 2) doivent **exister avant** que la CI Terraform de l'app (étape 6 appliquant l'étape 5) ne s'exécute — sinon l'authentification Vault de la CI échoue, ou le module `app_roles` n'a pas de `<app>_role` à qui rattacher les credentials dynamiques.
```
[01] Dépôt Gitea sous arcodange-org (hérite les secrets CI d'org)
├──> [02] factory/postgres/iac → base <app> + <app>_role + user_lookup()
└──> [03] tools/hashicorp-vault/iac → gitea_cicd_<app> (JWT CI) + policies <app> / <app>-ops
│ (02 et 03 indépendants entre eux, mais TOUS DEUX avant 05)
[04+05+06] Contenu du dépôt : chart/ + iac/ + .gitea/workflows/ (+ Dockerfile)
│ push → CI « dockerimage » build l'image · CI « vault » applique iac/
│ → creds/<app> (rôle DB dynamique) + rôle K8s <app> + secrets KV
[07] factory/argocd/values.yaml → ArgoCD crée l'Application → déploie le chart dans le namespace <app>
Runtime : Pod(SA <app>) → VSO → VaultAuth(role <app>) → creds/<app>
→ user PG dynamique héritant de <app>_role → pgbouncer.tools → base <app>
```
## Prérequis plateforme (déjà en place)
Ces fondations existent et ne sont **pas** à refaire pour chaque app :
| Brique | Où | Rôle |
|---|---|---|
| Mounts Vault `kvv2`, `postgres`, `transit`, auth `kubernetes` | [`tools/hashicorp-vault/iac/main.tf`](https://gitea.arcodange.lab/arcodange-org/tools/src/branch/main/hashicorp-vault/iac/main.tf) | Moteurs de secrets + auth K8s |
| Connexion Vault→Postgres (via `pgbouncer.tools`, user `credentials_editor`) | idem | Permet à Vault d'émettre des users PG dynamiques |
| Rôle JWT de bootstrap `gitea_cicd` + app OAuth2 Gitea (`gitea_app_id`) | [`gitea_oidc_auth.yml`](https://gitea.arcodange.lab/arcodange-org/factory/src/branch/main/ansible/arcodange/factory/playbooks/tools/roles/hashicorp_vault/tasks/gitea_oidc_auth.yml) | Échange OIDC Gitea → JWT Vault dans la CI |
| Bot `tofu_module_reader` (clé SSH dans `kvv1/gitea/tofu_module_reader`) | [`factory/iac/gitea_tofu_ci_user.tf`](https://gitea.arcodange.lab/arcodange-org/factory/src/branch/main/iac/gitea_tofu_ci_user.tf) | Laisse la CI cloner le module partagé `tools` en SSH |
| Secrets Actions d'organisation (`HOMELAB_CA_CERT`, `vault_oauth__sh_b64`, `PACKAGES_TOKEN`) | org Gitea `arcodange-org` | Hérités par tout dépôt de l'org |
## Index des étapes
| # | Page | Ce qu'on y fait | Statut |
|---|---|---|---|
| — | [Conventions de nommage](conventions.md) | Le nom `<app>` réutilisé à l'identique partout (à lire en premier) | ✅ |
| 01 | [Dépôt Gitea](01-gitea-repo.md) | Créer le dépôt sous `arcodange-org` + squelette | ✅ |
| 02 | [Base de données](02-database.md) | `factory/postgres/iac` → base `<app>` + rôle `<app>_role` | ✅ |
| 03 | [Vault plateforme](03-vault-platform.md) | `tools/hashicorp-vault/iac``gitea_cicd_<app>` + policies | ✅ |
| 04 | [Chart Helm](04-helm-chart.md) | Le chart de l'app (DB via pgbouncer, secrets VSO, ingress) | ✅ |
| 05 | [Terraform de l'app](05-app-terraform.md) | `iac/` → module `app_roles` (creds dynamiques + rôle K8s) | ✅ |
| 06 | [Workflows CI](06-ci-workflows.md) | `.gitea/workflows/` : `tofu apply` + build image | ✅ |
| 07 | [Enregistrement ArgoCD](07-argocd-register.md) | `factory/argocd/values.yaml` → Application + déploiement | ✅ |
| 08 | [Checklist](08-checklist.md) | Récapitulatif ordonné + definition of done | ✅ |
## Légende de statut
✅ actif · 🟡 dégradé/beta · 🔴 critique/EOL · ⚠️ problème connu · ❌ désactivé
## Comment éditer ce runbook
1. **Ajouter une page** → la créer depuis le template tree-docs adéquat **et** ajouter sa ligne dans l'index ci-dessus.
2. **Garder les liens croisés bidirectionnels** → toute dépendance citée dans une page (`Upstream`/`Downstream`) doit avoir sa réciproque sur l'autre page.
3. **Mettre à jour `Last Updated:`** ci-dessus après tout changement de structure.
4. Les exemples cités (`erp`, `webapp`) sont vivants : revérifier les snippets contre le code réel avant de s'y fier aveuglément.