Le flux etait declare et applique ; il manquait l'IDENTITE. Le runner du SITE
atteignait la porte de ops-01 sans avoir de cle.
LE PIEGE COMPTE PLUS QUE LE CORRECTIF. La cle s'injecte au CLONAGE, et `creer-vm`
cree TOUTES les machines d'un tenant. L'injecter a chaque clonage aurait donne a
l'hebergeur un acces SSH a la flotte entiere de chaque locataire, en silence — ca
aurait defait a la couche IDENTITE ce que le pare-feu venait de borner a la couche
RESEAU. Le meme critere gouverne donc les deux : porter `serveur_ops_tenant`.
`SETOPS_CLES_AMORCAGE` est vide partout ailleurs. Elle S'AJOUTE a celle de
l'exploitant, elle ne la remplace pas : c'est l'humain qui arme.
La cle vient du PLAN DU SITE, pas du disque local : materialiser depuis le poste
et depuis le runner doit produire la meme VM.
DEUX COUCHES MANGEAIENT LES ESPACES. Proxmox rendait `SSH public key validation
error` — message muet sur la cause. Isole par un CONTROLE (rejouer sans la cle :
la tache passe), puis par la mesure de ce qui arrivait au module :
"sshkeys": "ssh-ed25519" <- le premier mot, rien d'autre
J'ai accuse `make` d'abord ; c'etait `ansible-playbook -e cle=valeur`, qui decoupe
AU SHLEX. D'ou l'environnement pour le transport et `-e '{...}'` en JSON pour
l'entree. (Un scalaire YAML plie ne produit pas non plus de saut de ligne.)
TROIS TESTS QUI NE GARDAIENT RIEN. `test_inventory_host` inscrit ses tests dans une
liste explicite ; mes deux nouveaux n'y etaient pas — definis, jamais joues. La
garde d'exhaustivite ajoutee en a trouve un TROISIEME le jour meme,
`test_etiquette_vlan_repli_et_vide_explicite`, jamais inscrit depuis sa creation :
inscrit, il levait un KeyError sur une fixture qu'il lisait mal. Un test non
inscrit est pire qu'un test absent : on croit l'avoir.
PREUVE, AVEC SON CONTROLE NEGATIF :
runner du SITE -> ops-01 ops-01 10.17.19.41/24 entre
runner du SITE -> 10.17.19.21 Connection timed out refuse
make verifier : vert. make prouver : CONFORME, 52 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
Le test unitaire a rejete mon ajout d'export — c'est exactement son role : il
epingle le contrat de parametres-proxmox, et une variable de plus est un
changement de contrat qui doit etre declare, pas subi.
J'ai pousse le commit precedent AVEC cette preuve en echec. Cause : mon
garde-fou etait « grep -E 'CONFORME|ECART' », qui correspond aussi a « NON
CONFORME ». Un motif qui ne sait pas distinguer le succes de l'echec ne garde
rien — meme famille que les criteres creux de P31.
Harnais de nouveau a 33 preuves, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Une VM ne peut pas s'installer sans resoudre des noms. PowerDNS repond
UNIQUEMENT pour la zone souveraine et ne recurse pour personne : il manquait un
resolveur recursif. `client_unbound` est l'outil ecrit pour ca — il rejoint
`client_journal` et `client_metrique` parmi les integrations universelles.
`infra-dns-01` est exempte (PowerDNS occupe son port 53), et
`serveur_powerdns_listen_addresses` passe de 0.0.0.0 a l'adresse de l'hote pour
laisser 127.0.0.1:53 libre. Mais l'appartenance au groupe est AUSSI ce qui ouvre
le port 53 a la frontiere : en exemptant la machine, je lui retirais le droit de
resoudre. `serveur_powerdns` declare donc son propre flux sortant — il ne
recurse pour personne, mais doit resoudre pour lui-meme.
Nouvel intrant `dns_amorcage`, derive jusqu'a `make creer-vm`. Cloud-init
l'ecrit bien mais sans effet : `dns-nameservers` exige `resolvconf`, absent du
gabarit, et installer resolvconf demande apt, qui demande la resolution.
`serveur_debian` pose donc le resolveur en pre_tasks, avant le premier apt, avec
une garde qui respecte la bascule ulterieure de client_unbound.
Defaut corrige en chemin : `_intrants_communs()` lisait `instance/` en dur ; le
chemin derive maintenant de l'inventaire recu, et un test le prouve.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le pont n'était pas seulement non portable, il était faux. proxmox_clone_pont
faisait naître les VM sur vmbr1 avec une étiquette VLAN — l'ancien monde. En SDN
une VM appartient à son VNet ; c'est ce qu'il a fallu corriger à la main sur
infra-pki-01, et les treize suivantes auraient suivi.
deriver_nomenclature() expose désormais la zone de sécurité, instancier en dérive
proxmox_pont et une étiquette VIDE — le VNet porte déjà le tag, en poser un
second donnerait un double étiquetage. La chaîne va jusqu'à make creer-vm :
SETOPS_PONT='t11appl', SETOPS_VLAN=''.
Trois pièges. Un doublon dans le Makefile passait PONT_PROXMOX deux fois dans la
même cible, la seconde vide aurait écrasé la valeur dérivée. Un repli naïf sur
proxmox_vlan aurait fait revenir l'étiquette en SDN : le repli ne s'applique que
si la clé est ABSENTE, jamais si elle est présente et vide. Et le test unitaire
est tombé, à raison — il couvre maintenant cette distinction.
D-55 : le dépôt réseau porte le contrat entre l'Alliance et ses hébergeurs, et
abstrait le matériel en encapsulant chaque tenant dans sa zone EVPN. Mesuré : un
tenant est à deux valeurs de la portabilité complète (noeud, stockage).
D-57 : l'interface sysadmin d'un hyperviseur (vmbr0, 10.0.0.41/.43/.47) n'a pas
de route par défaut ; celle-ci vit sur vlan40, vers la frontière. On n'atteint
l'administration que depuis son propre domaine de diffusion. Ça tranche la
question de la sortie des nœuds laissée ouverte ce matin — option A, mais sur une
interface dédiée, ce qui lève l'objection qui la bloquait.
D-58 : un hôte déclare par quelle interface (`via`) chaque réseau lui arrive ; le
devis en dérive un port par interface et son type — trunk 11,40 sur bond3, accès
VLAN 10 sur vmbr0. Sans ça, ajouter le VLAN 10 le remettait sur le trunk du
transport, soit le domaine qu'on venait d'en sortir.
D-59 : un VLAN qui ne porte que des adresses d'hôte n'a pas besoin de pont.
Régression créée puis corrigée : le modèle public, qui ne déclare aucun
hyperviseur, n'émettait plus rien pour ce port. Il émet maintenant tout
l'underlay en disant que c'est un repli.
30 preuves OK, 4 tests unitaires.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Les cœurs/RAM/disque d'une VM sont estimés depuis l'empreinte des rôles
hébergés (roles/<rôle>/meta/empreinte.yml) sommée au socle SE, au lieu
d'hériter des specs du golden template. Le générateur écrit
proxmox_coeurs/memoire/disque_taille ; le clonage les passe à Proxmox
(omit si absent → aucune régression). Override par hôte dans le plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>