Files
factory/doc/runbooks/new-web-app/conventions.md
Gabriel Radureau c00c4cdd5c feat(multi-env): Phase B — make factory machinery env-capable (no activation)
ADR-0002 Phase B. Makes postgres/iac, argocd, and the conventions docs
multi-environment-capable WITHOUT activating any sandbox yet — every app
stays prod-only, so this change is behaviour-neutral:
  - postgres/iac `tofu plan` is a no-op (proven: the elision flatten keys
    are bare app names, db=<app>, role=<app>_role — identical addresses)
  - the argocd apps.yaml render is byte-identical (181→181 lines, diff
    empty) since no app declares `envs`

postgres/iac:
- variables.tf: `applications` becomes set(object({name, envs=optional(["prod"])}))
- main.tf: a `local.app_instances` flatten of applications × envs keyed by the
  elided instance id (env=prod → "<app>"); per-app resources iterate it and
  reference each.key / each.value.{database,role}. For prod-only apps every
  resource address + attribute is unchanged. (main.tf also got a full
  `tofu fmt` pass — the pgbouncer function block reindents 4→2 spaces, which
  is cosmetic; the correctness gate is the CI tofu plan, not the text diff.)
- terraform.tfvars: string entries → { name = "..." } objects.

argocd/templates/apps.yaml:
- after the prod Application, a `range $app_attr.envs` loop renders one extra
  Application per non-prod env: name/namespace `<app>-<env>`, shared repoURL,
  helm.valueFiles [values.yaml, values-<env>.yaml], per-env syncPolicy override.
  Renders nothing while no app sets `envs` → prod render unchanged.

docs:
- doc/runbooks/new-web-app/conventions.md (FR, authoritative): new section
  "Plusieurs environnements pour une même app" — elision rule, suffix rule,
  snake-case owner-role exception, erp/erp-sandbox table, ADR-0002 link.
- vibe/guidebooks/lab-ecosystem/naming-conventions.md (EN mirror): the env
  coordinate section + a "Two sandbox models" section reconciling the
  separate-cluster (ADR-0001, names repeat) vs in-cluster sibling (ADR-0002,
  <env> suffix) strategies; Last Updated bumped; ADR-0002 cross-links.

Activation (erp gets envs=["prod","sandbox"] in postgres tfvars + argocd
values + erp/iac) is Phase D, gated by its own plan review.

