Un ecosysteme pouvait DETENIR son genome sans savoir l'executer. Le poste d'exploitation porte Ansible epingle, le genome clone depuis SA PROPRE forge, et une cle SSH qui n'appartient qu'a lui. Il n'emporte ni la voute ni son mot de passe : la structure se reconstruit depuis la forge, les secrets depuis la sauvegarde. Deux sources qu'un meme incident n'atteint pas ensemble. Une machine neuve traverse tout le moteur sans rien heriter, et revele ce qu'un etat anterieur masquait. Deux defauts silencieux en sont sortis. setops_plan_dir pointait le lien `instance` en dur : neuf roles lisaient donc le plan d'une AUTRE instance. Le plancher de patient 0 portait les FQDN de Chezlepro, et son edge publiait server_name forge.chezlepro.internal. La variable suit desormais l'inventaire reellement charge. Trois instances sur quatre declaraient les SAN d'exposition de leur edge ; la quatrieme et le modele public ne les avaient pas. La forge de patient 0 etait donc publiee derriere le certificat auto-signe de Debian, sans que rien ne le signale -- `git clone` fut le premier a refuser, a juste titre. P42 le reclame maintenant pour tout ecosysteme qui declare un edge. Le harnais a ecrit la moitie de ce role : 5 echecs sur la piece neuve, aucun n'empechait le code de tourner, tous la rendaient invisible a la carte, au graphe et au lecteur. 42 preuves, 0 echec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 KiB
Catalogue des services
Pour qui : le mainteneur — ce que le moteur sait déployer, sous quel nom de groupe, et jusqu'où c'est éprouvé.
Ce document nomme les services que le moteur sait déployer, et la règle qui lie un groupe à son playbook :
groupe opérationnel -> playbooks/groupes/<groupe>.yml (P04 le prouve)
Le rôle porte le nom du groupe : serveur_keycloak, client_pki. Il n'y a pas de nom
court séparé. Seule exception, serveur_durci : un groupe dont le playbook compose
onze rôles de durcissement (hardening_packages, sysctl_hardening, apparmor,
auditd, fail2ban_ssh, ssh_hardening, nftables_baseline…) plutôt qu'un rôle
homonyme.
La nomenclature des VM et des VMID est documentée dans docs/nomenclature-vm.md.
Un service central peut partager un hôte avec d'autres services de la même fonction opérationnelle (plusieurs applications par VM). La relation stricte est entre groupe et playbook, pas entre groupe et VM.
Modèle à jour : chaque service est une application (
instance/plan/applications.yml). Voirdocs/plan-et-generation.md.
État d'implémentation des rôles
Mise à jour (2026-08-18), vérifiée rôle par rôle contre
roles/. Les 29 groupesserveur_*/client_*de ce catalogue ont tous leur rôle et leur playbook. Aucune capacité annoncée ici n'est un point d'ancrage vide.
Éprouvés sur VM réelles. Le 2026-08-13, la flotte a été reconstruite depuis zéro — 43 groupes, 0 échec, 37 minutes — puis remontée d'un seul trait. Ce n'est donc plus « du code validé » : chaque rôle a repris une machine nue et l'a menée à l'état voulu.
Ce que la reconstruction couvre, par capacité :
| Capacité | Rôles | Ce qui est éprouvé |
|---|---|---|
| Socle et durcissement | serveur_debian, serveur_durci |
clone du gabarit doré → machine conforme |
| Confiance | serveur_step_ca, client_pki |
mTLS avec SAN dérivés du plan, renouvellement |
| Noms | serveur_powerdns, client_unbound |
autoritaire interne + résolveur local |
| Identité | serveur_openldap, serveur_keycloak |
LDAPS, SSO OIDC, fédération LDAP automatisée (tasks/federation-ldap.yml), exposé par le plan (auth.<domaine>) |
| Passerelle SSO | serveur_oauth2_proxy |
SSO devant une app sans OIDC natif (éprouvé sur Icinga Web 2) |
| Données | serveur_postgresql, serveur_redis |
bases et comptes dérivés du registre, TLS verify-full |
| Courriel | serveur_postfix, serveur_dovecot, serveur_rspamd |
SMTP→LDAP→LMTP→IMAP, antispam, DKIM |
| Edge | serveur_nginx |
terminaison TLS, publication des expose: du plan |
| Observabilité | serveur_prometheus, serveur_loki, serveur_grafana |
métriques, journaux, tableaux sous SSO |
| Supervision | serveur_icinga, serveur_icingaweb2 |
Icinga 2 + IcingaDB + Web 2 + BPM, au SSO |
| Forge | serveur_forgejo |
Git + PostgreSQL + SSO OIDC |
| Collaboration | serveur_nextcloud, serveur_collabora |
déployés par la reconstruction, base et client OIDC dérivés du plan — usage (dépôt de fichier, édition partagée) non consigné comme preuve |
| Plateforme webapp | serveur_web_frontal, serveur_web_dorsal |
sites statiques et webapps natives (venv + systemd + nginx), zéro conteneur |
| Sauvegardes | serveur_backup, client_backup |
restic hors-nœud, restauration éprouvée (2026-08-12 : la donnée revient) |
| Exploitation | serveur_ops |
le poste depuis lequel l'ecosysteme se reconstruit : Ansible epingle, genome clone depuis sa propre forge, cle SSH propre — sans la voute ni son mot de passe |
| Agents de flotte | client_metrique, client_journal, client_smtp |
collecte et relais sur toute la flotte |
Rôles retirés (2026-07-04, supersédés ou hors conception) : serveur_sendmail
(→ Postfix), client_dns (→ plancher /etc/hosts + client_unbound), client_ldap
(login LDAP au niveau OS, hors design).
Ce que « éprouvé » ne dit pas. La reconstruction prouve que le moteur mène une machine nue à l'état voulu. Elle ne dit rien de la tenue d'un service sous charge, ni de sa mise à jour dans le temps — deux questions distinctes, et non traitées ici.
Services centraux
Le playbook est toujours playbooks/groupes/<groupe>.yml, et le rôle porte le nom du
groupe : la table ne répète donc ni l'un ni l'autre.
| Service | Groupe |
|---|---|
| Socle Debian | serveur_debian |
| Durcissement (compose onze rôles) | serveur_durci |
| step-ca (AC interne + ACME) | serveur_step_ca |
| PowerDNS (autoritaire interne) | serveur_powerdns |
| OpenLDAP (source de vérité des identités) | serveur_openldap |
| Keycloak (SSO OIDC, fédéré à l'annuaire) | serveur_keycloak |
| oauth2-proxy (SSO devant une app sans OIDC natif) | serveur_oauth2_proxy |
| PostgreSQL | serveur_postgresql |
| Redis | serveur_redis |
| NGINX — edge : TLS, mandataire inverse, WAF | serveur_nginx |
| Postfix (MTA) | serveur_postfix |
| Dovecot (mailstore IMAP/LMTP) | serveur_dovecot |
| rspamd (antispam, DKIM) | serveur_rspamd |
| Prometheus | serveur_prometheus |
| Loki | serveur_loki |
| Grafana | serveur_grafana |
| Icinga 2 + IcingaDB | serveur_icinga |
| Icinga Web 2 (+ module BPM) | serveur_icingaweb2 |
| Forgejo | serveur_forgejo |
| Nextcloud | serveur_nextcloud |
| Collabora | serveur_collabora |
| Dépôt de sauvegarde restic | serveur_backup |
Couche applicative web
La couche applicative web est distincte de l'edge serveur_nginx :
serveur_nginxest l'edge : mandataire inverse, terminaison TLS, WAF ; il reçoit le trafic externe et le route.serveur_web_frontalest la couche présentation web (UI, rendu, assets), servie derrière l'edge.serveur_web_dorsalest la couche application web (API, traitement), consommée par les frontaux.
Le « web » de ces deux groupes est implicite par leur position derrière serveur_nginx. Le jour où un service dorsal n'est pas web (worker batch, file, démon), créer un groupe dédié plutôt que d'élargir serveur_web_dorsal.
| Couche | Groupe | Ce que le rôle pose |
|---|---|---|
| Présentation web (sites statiques) | serveur_web_frontal |
nginx + contenu tiré d'un dépôt git souverain (Forgejo), en-têtes de sécurité |
| Application web (webapps dynamiques) | serveur_web_dorsal |
runtime + service systemd + nginx local — venv/paquets, zéro conteneur |
Les deux rôles sont codifiés depuis les spikes du 2026-07-05 (site Alliance Boréale
pour le frontal ; monregistraire — FastAPI + uvicorn + SQLite — pour le dorsal), et
web-frontal-01 / web-dorsal-01 sont actifs dans le plan de référence.
L'exposition ne passe pas par une dépendance de groupe mais par le plan : le champ
expose: d'une application fait dériver le vhost de l'edge, les SAN de son certificat et
le plancher /etc/hosts. Une seule ligne au plan, aucune recopie.
Lacune nommée : la dépendance causale
serveur_web_frontal→serveur_nginxn'est toujours pas déclarée dansdocs/dependances-groupes.yml. Le déploiement d'un frontal n'est donc pas refusé quand l'edge est absent — il aboutit à un site que rien ne publie. À déclarer.
Hôtes du plan de référence
Les quatorze hôtes de l'écosystème de référence, tous à l'état actif, tels que les
déclare instance/plan/applications.yml. Un modèle plus petit en porte moins : cette
table décrit une répartition éprouvée, pas un minimum requis.
| Hôte | Applications |
|---|---|
infra-pki-01 |
step-ca |
infra-dns-01 |
PowerDNS |
infra-edge-01 |
NGINX (edge) |
edge-mta-01 |
Postfix, rspamd |
infra-mail-01 |
Dovecot |
idm-01 |
OpenLDAP, Keycloak |
data-sql-01 |
PostgreSQL, Redis |
obs-01 |
Prometheus, Loki, Grafana |
mon-01 |
Icinga 2, Icinga Web 2, oauth2-proxy |
forge-01 |
Forgejo |
collab-01 |
Nextcloud, Collabora |
backup-01 |
dépôt restic |
web-frontal-01 |
site statique |
web-dorsal-01 |
webapp native |
Le courriel occupe deux hôtes, et ce n'est pas un détail de taille : edge-mta-01
porte ce qui parle à l'extérieur (Postfix, rspamd), infra-mail-01 ce qui détient les
boîtes (Dovecot). La coupure suit l'exposition, pas le logiciel.
Intégrations clientes
| Intégration | Groupe | Posée sur |
|---|---|---|
| Confiance PKI / ACME | client_pki |
tout hôte (universelle) |
| Métriques Prometheus | client_metrique |
tout hôte (universelle) |
| Journaux vers Loki | client_journal |
tout hôte (universelle) |
| Résolution locale (Unbound) | client_unbound |
tout hôte (universelle) |
| Relais SMTP | client_smtp |
déclaré par hôte, dans le plan |
| Sauvegarde restic | client_backup |
déclaré par hôte — obligatoire pour tout détenteur d'état (P36) |
Universelle ne veut pas dire recopiée : une intégration marquée universelle: true
dans son meta/ est posée sur chaque hôte par dérivation, avec l'exemption dérivée du
service rendu (P26 : un hôte n'est pas client de ce qu'il sert). Aucune ligne à écrire
dans le plan.
client_supervisionn'existe pas. Ce catalogue l'a longtemps annoncé ; il n'a jamais eu ni rôle ni playbook, et rien ne l'attend. La supervision s'exerce sans agent sur les hôtes : contrôles actifs depuis le cœur (hostalive) et résultats passifs poussés par l'API par celui qui détient la vérité de terrain — ainsi l'état des sauvegardes est-il rapporté parbackup-01, seul à pouvoir lire ses dépôts. Le nom est retiré plutôt que réservé : une case vide dans un catalogue se lit comme une promesse.
Ordre de déploiement — le raisonnement
L'ordre exécutable n'est pas ici. Il vit dans
docs/couches-deploiement.ymletdocs/dependances-groupes.yml, que P08 prouve cohérents (30 groupes classés, aucun cycle, aucune arête en arrière) et quemake reconstruiresuit. Ce qui suit en est le raisonnement, utile pour comprendre pourquoi cet ordre-là — et pour placer un service nouveau. Les phases sont franchies : les « intégrations à prévoir » ci-dessous sont posées.
L'ordre ci-dessous privilégie les dépendances structurantes avant les applications.
Phase 1 - Fondations transversales
-
serveur_powerdns- Service central : DNS interne autoritaire et/ou résolution interne selon le design retenu.
- Raison : les autres intégrations auront besoin de noms stables plutôt que d'adresses IP.
-
serveur_step_ca- Service central : autorité de certification interne et ACME.
- Intégration à prévoir :
client_pki. - Raison : les autres services auront besoin de certificats fiables avant d'être exposés proprement.
-
serveur_nginx- Service central : reverse proxy, terminaison TLS, publication HTTP(S), WAF.
- Intégration à prévoir : publication des services HTTP derrière le proxy.
- Raison : plusieurs services seront consommés par navigateur ou API et doivent passer par un point d'entrée cohérent.
-
serveur_postfix- Service central : MTA (courriel entrant + sortant interne) + relais SMTP.
- Intégration à prévoir :
client_smtp. - Raison : les notifications, réinitialisations de mot de passe et alertes doivent fonctionner tôt.
Phase 2 - Données et identité
-
serveur_postgresql- Service central : base de données relationnelle partagée.
- Intégration à prévoir : bases dédiées par application, comptes applicatifs et sauvegardes.
- Raison : Keycloak, Grafana, Icinga Web 2, Forgejo et Nextcloud peuvent dépendre de PostgreSQL.
-
serveur_openldap- Service central : annuaire interne (source de vérité des identités).
- Consommateurs : Keycloak (fédération/SSO), courriel (Postfix/Dovecot), apps.
- Raison : l'annuaire doit exister avant l'identité fédérée et le courriel.
-
serveur_keycloak- Service central : SSO/OIDC/SAML.
- Intégration à prévoir : applications web derrière
serveur_nginx. - Raison : les applications devraient être branchées au SSO dès leur arrivée plutôt qu'après coup.
Phase 3 - Observabilité minimale
-
serveur_prometheus- Service central : métriques.
- Intégration à prévoir :
client_metrique. - Raison : les prochains services doivent être mesurables dès leur déploiement.
-
serveur_loki- Service central : journaux centralisés.
- Intégration à prévoir :
client_journal. - Raison : les journaux centralisés accélèrent le diagnostic des services suivants.
-
serveur_grafana
- Service central : tableaux de bord.
- Intégration à prévoir : datasources Prometheus et Loki, authentification Keycloak.
- Raison : Grafana consolide les métriques et journaux après leur mise en place.
Phase 4 - Supervision active
serveur_icinga, puisserveur_icingaweb2- Service central : supervision active, interface web et vues métiers (BPM).
- Intégrations : PostgreSQL, NGINX, et le SSO via
serveur_oauth2_proxy— Icinga Web 2 n'a pas d'OIDC natif. - Rien à poser sur les hôtes supervisés : contrôles actifs depuis le cœur, résultats passifs poussés par l'API.
- Raison : ces composants forment une même capacité de supervision et cohabitent sur
mon-01.
Phase 5 - Services applicatifs internes
-
serveur_redis- Service central : cache et files internes.
- Intégration à prévoir : Nextcloud et autres applications qui en ont besoin.
- Raison : Redis est une dépendance applicative, pas une fondation globale.
-
serveur_forgejo- Service central : forge Git.
- Intégration à prévoir : PostgreSQL, NGINX, Keycloak, SMTP, sauvegardes.
- Raison : la forge devient plus utile après SSO, TLS, SMTP et observabilité.
-
serveur_nextcloud- Service central : collaboration fichiers.
- Intégration à prévoir : PostgreSQL, Redis, NGINX, Keycloak, SMTP, sauvegardes.
- Raison : Nextcloud dépend de plusieurs fondations et doit arriver après elles.
-
serveur_collabora- Service central : édition documentaire en ligne.
- Intégration à prévoir : Nextcloud, NGINX, certificats.
- Raison : Collabora est une extension de Nextcloud et doit venir après lui.
Règles d'intégration
- Tout service exposé en HTTP(S) doit prévoir son intégration avec
serveur_nginx. - Tout service avec authentification humaine doit prévoir son intégration avec
serveur_keycloak, sauf justification contraire. - Tout service générant des alertes ou notifications doit prévoir
client_smtp. - Toute VM de service rejoint
client_pki,client_metrique,client_journaletclient_unbound— par dérivation, sans rien écrire (intégrations universelles, P26). La supervision, elle, ne pose rien sur l'hôte. - Tout hôte qui détient de l'état doit porter
client_backup(P36 le refuse sinon). - Tout service utilisant un certificat interne doit dépendre de
client_pki. - Tout rôle serveur doit documenter ses ports, secrets, sauvegardes, dépendances et groupes clients associés.
Les groupes clients peuvent être ajoutés aux VM existantes quand le service central correspondant est réellement disponible.
Dépendances causales
Les dépendances exécutables sont déclarées dans docs/dependances-groupes.yml.
Le runbook DNS initial est dans docs/dns-interne.md.
Ce fichier sert à deux usages :
- bloquer le déploiement d'un groupe tant que ses prérequis actifs ne sont pas présents ;
- fournir une source exploitable pour les futurs modèles de supervision.
Un hôte peut porter un groupe client à l'état planifié. Le déploiement est refusé tant que le groupe serveur requis n'a pas au moins un hôte actif.