Set-OPS-Public/docs/audit/reference-avant-reconstruction-2026-08-08.md
Daniel Allaire c7fe250520 idempotence de la flotte : zero changed, et le zero est verifie
924 (rejeu depuis zero) -> 17 (2e passage) -> 0 (3e). Zero tache changed,
zero echec sur les quatorze hotes. Le depot n'avait jamais fait ce test a
l'echelle de la flotte.

Verification du zero, parce qu'un zero peut signifier que les roles ne font
plus rien : PLUS de taches se sont executees au passage a vide qu'au rejeu
(2266 contre 2152). Elles ont toutes tourne et toutes trouve le systeme
conforme. Un zero obtenu avec MOINS de taches aurait dit l'inverse.

Ce que le test a rapporte : trois defauts, dont deux n'etaient pas des defauts
d'idempotence mais des PANNES SILENCIEUSES — node_exporter mourait a chaque
renouvellement de certificat sur les 14 hotes, et chaque deploiement
invalidait les jetons OAuth2 de la forge.

Le chiffre devient la ligne de base : un deploiement futur qui rapporte
changed sur une flotte non modifiee signale desormais quelque chose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 15:00:43 -04:00

6.4 KiB
Raw Blame History

État de référence — avant reconstruction from-zero

Figé le 2026-08-08, écosystème chezlepro (index 17, 14 VM), avant destruction et rejeu complet du plan. Ce document existe pour que « identique » soit prouvable plutôt que ressenti. Toute divergence après reconstruction se lit contre lui.

Les cinq devis, avant