Refs ADR-0002 (factory#15). Phase A = tools#2 (merged). Phase C = erp#11 (merged).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-28 16:28:28 +02:00

6.7 KiB

Factory > Doc > Runbooks > Nouvelle application web > Conventions de nommage

Conventions de nommage

Pourquoi cette page. Un seul nom — <app> — est réutilisé à l'identique dans une dizaine de systèmes (Gitea, Postgres, Vault, Kubernetes, ArgoCD, GCS, DNS). Toutes les étapes du runbook en dépendent ; on le centralise ici pour ne pas le ré-expliquer partout. Audience. Quiconque crée ou audite une app sur la plateforme. Status. Actif · revu le 2026-05-31.


TL;DR

Choisis un identifiant <app> en kebab-case minuscule (webapp, erp, dance-lessons-coach, url-shortener). Ce nom devient, sans variation, la clé de toutes les ressources. Une seule faute de frappe quelque part casse la chaîne (auth Vault, rattachement DB, sync ArgoCD).

Le nom <app> dans chaque système

Système Identifiant dérivé de <app> Exemple (erp) Source de vérité
Dépôt Gitea arcodange-org/<app> (ou arcodange/<app> si org surchargé) arcodange-org/erp argocd/templates/apps.yaml
Base PostgreSQL <app> erp postgres/iac/main.tf
Rôle propriétaire PG (non-login) <app>_role erp_role postgres/iac/main.tf
Rôle DB dynamique Vault postgres/creds/<app> postgres/creds/erp modules/app_roles/main.tf
Rôle d'auth Kubernetes (Vault) <app> erp modules/app_roles/main.tf
Policy Vault runtime (pod) <app> erp modules/app_policy/main.tf
Policy Vault CI (ops) <app>-ops erp-ops modules/app_policy/main.tf
Rôle JWT de CI (Vault) gitea_cicd_<app> gitea_cicd_erp modules/app_policy/main.tf
Groupe d'identité Vault <app>-ops erp-ops modules/app_policy/main.tf
Secret KV de config kvv2/<app>/config kvv2/erp/config modules/app_roles (sortie kvv2_path_prefix)
Namespace Kubernetes <app> erp apps.yaml (CreateNamespace=true)
ServiceAccount Kubernetes <app> erp chart/templates/serviceaccount.yaml
Application ArgoCD <app> erp apps.yaml
Préfixe d'état OpenTofu (GCS) <app>/main erp/main iac/backend.tf
Domaine interne <app>.arcodange.lab erp.arcodange.lab chart/values.yaml (ingress)
Domaine public <app>.arcodange.fr webapp.arcodange.fr chart/values.yaml (ingress)

Pourquoi cette uniformité est structurante

Les briques se « branchent » entre elles par convention de nom, pas par configuration explicite :

  • Le module app_roles génère un user PG dynamique avec GRANT <app>_role TO … → il suppose que <app>_role (créé à l'étape 2) porte exactement ce nom.
  • Le VaultDynamicSecret du chart lit postgres/creds/<app> → il suppose que le rôle Vault (créé à l'étape 5) porte exactement <app>.
  • L'Application ArgoCD déduit repoURL=.../<app>, path=chart, namespace=<app> du seul nom → le dépôt (étape 1) et le namespace doivent matcher.

Utilise un nom court, stable, kebab-case dès le départ. N'introduis pas de variantes (my_app vs my-app, MyApp, pluriels) : rien ne te préviendra, l'app échouera silencieusement à se connecter ou à se déployer.

Plusieurs environnements pour une même app

Une application peut être déployée plusieurs fois (prod, sandbox, …) sans devenir une app distincte : même dépôt, même chart, même version. On ajoute une seconde coordonnée <env> au nom, régie par une règle d'élision (ADR-0002) :

  • env vaut prod par défaut, et prod s'élide. Quand env == prod, aucun suffixe n'est ajouté : tous les noms dérivés sont identiques au cas mono-environnement décrit plus haut. Une app existante ne change donc pas (plan à vide).
  • Les environnements non-prod prennent le suffixe <app>-<env> en kebab-case partout — base, namespace, chemins/rôles/policies Vault, Application ArgoCD, hôte DNS, sous-préfixe d'état GCS — à une exception : le rôle propriétaire PostgreSQL reste en snake-case <app>_<env>_role, pour rester cohérent avec le suffixe _role.
  • Un seul dépôt et un seul chart servent tous les environnements ; les différences sont superposées via values-<env>.yaml. Un seul rôle JWT de CI (gitea_cicd_<app>) par dépôt couvre tous ses environnements.

Exemple — erp (prod, élidé) vs erp-sandbox :

Système erp (env = prod) erp-sandbox (env = sandbox)
Base PostgreSQL erp erp-sandbox
Rôle propriétaire PG erp_role erp_sandbox_role
Namespace + ServiceAccount erp erp-sandbox
Creds DB dynamiques Vault postgres/creds/erp postgres/creds/erp-sandbox
Secret KV de config kvv2/erp/config kvv2/erp-sandbox/config
Application ArgoCD erp erp-sandbox
Domaine interne erp.arcodange.lab erp-sandbox.arcodange.lab
Dépôt Gitea / chart / JWT CI arcodange-org/erp · chart · gitea_cicd_erp partagés (mêmes valeurs)

Déclaration : postgres/iac/terraform.tfvars et la liste applications côté tools acceptent envs = ["prod", "sandbox"] ; l'omettre revient à ["prod"]. L'Application ArgoCD non-prod se déclare via une clé envs sous l'app dans argocd/values.yaml.

Références croisées