2026-06-24 20:17:46 -04:00
|
|
|
---
|
|
|
|
|
groupes:
|
|
|
|
|
client_pki:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_step_ca
|
|
|
|
|
raison: "La confiance CA et ACME client dependent de l'autorite interne."
|
|
|
|
|
surveillance: "Verifier validite CA, emission ACME et expiration des certificats."
|
|
|
|
|
|
|
|
|
|
client_metrique:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_prometheus
|
|
|
|
|
raison: "Les exporters clients doivent etre collectes par Prometheus."
|
|
|
|
|
surveillance: "Verifier targets Prometheus, scrape duration et erreurs de collecte."
|
|
|
|
|
|
|
|
|
|
client_journal:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_loki
|
|
|
|
|
raison: "L'expedition des journaux depend du collecteur central Loki."
|
|
|
|
|
surveillance: "Verifier ingestion Loki, retard et volume de journaux."
|
|
|
|
|
|
|
|
|
|
client_smtp:
|
|
|
|
|
requiert_groupes_actifs:
|
Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix),
client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors
design). Rôles + playbooks de groupe retirés.
Nettoyage des références :
- dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées
mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps
périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak →
serveur_postgresql, la raison parlait à tort de Nextcloud).
- 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix.
- README, AGENTS : listes/glossaire nettoyés.
- catalogue-services : listes, tables, roadmap ; note « rôles retirés ».
- nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux).
- courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs,
intrants, READMEs (client_smtp/forgejo/openldap/unbound).
ansible-lint : 0 échec (366 fichiers). instancier OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 12:14:04 -04:00
|
|
|
- serveur_postfix
|
|
|
|
|
raison: "Les notifications locales doivent relayer vers un MTA actif (Postfix)."
|
2026-06-24 20:17:46 -04:00
|
|
|
surveillance: "Verifier file d'attente, relais SMTP et echecs de livraison."
|
|
|
|
|
|
2026-07-07 03:08:09 -04:00
|
|
|
serveur_postfix:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_dovecot
|
|
|
|
|
raison: "Postfix remet le courrier local via LMTP a Dovecot (mailstore) ; la remise exige Dovecot actif."
|
|
|
|
|
surveillance: "Verifier file d'attente, remise LMTP (status=sent) et rejets."
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
serveur_keycloak:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_postgresql
|
2026-07-07 03:08:09 -04:00
|
|
|
- serveur_openldap
|
|
|
|
|
raison: "Keycloak persiste dans PostgreSQL et federe l'annuaire OpenLDAP (resoudre_annuaire_uri)."
|
|
|
|
|
surveillance: "Verifier connexion base, federation LDAP, etat realm et disponibilite OIDC."
|
|
|
|
|
|
|
|
|
|
serveur_dovecot:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_openldap
|
|
|
|
|
raison: "Dovecot resout ses utilisateurs (userdb/passdb) sur l'annuaire OpenLDAP (resoudre_annuaire_*)."
|
|
|
|
|
surveillance: "Verifier bind LDAP, authentification IMAP et remise LMTP."
|
2026-06-24 20:17:46 -04:00
|
|
|
|
|
|
|
|
serveur_grafana:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_prometheus
|
|
|
|
|
- serveur_loki
|
|
|
|
|
raison: "Grafana est utile comme interface aux metriques et journaux centraux."
|
|
|
|
|
surveillance: "Verifier datasources Prometheus/Loki et authentification."
|
|
|
|
|
|
|
|
|
|
serveur_icinga:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_postgresql
|
|
|
|
|
raison: "La plateforme Icinga Web/BPM depend d'une base relationnelle."
|
|
|
|
|
surveillance: "Verifier moteur Icinga, base, interface web et notifications."
|
|
|
|
|
|
2026-07-07 03:08:09 -04:00
|
|
|
serveur_icingaweb2:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_icinga
|
|
|
|
|
- serveur_postgresql
|
|
|
|
|
- serveur_openldap
|
|
|
|
|
raison: "Frontal web d'Icinga : lit IcingaDB (base), affiche le moteur Icinga et authentifie sur l'annuaire OpenLDAP (resoudre_annuaire)."
|
|
|
|
|
surveillance: "Verifier acces IcingaDB, connexion Icinga et authentification LDAP."
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
serveur_forgejo:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_postgresql
|
|
|
|
|
- serveur_nginx
|
dependances : un ecosysteme minimal n'est pas un ecosysteme incomplet
Le controle de dependances a REFUSE le deploiement de patient 0 : client_journal requiert
serveur_loki, client_metrique requiert serveur_prometheus, serveur_forgejo requiert
serveur_postgresql et serveur_postfix. Quatre refus, une seule racine — le moteur suppose
que tout ecosysteme porte tous les services. Apres les intrants (P32) et les bases (P35),
troisieme manifestation en cinq jours. Et le mur que rencontrerait toute offre plus petite
que l'ecosysteme de reference.
UNE INTEGRATION UNIVERSELLE A BESOIN D'UN INTERLOCUTEUR. « Tout hote est mesure » est vrai
dans un ecosysteme qui porte un Prometheus ; ailleurs, la meme phrase pose sur chaque
machine un client qui n'a personne a qui parler. La regle est desormais DERIVEE : le
service central d'une integration est celui que le registre des dependances lui donne
deja. Rien de neuf a tenir a jour, donc rien de neuf a oublier.
Chezlepro -> diff VIDE (tous ses services existent, rien ne change)
patient 0 -> client_backup, client_pki, client_unbound
UNE EXIGENCE N'EST PAS TOUJOURS ABSOLUE. Deux notions manquaient au registre :
`sauf_si` l'exigence tombe sous condition (Forgejo + SQLite)
`utilise_si_present` un agrement, jamais bloquant (Forgejo notifie SI un MTA existe)
Les confondre obligeait une forge a deployer une pile courriel entiere pour exister.
ET LA LECON D'HIER A SERVI : trois lecteurs avaient besoin le meme jour de lire une
variable d'instance (P35, les clauses sauf_si, le generateur). Trois copies auraient
recommence ce qu'on venait de refermer. Il y en a UNE, dans inventory_rules.
make verifier 41/41 ; make ci 41/41 ; inventaire de Chezlepro identique.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 14:54:00 -04:00
|
|
|
# UNE EXIGENCE PEUT ETRE CONDITIONNELLE (2026-08-22). Depuis que le role sait tenir sa
|
|
|
|
|
# base dans un fichier, exiger un serveur PostgreSQL est faux pour qui a choisi SQLite
|
|
|
|
|
# — et bloquait le deploiement d'un ecosysteme parfaitement coherent.
|
|
|
|
|
sauf_si:
|
|
|
|
|
serveur_postgresql: { variable: serveur_forgejo_bd, vaut: sqlite }
|
|
|
|
|
# UTILISE SI PRESENT : Forgejo envoie des notifications quand un MTA existe, et s'en
|
|
|
|
|
# passe sinon. Ce n'etait pas une EXIGENCE — le confondre avec une exigence obligeait
|
|
|
|
|
# une forge a deployer une pile courriel pour exister.
|
|
|
|
|
utilise_si_present:
|
2026-07-03 15:52:38 -04:00
|
|
|
- serveur_postfix
|
dependances : un ecosysteme minimal n'est pas un ecosysteme incomplet
Le controle de dependances a REFUSE le deploiement de patient 0 : client_journal requiert
serveur_loki, client_metrique requiert serveur_prometheus, serveur_forgejo requiert
serveur_postgresql et serveur_postfix. Quatre refus, une seule racine — le moteur suppose
que tout ecosysteme porte tous les services. Apres les intrants (P32) et les bases (P35),
troisieme manifestation en cinq jours. Et le mur que rencontrerait toute offre plus petite
que l'ecosysteme de reference.
UNE INTEGRATION UNIVERSELLE A BESOIN D'UN INTERLOCUTEUR. « Tout hote est mesure » est vrai
dans un ecosysteme qui porte un Prometheus ; ailleurs, la meme phrase pose sur chaque
machine un client qui n'a personne a qui parler. La regle est desormais DERIVEE : le
service central d'une integration est celui que le registre des dependances lui donne
deja. Rien de neuf a tenir a jour, donc rien de neuf a oublier.
Chezlepro -> diff VIDE (tous ses services existent, rien ne change)
patient 0 -> client_backup, client_pki, client_unbound
UNE EXIGENCE N'EST PAS TOUJOURS ABSOLUE. Deux notions manquaient au registre :
`sauf_si` l'exigence tombe sous condition (Forgejo + SQLite)
`utilise_si_present` un agrement, jamais bloquant (Forgejo notifie SI un MTA existe)
Les confondre obligeait une forge a deployer une pile courriel entiere pour exister.
ET LA LECON D'HIER A SERVI : trois lecteurs avaient besoin le meme jour de lire une
variable d'instance (P35, les clauses sauf_si, le generateur). Trois copies auraient
recommence ce qu'on venait de refermer. Il y en a UNE, dans inventory_rules.
make verifier 41/41 ; make ci 41/41 ; inventaire de Chezlepro identique.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 14:54:00 -04:00
|
|
|
raison: "Forgejo depend d'une base (serveur ou fichier) et d'une publication HTTP(S) ; le courriel est un agrement."
|
2026-06-24 20:17:46 -04:00
|
|
|
surveillance: "Verifier HTTP(S), base, files Git et envoi courriel."
|
|
|
|
|
|
serveur_ops : la difference entre une archive et une matrice
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>
2026-08-23 11:58:10 -04:00
|
|
|
serveur_ops:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_forgejo
|
|
|
|
|
# LE POSTE LIT LE GENOME SUR LA FORGE DE SON PROPRE ECOSYSTEME — c'est ce qui le rend
|
|
|
|
|
# autonome : il ne redemande rien a son parent. Sans forge, il n'a aucune source.
|
|
|
|
|
#
|
|
|
|
|
# Une forge EXTERNE reste possible (un ecosysteme peut lire le genome ailleurs) : il
|
|
|
|
|
# suffit de surcharger `serveur_ops_forge_url`. L'exigence tombe alors, comme pour
|
|
|
|
|
# toute exigence conditionnelle du registre.
|
|
|
|
|
sauf_si:
|
|
|
|
|
serveur_forgejo: { variable: serveur_ops_forge_externe, vaut: true }
|
|
|
|
|
# UTILISE SI PRESENT : sans confiance PKI, `git clone` refuse le certificat de la
|
|
|
|
|
# forge — et il a raison de refuser. Ce n'est pas une exigence du groupe : une forge
|
|
|
|
|
# a certificat public se cloner sans client_pki.
|
|
|
|
|
utilise_si_present:
|
|
|
|
|
- serveur_step_ca
|
|
|
|
|
raison: "Le poste d'exploitation clone le genome depuis la forge de l'ecosysteme ; sans elle, il n'a pas de source."
|
|
|
|
|
surveillance: "Verifier que les depots clones suivent leur amont et qu'ansible repond dans le venv."
|
|
|
|
|
|
2026-08-23 14:41:56 -04:00
|
|
|
client_artefacts:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_artefacts
|
|
|
|
|
# L'INTEGRATION SUIT L'EXISTENCE DU SERVICE. Un ecosysteme sans source d'artefacts
|
|
|
|
|
# prend ses paquets a l'amont : c'est un choix valide, pas une panne. Le role se
|
|
|
|
|
# desactive alors seul (`client_artefacts_actif` derive de l'inventaire) et RETIRE la
|
|
|
|
|
# direction posee auparavant -- sans quoi les hotes resteraient braques sur une
|
|
|
|
|
# machine disparue.
|
|
|
|
|
sauf_si:
|
|
|
|
|
serveur_artefacts: { variable: client_artefacts_actif, vaut: false }
|
|
|
|
|
raison: "Un hote ne peut prendre ses paquets chez lui que si l'ecosysteme heberge une source."
|
|
|
|
|
surveillance: "Verifier que le cache repond sur 3142 et que les hotes le designent bien."
|
|
|
|
|
|
|
|
|
|
serveur_artefacts:
|
|
|
|
|
requiert_groupes_actifs: []
|
|
|
|
|
raison: "Un cache apt ne depend d'aucun service de l'ecosysteme : il ne fait que relayer et retenir."
|
|
|
|
|
surveillance: "Verifier l'ecoute sur 3142, le taux de service depuis le journal, et l'espace du cache."
|
|
|
|
|
|
runner : `serveur_ops_tenant` — le runner d'un tenant recoit enfin sa voute
La doctrine des runners decrit trois portees depuis le 2026-08-22 :
calculer plan -> inventaire aucune voute serveur_ops
configurer roles sur ses machines voute du TENANT <- revendiquee, jamais recue
materialiser creer/detruire des VM voute du SITE serveur_ops_site
La deuxieme ligne etait un trou. RIEN ne deposait jamais la voute d'un tenant sur
son runner. Un runner pouvait deriver son inventaire et ne rien pouvoir en faire :
chaque role qui demande un secret echouait sur son assertion, et l'echec ne disait
pas qu'il manquait un FICHIER, seulement que les valeurs etaient vides.
Decouvert en preparant la reconstruction de Chezlepro. Le runner du SITE peut
materialiser ses quinze machines ; il ne peut pas les configurer, parce que
Chezlepro a sa PROPRE autorite de certification — donc `client_pki` y reclame un
secret de Chezlepro. Le runner du site ne l'a pas, et NE DOIT PAS l'avoir : c'est
la ligne qui rend l'hebergement mutualise defendable.
`serveur_ops_tenant` est le symetrique exact de `serveur_ops_site` : un MARQUEUR,
pas un installateur. Il depose la voute `decrypt: false`, puis RELIT l'en-tete du
fichier depose — une voute dechiffree par accident est une fuite silencieuse. Le
dossier d'inventaire (`principal` ou `production`) se DECOUVRE sur la machine
plutot que d'etre ecrit.
Pourquoi un role a part et non une option de `serveur_ops` : donner sa voute a un
runner est un POUVOIR, pas un reglage. Le declarer au plan force a repondre a
« cette machine a-t-elle le droit de configurer cet ecosysteme ? » — une option
activee par defaut y repondrait a notre place.
CHEZLEPRO LISAIT ENCORE SON GENOME CHEZ PATIENT 0.
Trouve au passage, et bloquant pour la reconstruction : `serveur_ops_forge_amont`
pointait sur `10.29.16.11` — la forge de patient 0, l'amont d'avant que le site
ait la sienne. D-81 a tranche depuis. Laisse tel quel, Chezlepro se serait
reconstruit depuis un moteur perime, sur un reseau que le decoupage en zones a de
toute facon deplace.
Corrige vers la forge du site, PAR SON IP — `forge.genese.internal` appartient a
la zone souveraine du site, et un tenant ne resout que la sienne ; le certificat
SERVI porte bien `IP Address:10.0.33.11`. La racine de l'AC du site est desormais
versionnee a cote de la carte de la fabric a laquelle elle appartient, et son
chemin se DERIVE du symlink `underlay.yml` : il vaut depuis le poste comme depuis
un runner.
Le role est inscrit dans les quatre registres qui l'exigeaient — couches de
deploiement, graphe des dependances, catalogue des services, carte d'orientation.
Ce sont les preuves P08, P38 et P48 qui l'ont reclame, chacune a son tour.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 15:30:51 -04:00
|
|
|
serveur_ops_tenant:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_ops
|
|
|
|
|
# LE RUNNER DE TENANT EST ADDITIF, comme celui du site : il suppose le poste
|
|
|
|
|
# d'exploitation en place, dont il reutilise la racine, l'utilisateur, les depots
|
|
|
|
|
# clones et le lien `instance`. Seul, il ne ferait que deposer un secret sur une
|
|
|
|
|
# machine qui n'a pas le plan qu'il ouvre.
|
|
|
|
|
raison: "Le runner de tenant n'ajoute qu'un pouvoir a un poste d'exploitation existant : sans lui, rien a quoi l'attacher."
|
|
|
|
|
surveillance: "Verifier que la voute de l'ecosysteme est presente ET CHIFFREE sous son dossier d'inventaire."
|
|
|
|
|
|
2026-08-24 15:30:03 -04:00
|
|
|
serveur_ops_site:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_ops
|
|
|
|
|
# LE RUNNER DE SITE EST ADDITIF : il suppose le poste d'exploitation en place, dont il
|
|
|
|
|
# reutilise la racine, l'utilisateur et les depots clones. Seul, il n'aurait ni carte
|
|
|
|
|
# de la fabric ni moteur pour agir.
|
|
|
|
|
raison: "Le runner de site n'ajoute qu'un pouvoir a un poste d'exploitation existant : sans lui, rien a quoi l'attacher."
|
|
|
|
|
surveillance: "Verifier que la voute du site est presente ET CHIFFREE, et que la carte de la fabric est lisible."
|
|
|
|
|
|
2026-08-24 16:59:34 -04:00
|
|
|
serveur_resolveur:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_powerdns
|
|
|
|
|
# Le resolveur prend la zone souveraine en STUB-ZONE : sans autoritatif, il ne saurait
|
|
|
|
|
# resoudre aucun nom de l'ecosysteme, et sa propre validation echouerait.
|
|
|
|
|
raison: "Le resolveur du tenant delegue la zone souveraine a l'autoritatif ; sans lui, il ne sait rien de l'ecosysteme."
|
|
|
|
|
surveillance: "Verifier qu'il repond pour la zone interne ET pour un nom de l'Internet."
|
|
|
|
|
|
2026-07-07 03:08:09 -04:00
|
|
|
serveur_nextcloud:
|
|
|
|
|
requiert_groupes_actifs:
|
|
|
|
|
- serveur_postgresql
|
|
|
|
|
- serveur_keycloak
|
|
|
|
|
- serveur_collabora
|
|
|
|
|
raison: "Nextcloud persiste dans PostgreSQL (verify-full), federe l'identite par OIDC (Keycloak) et valide WOPI contre Collabora (edition en ligne)."
|
|
|
|
|
surveillance: "Verifier base, decouverte OIDC, autodetection WOPI et acces web."
|
|
|
|
|
|