Files
factory/doc/runbooks/new-web-app
Gabriel Radureau 8330d82225 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>
2026-05-31 17:22:30 +02:00
..

Factory > Doc > Runbooks > Nouvelle application web

Mettre en service une nouvelle application web

Last Updated: 2026-05-31 Status: Procédure courante Related: Conventions de nommage · Checklist · ADR CI/CD · ADR Vault

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, le dépôt des services partagés 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 (image publique + DB) et 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

%%{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 Rôle
Mounts Vault kvv2, postgres, transit, auth kubernetes tools/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 É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 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 Le nom <app> réutilisé à l'identique partout (à lire en premier)
01 Dépôt Gitea Créer le dépôt sous arcodange-org + squelette
02 Base de données factory/postgres/iac → base <app> + rôle <app>_role
03 Vault plateforme tools/hashicorp-vault/iacgitea_cicd_<app> + policies
04 Chart Helm Le chart de l'app (DB via pgbouncer, secrets VSO, ingress)
05 Terraform de l'app iac/ → module app_roles (creds dynamiques + rôle K8s)
06 Workflows CI .gitea/workflows/ : tofu apply + build image
07 Enregistrement ArgoCD factory/argocd/values.yaml → Application + déploiement
08 Checklist 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.