--- # LES RUNBOOKS DE CONSTRUCTION — l'ordre des gestes, et pourquoi celui-la. # # CE QUE CE FICHIER AJOUTE AU MAKEFILE, ET CE QU'IL NE REPETE PAS. # # Les 132 cibles documentees du Makefile disent chacune CE QU'ELLE FAIT. Aucune ne dit # dans quel ORDRE, ni pourquoi maintenant, ni ce qu'il faut avoir mesure avant. Cette # connaissance-la vivait en prose dans `docs/runbooks-exploitation.md`, # `docs/implanter-un-tenant-sur-un-site.md` et `docs/preparer-un-site-hebergeur.md` — et # la console offrait des boutons sans sequence. # # ON NE RECOPIE PAS LE LIBELLE D'UNE CIBLE. `scripts/runbooks.py` va le lire dans le # Makefile au moment de servir. Un libelle recopie ici serait une seconde liste, et une # liste qui suit une autre prend du retard sur elle. Ce fichier ne porte donc que ce que # le Makefile ne peut pas porter : l'ordre, la nature du geste, la portee, le pourquoi. # # LA GARDE EST ECRITE AVEC LA LISTE, PAS APRES. `python3 scripts/runbooks.py verifier` # (et P83) refusent qu'une cible documentee ne soit ni portee par un runbook ni exemptee # avec un motif. Sans cela, la console cacherait des pouvoirs que le moteur possede. # # NATURE D'UNE ETAPE # mesure n'ecrit rien, rejouable sans consequence, proposee meme apres un echec # ecriture change l'etat du monde ; exige que l'etape precedente ait reussi # destructif detruit ; exige une confirmation ecrite en plus de CONFIRMER=true # # PORTEE D'UN RUNBOOK — ce que la MACHINE porte, au sens de `contexte()` : # tenant un ecosysteme est monte (`instance/`) : on le configure # site une fabric est montee (`underlay.yml`) : on materialise # poste les deux — l'atelier du mainteneur # toute ni l'un ni l'autre n'est requis # # LA PORTEE SE PESE A L'ETAPE (2026-09-20). Un runbook donne le defaut ; une etape qui # exige davantage le declare avec son propre `portee:`. Mesure faite sur la console de # TechnoLibre : declaree au seul runbook, une unique etape qui materialise (`flotte-creer`, # `creer-vm`) faisait basculer TOUTE la sequence en `poste` — et un locataire ne pouvait # plus deployer sa propre flotte, ce qui est exactement son metier. Le locataire conduit # donc sa sequence, et bute precisement la ou il faut : sur la machine a engendrer. # CE QUE LA CONSOLE DOIT DEMANDER A L'EXPLOITANT. Une variable absente d'ici est refusee # par la garde : la console ne saurait pas quoi afficher, et un champ libre sans invite # est une invitation a se tromper. variables: HOTE: invite: "La machine" source: hotes # la liste vient de l'inventaire actif GROUPE: invite: "Le groupe (role)" source: groupes NOM: invite: "Nom du dossier de l'ecosysteme" exemple: "OPS-Machin" MODELE: invite: "Modele de depart" source: modeles INSTANCE: invite: "Nom de l'ecosysteme a detruire (il doit etre ecrit en toutes lettres)" SITE: invite: "Depot du site a detruire (ecrit en toutes lettres)" TENANT: invite: "Dossier du locataire a amorcer" exemple: "OPS-Machin" DEPOT: invite: "Un seul depot (vide = tous ceux que le runner porte)" facultatif: true VERS: invite: "Repertoire de destination (une cle chiffree, hors du poste)" ARCHIVE: invite: "Fichier d'archive a restaurer" CIBLE: invite: "Hote ou adresse a sonder" SERVICE: invite: "Le lien dont on prouve la coupure" valeurs: [artefacts, genome, resolveur] ROLE: invite: "Un seul role (vide = tous)" facultatif: true LIMITE: invite: "Motif d'hotes" facultatif: true RECU_PAR: invite: "Qui recoit la remise (nom complet)" COURRIEL: invite: "Courriel de la personne qui recoit" DANS: invite: "Jours avant le second temps" facultatif: true JEU: invite: "Le jeu d'etat (openldap, postgresql, nextcloud... — voir restauration-etat)" DEPUIS: invite: "Reprendre a cette etape (vide = depuis le debut)" valeurs: [sauvegarder, raser, creer, inseminer, armer, monter, parefeu, bilan] facultatif: true ARMER: invite: "Armer sans marquer la pause" valeurs: [oui] facultatif: true SOURCE: invite: "Comparer a quel instantane (vide = celui d'avant rasage)" valeurs: [candidat] facultatif: true VMID: invite: "Identifiant Proxmox de la VM" DIALECTE: invite: "Dialecte du commutateur" valeurs: [cisco, binardat] facultatif: true PARALLELE: invite: "Combien de VM a la fois" facultatif: true runbooks: # ───────────────────────────────────────────────────────────────────────────── - id: site-premier-jour titre: "Le premier jour d'un site" portee: site doc: docs/runbooks-exploitation.md but: >- Faire naitre un site hebergeur depuis une fabric nue : les machines, puis le moteur, puis la forge qui permettra aux locataires de se reproduire. L'ordre n'est pas une preference — le premier passage s'ARRETE sur une forge vide, et c'est normal. etapes: - cible: underlay nature: mesure pourquoi: >- La fabric declaree tient-elle debout toute seule ? Rien ne sert de creer des machines sur un plan d'adressage qui se contredit. - cible: underlay-plan nature: mesure pourquoi: >- Le declare face au REEL, par l'API du cluster et une sonde TCP. C'est ici qu'on apprend qu'un pont n'existe pas, pas au milieu de la creation des VM. - cible: site-creer nature: ecriture fixes: {CONFIRMER: "true"} duree: "~9 min" pourquoi: >- Les machines du site, depuis l'underlay. Elles naissent ; elles ne repondent pas encore. - cible: site-deployer-tout nature: ecriture fixes: {CONFIRMER: "true"} duree: "~20 min" pourquoi: >- Premier passage. Il va jusqu'a `serveur_ops` et s'arrete sur la forge vide : ce n'est pas un echec, c'est le maillon suivant. - cible: forge-amorcer nature: ecriture fixes: {CONFIRMER: "true"} duree: "~45 s" pourquoi: >- La forge tourne et n'a ni organisation ni depot. Sans cet amorcage, le runner clone le vide et le deploiement ne finira jamais. - cible: site-deployer-tout nature: ecriture fixes: {CONFIRMER: "true"} duree: "~4 min" pourquoi: >- Second passage. Celui-ci doit finir a zero echec ; s'il n'y arrive pas, c'est un vrai defaut, plus un maillon manquant. - cible: publier nature: ecriture variables: [DEPOT] pourquoi: >- Le geste quotidien : eregion ET la forge du site, puis la verification. Un `git push` seul laisse la forge du site en retard sans que rien le dise. - cible: genome-pousser nature: ecriture variables: [DEPOT] pourquoi: >- La forge du site FAIT AUTORITE : tant qu'elle est en retard, tout ecosysteme qui s'y reproduit reproduit un moteur perime. - cible: routes-fabric-etat nature: mesure pourquoi: >- Les hyperviseurs routent-ils toutes les zones ? Une zone non routee ne se voit qu'au moment ou un locataire y pose sa premiere machine. - cible: gabarit-etat nature: mesure pourquoi: >- Sans gabarit conforme, aucun locataire ne pourra cloner quoi que ce soit ici. # ───────────────────────────────────────────────────────────────────────────── - id: site-tenir titre: "Tenir un site en etat" portee: site doc: docs/hebergeur-exploitation.md but: >- Les gestes reguliers de l'hebergeur : porter le genome a jour, appliquer un role aux machines du site, et regarder ce que la fabric fait vraiment. etapes: - cible: genome-etat nature: mesure pourquoi: >- Ce que la forge porte, face au poste. Un ecart ici se paie chez TOUS les locataires qui clonent ensuite. - cible: genome-pousser nature: ecriture variables: [DEPOT] pourquoi: "Remettre la forge au niveau du poste, depot par depot si besoin." - cible: site-appliquer nature: ecriture variables: [GROUPE] pourquoi: >- Rejouer un role sur les machines du site — c'est ainsi qu'un runner reprend le genome courant, rien ne le tire tout seul. - cible: site-decrire nature: mesure pourquoi: "Ce que l'underlay declare comme machines de l'hebergeur." - cible: site-inventaire nature: mesure pourquoi: "L'inventaire dynamique du site, tel qu'Ansible le voit — pas tel qu'on l'imagine." - cible: site-intrants nature: mesure pourquoi: "Ce que ce site expose a ses locataires, derive et non declare deux fois." - cible: fiches-site-deposer nature: ecriture pourquoi: >- Deposer chez chaque locataire la fiche que le site lui destine. Son runner n'a pas le depot du site : c'est par elle que son inventaire se genere sans lui. A commiter dans le depot de chaque locataire. - cible: site-verifier nature: mesure pourquoi: "Le playbook du site correspond-il encore aux couches declarees ?" - cible: site nature: ecriture pourquoi: "Regenerer playbooks/site.yml quand les couches ont bouge." - cible: routes-fabric-etat nature: mesure pourquoi: "Une route de zone manquante est invisible jusqu'au premier invite qui la traverse." - cible: locataire-creer nature: ecriture variables: [TENANT, PARALLELE] fixes: {CONFIRMER: "true"} pourquoi: >- Cloner les VM d'un locataire NOMME, d'apres la face reseau qu'il publie : le runner du site materialise sans monter son depot. Memes machines, memes parametres que `flotte-creer` sur l'instance montee (P93, P94). - cible: locataire-raser nature: destructif variables: [TENANT, INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM d'un locataire NOMME, d'apres sa face : les memes VMID que le plan derive (P94). Son nom court s'ecrit en toutes lettres, comme pour `raser`. - cible: site-raser nature: destructif variables: [SITE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM du SITE. A ne faire que sur un site de chantier : la reconstruction est prouvee, elle n'est pas gratuite. # ───────────────────────────────────────────────────────────────────────────── - id: locataire-naitre titre: "Faire naitre un ecosysteme de locataire" portee: tenant doc: docs/multi-instances.md but: >- Du modele au plan monte : creer le dossier de l'ecosysteme, le rendre actif, puis generer son inventaire. Tout l'adressage descend du seed `index` — on ne l'ecrit jamais a la main. etapes: - cible: instance-modeles nature: mesure pourquoi: "Quels modeles de depart existent, avant d'en choisir un." - cible: instances nature: mesure pourquoi: >- Les ecosystemes deja decouverts, et surtout les COLLISIONS d'index : deux ecosystemes sur le meme seed se marcheraient dessus en silence. - cible: instance-creer nature: ecriture variables: [NOM, MODELE] pourquoi: "Le dossier de l'ecosysteme, depuis un modele, avec son index reserve." - cible: instance-utiliser nature: ecriture variables: [NOM] pourquoi: >- Basculer le symlink `instance/`. C'est lui qui decide QUEL ecosysteme la console configure — et quelle voute elle ouvrira. - cible: instance-courante nature: mesure pourquoi: "Verifier vers quoi on pointe avant d'ecrire quoi que ce soit." - cible: intrants-verifier nature: mesure pourquoi: >- Tout intrant qu'un role EXIGE est-il fourni ? Un intrant manquant ne se voit sinon qu'au milieu d'un deploiement. - cible: ports-verifier nature: mesure pourquoi: "Deux roles co-localises qui reclament le meme port ne cohabiteront pas." - cible: instancier nature: mesure pourquoi: >- Generer hosts.yml depuis le plan SANS l'appliquer — on regarde le diff avant de le prendre. - cible: instancier-appliquer nature: ecriture pourquoi: >- Prendre l'inventaire genere. `hosts.yml` est un ARTEFACT : on edite le plan, on ne le corrige jamais a la main. - cible: inventaire-verifier nature: mesure pourquoi: "L'inventaire se parse-t-il, voute dechiffree ? Sinon rien ne partira." # ───────────────────────────────────────────────────────────────────────────── - id: locataire-materialiser titre: "Preparer le terrain d'un locataire sur la fabric" portee: site doc: docs/implanter-un-tenant-sur-un-site.md but: >- Tout ce que l'HEBERGEUR pose avant qu'un locataire puisse exister : le placement, les pools, le SDN, les pare-feux et la frontiere. Chaque devis se mesure avant de s'appliquer — un devis qu'on applique sans l'avoir lu est un pari. etapes: - cible: placement-plan nature: mesure pourquoi: >- Le noeud, le stockage, le pont et le gabarit existent-ils VRAIMENT sur ce cluster ? C'est la premiere chose qui manque, et la derniere qu'on regarde. - cible: devis-proxmox-pools nature: mesure pourquoi: "Un pool par locataire, derive du plan — la cloison la plus simple." - cible: devis-proxmox-pools-verifier nature: mesure pourquoi: "Le devis tient-il ses propres regles avant qu'on le pose ?" - cible: devis-sdn nature: mesure pourquoi: "Zone, VNets et sous-reseaux, derives du seed de l'ecosysteme." - cible: devis-sdn-verifier nature: mesure pourquoi: "Relire le devis SDN avant de toucher au reseau du cluster." - cible: sdn-plan nature: mesure pourquoi: "L'ecart entre le SDN en service et ce devis — ce qui manque, ce qui est perime." - cible: sdn-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Reconcilier : creer ce qui manque et RETIRER ce qui est perime. Le retrait est la moitie qu'on oublie. - cible: flux nature: ecriture pourquoi: >- Regenerer le registre des flux et les regles nftables depuis les `meta/flux.yml` des roles. Tout ce qui suit en descend. - cible: face-reseau-publier nature: ecriture pourquoi: >- Publier ce que ce locataire demande a son site (`face-reseau.yml`) : ses machines, ses zones, ses flux deja resolus. Le site ne lit plus que ce fichier. Apres `flux`, et a commiter dans le depot du locataire. - cible: devis-proxmox-fw nature: mesure pourquoi: "Le pare-feu est-ouest intra-locataire, derive du registre des flux." - cible: devis-proxmox-fw-verifier nature: mesure pourquoi: "Relire ce devis avant de le poser sur le cluster." - cible: proxmox-fw-plan nature: mesure pourquoi: "L'ecart entre le pare-feu en service et le devis." - cible: proxmox-fw-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: "Poser IPSets, groupes et affectations — et retirer ce qui ne se declare plus." - cible: proxmox-fw-eprouver nature: mesure variables: [TENANT, HOTE] pourquoi: >- Avant d'activer le pare-feu d'UNE VM : les regles du devis tiennent-elles face aux flux que la VM recoit REELLEMENT ? Une VM reconstruite a perdu ses options. - cible: proxmox-fw-activer-vm nature: ecriture variables: [TENANT, HOTE] fixes: {CONFIRMER: "true"} pourquoi: >- Activer une VM a la fois, matrice avant et apres, Icinga lu. Chaque defaut du 2026-09-28 ne s'est montre qu'a l'activation d'UNE VM. - cible: devis-opnsense nature: mesure pourquoi: "La frontiere nord/sud, derivee du meme registre de flux." - cible: devis-opnsense-verifier nature: mesure pourquoi: "Relire le devis de frontiere : c'est la porte de l'exterieur." - cible: frontiere-plan nature: mesure pourquoi: "Ce que la frontiere porte aujourd'hui, face a ce devis." - cible: frontiere-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Reconcilier la frontiere. Les routes creees ETEINTES ont deja coute une journee : une route eteinte compte « posee » et ne route rien. - cible: devis-reseau nature: mesure variables: [DIALECTE] pourquoi: >- Le devis des commutateurs physiques (VLANs, SVIs, ACLs). Il se pose a la main sur le materiel — le moteur ne configure pas les switches. - cible: frontiere-mesurer nature: mesure pourquoi: >- La frontiere refuse-t-elle ce qui n'est pas declare ? Un connect() qui aboutit ne prouve rien : seule la LIVRAISON compte. # ───────────────────────────────────────────────────────────────────────────── - id: locataire-deployer titre: "Materialiser et deployer la flotte d'un locataire" portee: tenant doc: docs/vm-lifecycle.md but: >- Des VM au service rendu : creer les machines manquantes, deployer couche par couche, puis mesurer. Rien n'est « pret » avant la recette. etapes: - cible: flotte-creer nature: ecriture portee: poste variables: [PARALLELE] fixes: {CONFIRMER: "true"} pourquoi: >- Les VM manquantes, clonees depuis le gabarit dore. VMID, IP et VLAN sont DERIVES du plan : on ne les saisit nulle part. - cible: monter-flotte nature: ecriture duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Des VM qui viennent de naitre (ou de renaitre) a la flotte recettee : flux, AC et DNS d'abord, tout le reste, puis `valider`. C'est la sequence du runner apres une reconstruction ; chaque proprietaire d'etat y remet celui d'avant. - cible: deployer-tout nature: ecriture duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Toute la flotte, dans l'ordre des couches. L'ordre vient du graphe de dependances, pas d'une liste tenue a la main. - cible: deployer-groupe nature: ecriture variables: [GROUPE] facultative: true pourquoi: >- Un seul role, sur toute la flotte. C'est le geste d'apres : quand un role a change et qu'on ne veut pas tout rejouer. - cible: appliquer nature: ecriture variables: [GROUPE] facultative: true pourquoi: >- Appliquer un groupe a la flotte. Meme usage que `deployer-groupe`, par le chemin court — sans le graphe des couches. - cible: verifier-deploiement nature: mesure pourquoi: "L'etat de la flotte apres coup — avant de croire que c'est fini." - cible: valider nature: mesure pourquoi: >- La recette de validation sur la flotte. C'est elle qui autorise le mot « pret », pas l'absence d'erreur rouge. # ───────────────────────────────────────────────────────────────────────────── - id: machine-une titre: "Ajouter ou reprendre une seule machine" portee: tenant doc: docs/vm-lifecycle.md but: >- Le cycle d'UNE machine, du plan au service : la voir derivee, la creer, la deployer, la verifier. Le meme chemin sert pour une machine neuve et pour une machine a reprendre. etapes: - cible: hote-afficher nature: mesure variables: [HOTE] pourquoi: >- Tout ce que le plan derive pour cette machine — avant de la creer, pour verifier qu'on va bien poser ce qu'on croit. - cible: creer-vm nature: ecriture portee: poste variables: [HOTE] duree: "~4 min 30" pourquoi: "Cloner depuis le gabarit et ATTENDRE que la machine reponde." - cible: deployer nature: ecriture variables: [HOTE] pourquoi: "Les roles de cette machine, couche par couche, dans l'ordre du graphe." - cible: verifier-hote nature: mesure variables: [HOTE] pourquoi: "Le playbook de verification sur cette machine seule." - cible: cloner-vm nature: ecriture portee: poste variables: [HOTE, VMID] facultative: true pourquoi: >- Cloner SANS passer par le plan. Chemin de reprise : a n'emprunter que lorsque le plan ne peut pas encore deriver la machine. # ───────────────────────────────────────────────────────────────────────────── - id: flotte-refaire titre: "Raser et reconstruire un ecosysteme" portee: tenant doc: docs/vm-lifecycle.md but: >- La preuve la plus dure du moteur : detruire un ecosysteme et le refaire depuis le code seul. A ne lancer que sur un chantier — la prod vit ailleurs. etapes: - cible: reconstruire-locataire nature: destructif portee: poste duree: "long" variables: [TENANT, DEPUIS, ARMER] fixes: {CONFIRMER: "true"} pourquoi: >- TOUT, d'une commande, depuis le poste : sauvegarder, raser et recreer (runner du site), amorcer, armer, monter (runner du locataire, etat remis), pare-feu, bilan. Arret a la premiere etape en echec ; `DEPUIS` reprend. Les etapes ci-dessous sont les memes, une a une. - cible: sauvegarder-maintenant nature: ecriture pourquoi: >- Deposer l'etat de chaque noeud JUSTE AVANT de raser. La reconstruction remet le dernier instantane anterieur a la naissance des machines : sans ce depot, c'est celui de la nuit, et la journee est perdue. Il est etiquete « avant-raser » et garde jusqu'a la reconstruction suivante : c'est contre lui que jugent les temoins. - cible: raser nature: destructif portee: poste variables: [INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Detruire les VM derivees du plan. Le nom de l'ecosysteme s'ecrit en toutes lettres : c'est le seul garde-fou qui resiste a un clic distrait. - cible: reconstruire nature: ecriture portee: poste duree: "long" fixes: {CONFIRMER: "true"} pourquoi: >- Refaire tout depuis zero : les VM, puis le deploiement complet — ou chaque role proprietaire REMET l'etat de l'incarnation precedente (AC, annuaire, bases, Nextcloud, courriel, DKIM). Si le code ne suffit pas, c'est ici qu'on l'apprend. - cible: restauration-etat nature: mesure pourquoi: >- Ce que chaque jeu est devenu : restaure (et depuis quel instantane), neuf, en place. Un jeu EN ATTENTE bloque la sauvegarde de son noeud — c'est voulu. - cible: temoins-etat nature: mesure variables: [HOTE, SOURCE] pourquoi: >- L'etat vivant est-il celui d'avant le rasage ? Une perte, ou une identite changee (cles de l'AC, DKIM, instanceid de Nextcloud, mot de passe d'une entree de l'annuaire), est un ecart. Le bilan dit ce que les roles ont fait ; les temoins mesurent ce qui est revenu. - cible: restauration-renoncer nature: destructif variables: [HOTE, JEU] fixes: {CONFIRMER: "true"} pourquoi: >- Ecarter l'etat d'avant d'un jeu, sans le remettre. La sauvegarde reprend, et l'ancien etat sortira de la retention : une decision, pas une reparation. - cible: valider nature: mesure pourquoi: "Une reconstruction sans recette n'a rien prouve." - cible: parefeu-verifier-flotte nature: mesure portee: poste variables: [INSTANCE] pourquoi: >- La sonde `connectivite` est-elle saine sur chaque VM ? C'est le prealable : une VM clonee nait sans ses options de pare-feu, et on n'active que sur une flotte saine. - cible: parefeu-activer-flotte nature: ecriture portee: poste variables: [INSTANCE] fixes: {CONFIRMER: "true"} pourquoi: >- Tout activer d'un coup, puis lire la sonde `connectivite` que chaque VM rapporte a la minute : seul ce qui change apres l'activation compte. Environ trois minutes. # ───────────────────────────────────────────────────────────────────────────── - id: gabarit titre: "Le gabarit dore" portee: site doc: docs/procedure-template-debian13-proxmox.md but: >- La VM de reference que toute la flotte clone. Elle nait en q35/OVMF et ne se convertit jamais : convertir depuis i440fx casse interfaces et disques. etapes: - cible: gabarit-etat nature: mesure pourquoi: "Le gabarit porte-t-il ce que le SITE declare ? A regarder avant d'y toucher." - cible: preparer-modele nature: ecriture duree: "long" pourquoi: "Preparer la VM de reference, celle qui sera clonee pour chaque hote." - cible: verifier-modele nature: mesure pourquoi: "Le gabarit tient-il ses promesses avant qu'on le capture ?" - cible: nettoyer-modele nature: destructif fixes: {CONFIRMER: "true"} pourquoi: >- Nettoyer avant capture. Destructif pour la VM de reference : ce qui est efface ne se retrouve pas. # ───────────────────────────────────────────────────────────────────────────── - id: mesurer titre: "Mesurer sans rien ecrire" portee: tenant doc: docs/devis-services.md but: >- Les devis de service : ils confrontent ce que le plan derive a ce que le systeme rend VRAIMENT, et sortent en erreur s'il y a un ecart. Une tache verte ne prouve pas qu'un service rend son service. etapes: - cible: identite-plan nature: mesure pourquoi: "L'identite deployee face a ce que le plan derive." - cible: certificats-plan nature: mesure pourquoi: >- Les certificats sur disque face a ceux reellement SERVIS. Un cert renouvele mais non recharge reste perime en memoire. - cible: expositions-plan nature: mesure pourquoi: "Chaque exposition du plan repond-elle, depuis l'edge et depuis le poste ?" - cible: expositions-etat nature: mesure pourquoi: "Chaque exposition est-elle servie sous un certificat qui la porte ?" - cible: courriel-plan nature: mesure pourquoi: "La chaine Postfix → LDAP → Dovecot → IMAP, de bout en bout." - cible: postgresql-plan nature: mesure pourquoi: "Le chiffrement impose et la portee reelle des acces." - cible: mtu-mesurer nature: mesure pourquoi: "L'invite porte-t-il le MTU de sa zone ? Un MTU faux ne se voit qu'aux gros paquets." - cible: versions-mesurer nature: mesure pourquoi: "De combien nos epinglages ont-ils vieilli face aux amonts ?" - cible: ports-verifier nature: mesure pourquoi: "Deux roles co-localises revendiquent-ils le meme port ?" - cible: intrants-verifier nature: mesure pourquoi: "Un intrant exige et non fourni est une panne differee." - cible: flux-verifier nature: mesure pourquoi: "Le registre des flux correspond-il encore aux `meta/flux.yml` des roles ?" - cible: site-intrants-verifier nature: mesure pourquoi: "Le locataire monte suit-il encore les intrants de son site ?" - cible: sonder nature: mesure variables: [CIBLE] pourquoi: >- Sonder une cible et DIRE ce qui distingue absence, politique et frontiere. Un « echec » nu ecrase ces trois causes et envoie chercher la panne ailleurs. - cible: faits nature: mesure variables: [LIMITE] pourquoi: "Les faits Ansible de la flotte, quand une hypothese demande un fait." # ───────────────────────────────────────────────────────────────────────────── - id: recette titre: "La recette — avant de dire « pret »" portee: tenant doc: docs/audit/plan-de-recette.md but: >- Ce qui separe « ca a tourne sans erreur » de « c'est livrable ». Les preuves lisent le depot ; la recette interroge la flotte. Il faut les deux. etapes: - cible: verifier nature: mesure pourquoi: "Rejouer les preuves sans reecrire le rapport — la verification rapide." - cible: prouver nature: mesure pourquoi: >- Executer les preuves et ECRIRE le rapport date. C'est le document qu'on montre, et celui qu'on relit dans six mois. - cible: valider nature: mesure pourquoi: "La recette de validation sur la flotte reelle." - cible: verifier-deploiement nature: mesure pourquoi: "L'etat de la flotte, apres coup." - cible: inventaire nature: mesure pourquoi: "L'inventaire se verifie et se montre — lab puis production." # ───────────────────────────────────────────────────────────────────────────── - id: acces-admin titre: "L'acces d'administration (tunnel WireGuard)" portee: site doc: docs/acces-administration.md but: >- Un tunnel nominatif par locataire, declare par lui et borne a lui. Sans garde, un ecosysteme s'ouvrirait un acces chez son voisin depuis son propre plan. etapes: - cible: vpn-admin-plan nature: mesure pourquoi: "Ce que la frontiere porte aujourd'hui, face aux pairs declares au plan." - cible: vpn-admin-appliquer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: "Poser l'instance et les pairs declares — et retirer ceux qui ne le sont plus." # ───────────────────────────────────────────────────────────────────────────── - id: dns-public titre: "Le DNS public et sa signature" portee: tenant doc: docs/dns-interne.md but: >- Publier les zones du locataire, signees avant d'etre exposees. Les DS partent chez le registraire : c'est le seul maillon que le moteur ne peut pas poser lui-meme. etapes: - cible: dnssec-verifier nature: mesure pourquoi: "Une cle en voute pour chaque zone signee, et des DS conformes au registre." - cible: dnssec-ds nature: mesure pourquoi: >- Les DS a remettre au registraire, calcules depuis la voute du locataire. A porter a la main chez le registraire : aucun automate ne le fera. - cible: dns-bascule-devis nature: mesure pourquoi: >- Basculer nos serveurs de noms changerait-il quelque chose ? Le plan face au DNS reellement en service, avant de toucher a la delegation. # ───────────────────────────────────────────────────────────────────────────── - id: filiation titre: "Filiation, insemination, emancipation" portee: tenant doc: docs/filiation-emancipation.md but: >- D'ou vient cet ecosysteme, de quoi depend-il encore, et que faut-il couper pour qu'il tienne seul. L'emancipation se mesure ; elle ne se decrete pas. etapes: - cible: genome nature: mesure pourquoi: "Les depots requis a la reproduction de cet ecosysteme, et leur etat." - cible: genome-inscrire nature: ecriture pourquoi: "Inscrire la parente dans l'instance — sans quoi la filiation n'est qu'un souvenir." - cible: genome-verifier nature: mesure pourquoi: "La parente inscrite tient-elle encore ? Le code de sortie repond." - cible: inseminer nature: ecriture variables: [TENANT, HOTE] pourquoi: >- Le SITE amorce le runner d'un locataire, SANS ses secrets. Trois murs connus : apt, pip, et le genome lui-meme. - cible: depots-perimes nature: destructif fixes: {CONFIRMER: "true"} # FACULTATIVE, SINON ELLE BARRE LA PREUVE QUI LA SUIT. La console # debloque d'office une etape « mesure » ; toute autre attend que la # precedente non facultative ait REUSSI dans la session. Un menage # qu'on peut ne pas avoir a faire — aucun depot perime ce jour-la — # rendrait alors l'emancipation injouable. Le ménage n'est pas un # prealable a la preuve : il nettoie ce que la filiation a laisse. facultative: true pourquoi: >- Un depot raye du plan reste sur le disque du runner, qui garde de quoi lire un ecosysteme qu'il ne declare plus. Trois choses ne sont jamais retirees : ce qui n'est pas un depot git, ce qui porte des modifications non validees, et ce qui porte des commits qu'aucun distant ne porte. - cible: emancipation-prouver # ECRITURE, ET NON MESURE, MALGRE LE MOT « PROUVER ». La cible COUPE # l'amont quelques secondes pour mesurer : elle refuse d'ailleurs sans # CONFIRMER=true, et le dit. Le fait qu'elle rapporte un constat ne la # rend pas inerte. Declarée « mesure », elle se serait offerte a tout # outil qui ne propose que ce qui n'agit pas. nature: ecriture variables: [SERVICE, HOTE] fixes: {CONFIRMER: "true"} pourquoi: >- Prouver qu'un lien est coupe, en le coupant. La coupure est retiree quoi qu'il arrive, mais la fonction eprouvee peut echouer pendant ce temps. La mesure instruit ; l'humain decide. Une emancipation automatique serait une expulsion. # ───────────────────────────────────────────────────────────────────────────── - id: remise titre: "La remise au client" portee: poste doc: docs/remise-au-client.md but: >- Deux temps qui ne se confondent pas : le paquet qu'on remet, puis le re-cle qui mesure la revocation reelle. Tant que le temps 2 n'est pas fait, on detient encore les cles de quelqu'un d'autre. etapes: - cible: remise-recenser nature: mesure pourquoi: "Ce qu'une remise emporterait, sans rien ecrire. A lire avant de fabriquer." - cible: remise-paquet nature: ecriture variables: [VERS] pourquoi: "Temps 1 : le paquet chiffre, et relu apres ecriture." - cible: remise-inscrire nature: ecriture variables: [RECU_PAR, COURRIEL, DANS] pourquoi: >- Inscrire la remise chez le locataire : qui a recu, quand, et dans combien de jours le second temps est du. - cible: remise-verifier nature: mesure pourquoi: "Temps 1 fait ? Temps 2 du, ou echu ? La seule reponse qui compte est datee." - cible: remise-recleer nature: ecriture fixes: {CONFIRMER: "true"} pourquoi: >- Temps 2 : mesurer la revocation REELLE, puis estampiller. On ne coche pas cette case, on la mesure. # ───────────────────────────────────────────────────────────────────────────── - id: cles titre: "Les cles hors du poste" portee: poste doc: docs/sortir-les-cles-du-poste.md but: >- Ce qui n'existe QUE sur le poste meurt avec lui : les CLES, et les VOUTES qu'elles ouvrent (gitignorees, donc sur aucune forge). Les deux sortent, sur un support qu'on relit — et on refait l'operation a chaque voute nouvelle ou modifiee. etapes: - cible: cles-recenser nature: mesure pourquoi: "Ce qui n'existe que sur ce poste, sans rien ecrire. La liste fait peur, c'est le but." - cible: cles-exporter nature: ecriture variables: [VERS] pourquoi: "Sortir les cles, chiffrees, et les RELIRE apres ecriture." - cible: voutes-recenser nature: mesure pourquoi: "Les voutes de ce poste, et leur empreinte. Une voute en clair est refusee avant tout." - cible: voutes-exporter nature: ecriture variables: [VERS] pourquoi: >- Sortir les voutes, deja chiffrees, dans leur propre archive, et la RELIRE. Sans elles, les cles restaurees n'ouvrent rien (2026-09-28). - cible: cles-compagnons nature: ecriture variables: [VERS] pourquoi: >- Deposer le script de restauration sur la cle. Une archive qu'on ne sait pas rouvrir dans cinq ans n'est pas une sauvegarde. - cible: cles-restaurer nature: ecriture variables: [ARCHIVE] pourquoi: "Remettre les cles en place. A eprouver AVANT d'en avoir besoin." - cible: depot-hors-site nature: ecriture variables: [VERS] pourquoi: >- Copier le depot de sauvegarde HORS du site. Le site heberge du chiffre et ne peut pas le juger : la verification suit la cle. # ───────────────────────────────────────────────────────────────────────────── - id: lire-le-plan titre: "Lire le plan et ce qu'il derive" portee: tenant doc: docs/plan-et-generation.md but: >- Tout ce qui se regarde sans rien changer : les registres du plan, leur validation, et l'inventaire qui en descend. Le premier geste devant un ecosysteme qu'on ne connait pas. etapes: - cible: serveurs nature: mesure pourquoi: "Les serveurs declares au plan." - cible: serveurs-verifier nature: mesure pourquoi: "Le registre des serveurs tient-il ses regles ?" - cible: applications nature: mesure pourquoi: "Les applications declarees au plan." - cible: applications-verifier nature: mesure pourquoi: "Le registre des applications tient-il ses regles ?" - cible: bases nature: mesure pourquoi: "Les bases de donnees declarees au plan." - cible: bases-verifier nature: mesure pourquoi: "Le registre des bases tient-il ses regles ?" - cible: domaines nature: mesure pourquoi: "Les domaines declares au plan." - cible: domaines-verifier nature: mesure pourquoi: "Le registre des domaines tient-il ses regles ?" - cible: inventaire-lister nature: mesure pourquoi: "L'inventaire complet, en JSON — la verite generee." - cible: inventaire-graphe nature: mesure pourquoi: "Le graphe des groupes : qui herite de quoi." - cible: inventaire-hote nature: mesure variables: [HOTE] pourquoi: "Les variables derivees d'une machine, telles qu'Ansible les verra." - cible: inventaire-lab nature: mesure pourquoi: "Le graphe de l'inventaire de laboratoire." - cible: inventaire-production nature: mesure pourquoi: "Le graphe de l'inventaire de production." - cible: config nature: mesure pourquoi: "La configuration Proxmox telle que le moteur la lit." # ───────────────────────────────────────────────────────────────────────────── - id: depot-verifier titre: "Verifier le depot avant de livrer" portee: toute doc: AGENTS.md but: >- Ce que le depot se doit a lui-meme : syntaxe, lint, tests, schema, fiches. Rien n'est « pret » sans au moins la syntaxe du playbook touche et l'entree de CHANGELOG. etapes: - cible: syntaxe nature: mesure pourquoi: "La syntaxe de TOUS les playbooks. Jamais declarer pret si elle echoue." - cible: lint nature: mesure pourquoi: "`ansible-lint` sur tout le depot." - cible: test nature: mesure pourquoi: "Les tests unitaires de derivation — nomenclature et inventaire." - cible: ci nature: mesure pourquoi: >- Verifier le depot comme la CI, sur un modele public monte a l'ecart : sans jamais toucher a l'ecosysteme monte. - cible: schema nature: ecriture pourquoi: >- Regenerer le schema du plan depuis les registres et les validateurs. C'est lui qui construit les formulaires : un champ nouveau apparait sans toucher a l'interface. - cible: fiches nature: ecriture variables: [ROLE] pourquoi: "Regenerer la fiche de chaque role, depuis le role lui-meme." - cible: plan-recette nature: ecriture pourquoi: "Regenerer le plan de recette depuis le wiki." - cible: wiki-publier nature: ecriture pourquoi: "Publier le wiki vers la forge, une fois qu'il dit vrai." # CE QUE LA CONSOLE N'OFFRE PAS, ET POURQUOI. Une exemption muette serait un oubli # deguise : chaque ligne porte son motif, et la garde refuse une exemption vide. hors_assistant: aide: >- Aide en ligne de commande. La console porte la meme information autrement — chaque etape affiche le libelle lu dans le Makefile. ansible-runtime: >- Prerequis interne, appele par les cibles qui deploient. L'offrir seul donnerait un bouton qui ne fait rien de visible. inventaire-ui: >- C'est cette console elle-meme. Un bouton qui la relance depuis elle-meme n'a pas d'objet. syntaxe-modele: "Couverte par `syntaxe`, qui passe tous les playbooks d'un coup." syntaxe-verification-modele: "Couverte par `syntaxe`." syntaxe-nettoyage: "Couverte par `syntaxe`." syntaxe-verification-hote: "Couverte par `syntaxe`." syntaxe-groupes: "Couverte par `syntaxe`." syntaxe-proxmox: "Couverte par `syntaxe`." model-creer: >- Fabrique un MODELE d'ecosysteme — un geste de mainteneur du moteur, pas d'exploitant. Il se fait au poste, en connaissance du catalogue des modeles. serveurs-bootstrap: >- Chemin de REPRISE : reconstitue le plan depuis un inventaire existant. Il ecrit par dessus le plan, et ne doit pas etre a un clic d'un exploitant qui explore. applications-bootstrap: >- Meme raison que `serveurs-bootstrap` : amorcage de reprise, pas geste courant. cacher-paquets: >- Se fait EN LIGNE depuis le poste, avant de partir sur un site hors ligne. Le runner, lui, est deja derriere la frontiere : le bouton serait au mauvais endroit. ca-racine: >- Recupere la racine de l'AC pour l'installer sur un poste. L'empreinte doit etre verifiee A LA MAIN avant installation — un bouton encouragerait a sauter ce controle. ca-empreinte: >- Le temoin de comparaison de `ca-racine`. Meme raison : il se lit, il ne se clique pas.