identite       CONFORME : le réel correspond au déclaré (1 compte(s) dans l'annuaire).
certificats    CONFORME : aucun certificat servi n'est en fin de vie.
expositions    CONFORME : toute exposition déclarée répond, des deux points de vue.
postgresql     CONFORME : chiffrement imposé, et aucun réseau hors du supernet dérivé.
courriel       CONFORME : la chaîne tient, de la résolution LDAP à la boîte.

Ce que la flotte porte

backup-01 10.27.18.21 1 service(s) metier
collab-01 10.27.21.21 3 service(s) metier
data-sql-01 10.27.18.11 2 service(s) metier
edge-mta-01 10.27.16.21 2 service(s) metier
forge-01 10.27.21.11 1 service(s) metier
idm-01 10.27.17.11 3 service(s) metier
infra-dns-01 10.27.19.11 1 service(s) metier
infra-edge-01 10.27.16.11 2 service(s) metier
infra-mail-01 10.27.19.31 2 service(s) metier
infra-pki-01 10.27.19.21 2 service(s) metier
mon-01 10.27.20.21 6 service(s) metier
obs-01 10.27.20.11 2 service(s) metier
web-dorsal-01 10.27.21.41 2 service(s) metier
web-frontal-01 10.27.21.31 2 service(s) metier

Ce qui sera perdu et devra être refait à la main

Objet Conséquence Geste de reprise
Clé racine de l'AC (/etc/step-ca/secrets/root_ca_key) la racine installée dans le navigateur devient inutile ; tous les certificats changent make ca-racine + réinstaller, en comparant l'empreinte (§6.3)
Mot de passe du compte sysadmin l'annuaire est recréé vide, puis amorcé relever le jeton d'amorçage en voûte (§6.1) et le changer
Contenu applicatif (dépôts Forgejo, fichiers Nextcloud, courriels, tableaux Grafana) non sauvegardé, non reconstructible par le code aucun — assumé : c'est un POC

Ce qui survit : les deux voûtes et ~/.config/setops-vault-pass vivent hors dépôt et hors cluster ; le code est sur eregion.chezlepro.ca (192.168.12.201), machine distincte du tenant. Rien de ce qui est nécessaire au rejeu n'est dans les 14 VM.


Après reconstruction — 2026-08-09

Écosystème détruit (14 VM, disques compris) puis rejoué depuis le plan seul. Aucune sauvegarde restaurée : ni LDAP, ni base, ni certificat, ni fichier.

identite       CONFORME
certificats    CONFORME
expositions    CONFORME
postgresql     CONFORME
courriel       CONFORME

Cinq sur cinq, identiques à la référence. C'est la première fois que le dépôt peut dire que le système reconstruit est celui que le plan décrit — au lieu de dire que le dépôt est cohérent avec lui-même.

Les six défauts que seul un rejeu depuis zéro pouvait montrer

# Défaut Pourquoi il dormait
1 amorcage_acces_courriel jamais déclaré par le tenant le compte existait déjà, le garde-fou n'avait jamais eu à se déclencher
2 rôles de realm créés après leur attachement aux groupes un passage précédent les avait créés
3 claim de groupes posé avant les clients OIDC les clients existaient déjà
4 écriture Keycloak annulée par le collecteur de transactions la synchro LDAP complète ne se rejoue pas en exploitation
5 grafana-cli lancé avant que Grafana ait fini de démarrer le service tournait depuis toujours
6 port d'Alloy (12345) en collision avec le SASL de Dovecot Alloy tenait le port ; c'est Dovecot qui échouait, en silence

Trois défauts d'ordre, deux courses de premier démarrage, un conflit de port. Aucun n'était visible à un redéploiement, et aucun aux 31 preuves statiques — elles lisent le dépôt, pas la machine.

Le sixième mérite d'être relu : le conflit existait depuis toujours, mais dans l'autre sens. Alloy tenait 12345 et l'écoute SASL de Dovecot échouait sans que personne ne le voie. La reconstruction a inversé l'ordre de démarrage et rendu visible un défaut qui était là depuis le début.

Ce qui a dû être refait à la main

  • La base de Grafana : le premier démarrage, interrompu par le défaut nº 5, avait laissé un schéma à moitié migré (no such column: with_credentials). Base mise de côté, recréée par Grafana — 95 s pour lier son port, ce qui explique la course.
  • Rien d'autre. Ni certificat, ni compte, ni zone DNS, ni base de données.

Idempotence de la flotte — référence du 2026-08-09

Mesure faite après la seconde reconstruction, en rejouant make deployer-tout sur une flotte intacte. Le dépôt n'avait jamais fait ce test à l'échelle de la flotte.

                      plays   taches ok   changed   sautees
rejeu depuis zero       61        2152       924       443
2e passage              30        2249        17       ...
3e passage (apres)      30        2266         0       227

Zéro tâche changed, zéro échec.

Et ce zéro n'est pas du silence : plus de tâches se sont exécutées au passage à vide qu'au rejeu (2266 contre 2152). Elles ont toutes tourné, et toutes trouvé le système conforme. Un zéro obtenu avec moins de tâches aurait signifié l'inverse — des rôles qui ne font plus leur travail.

Ce que les 17 du deuxième passage cachaient

Tâche Ce que c'était vraiment
13× Activer et demarrer node_exporter le service était mort — tué par SIGHUP à chaque renouvellement de certificat
2× Prometheus liste de cibles non ordonnée (intersect rend un ensemble)
2× Forgejo le dépôt faisait tourner le secret JWT du service à chaque déploiement

Deux des trois n'étaient pas des défauts d'idempotence : c'étaient des pannes, qu'un compte de changed a rendues visibles. La collecte de métriques s'arrêtait toutes les 24 heures sur les quatorze hôtes, et les jetons OAuth2 de la forge étaient invalidés à chaque passage. Ni l'une ni l'autre ne se signalait autrement.

À quoi sert ce chiffre

Il devient la ligne de base. Un déploiement futur qui rapporte changed sur une flotte non modifiée signale quelque chose : soit une dérive du système, soit un rôle qui a cessé d'être idempotent. Tant que le fond était à 17, ce signal était noyé.