Some checks are pending
verifier / verifier (push) Waiting to run
REFABRIQUE (VMID 9006, modeleSetOPS-minimal). Quatre roles au lieu de dix-sept :
qemu_guest_agent, cloud_init, sudo_ansible, ssh_baseline — des conditions
d existence, pas des choix d efficacite. Tout le reste vient du socle, et P56 refuse
qu un role retire ne soit repris par personne.
FABRIQUE CHEZ LE SITE, ET C EST LA DECISION QUI COMPTE. « Les ressources du SITE
font autorite pour tous ses artefacts ; elles servent les tenants jusqu a ce qu ils
s emancipent. »
Il se fabriquait DEHORS : `-i "<ip>,"` ne porte aucun group_vars, donc ni mandataire
ni resolveur. L ancien gabarit allait chercher ses paquets chez Debian et resolvait
chez l ancien LAN — 192.168.10.10, lu sur la VM 99998. Le site avait son cache et
son resolveur, et son propre artefact les ignorait.
Desormais la fabrication DERIVE ses ressources du plan du site (underlay --adresses)
et tourne sur le reseau du genome. PROUVE : dix requetes de 10.0.33.31 servies par
site-cache-01, resolveur pose a 10.0.34.11.
L IDENTITE DU GABARIT VIENT DU SITE, PLUS DU TENANT. `proxmox_clone_vmid_modele`
vivait dans les group_vars de l ecosysteme : deux tenants pouvaient cloner deux
gabarits differents sans que rien ne le dise, et un tenant decidait d un objet dont
descend chaque VM de chaque ecosysteme. Meme mouvement que l INDEX (2026-08-25) : le
site ALLOUE, le tenant RECOIT. Cle `gabarit` du plan du site, lue par
underlay --gabarit.
PIEGE FERME EN CHEMIN : creer-vm passait VMID_MODELE="$SETOPS_VMID_MODELE" a
cloner-vm, or inventory_host.py n emet PAS cette variable. Elle valait donc le VIDE,
et ce vide ECRASAIT la valeur derivee — le gabarit du tenant reprenait la main sans
bruit.
ET UN PIEGE DEJA DOCUMENTE, PAYE UNE TROISIEME FOIS : le chemin du controleur
contient une espace, et `lookup('pipe', ...)` le decoupait. Guillemets.
EPROUVE DE BOUT EN BOUT : VM clonee du gabarit minimal — nom, adresse, machine-id
neuf, cle d hote regeneree, agent invite actif ; puis socle applique dessus,
changed=5, 0 echec, auditd compris. VM d essai retiree.
make verifier : vert. make prouver : CONFORME, 56 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
128 lines
6.7 KiB
YAML
128 lines
6.7 KiB
YAML
---
|
|
- name: Préparer le template Debian 13 Proxmox
|
|
# Le gabarit n'est pas un hote du tenant : son adresse vit sur le reseau de
|
|
# fabrication, donc il ne peut pas venir du plan et le groupe `modeles_vm` reste vide.
|
|
# `MODELE_HOTE` passe alors `cible_modele`, et l'inventaire d'un seul hote (`-i "<ip>,"`)
|
|
# place la machine dans `all` — PAS dans `modeles_vm`. Sans cette indirection, la
|
|
# commande etait juste et la cible introuvable : « skipping: no hosts matched ».
|
|
hosts: "{{ cible_modele | default('modeles_vm') }}"
|
|
become: true
|
|
gather_facts: true
|
|
|
|
pre_tasks:
|
|
# ─── LE GABARIT EST UN ARTEFACT DU SITE, ET IL SE FABRIQUE CHEZ LUI ──────────
|
|
#
|
|
# « Les ressources du SITE font autorité pour tous les artefacts du site » (décision
|
|
# de l'exploitant, 2026-09-01). Le gabarit en est un — c'est de lui que descend
|
|
# chaque VM de chaque tenant.
|
|
#
|
|
# Il se fabriquait pourtant DEHORS : `-i "<ip>,"` ne porte aucun `group_vars`, donc
|
|
# ni mandataire ni résolveur. La machine allait chercher ses paquets chez Debian et
|
|
# résolvait chez l'ancien LAN (`192.168.10.10`, lu sur le gabarit du 2026-08-09).
|
|
# Le site avait son cache et son résolveur, et son propre artefact les ignorait.
|
|
#
|
|
# DÉRIVÉ, JAMAIS ÉCRIT : les adresses viennent du plan du site, par le groupe que la
|
|
# machine porte. Le jour où le cache déménage, la fabrication suit — c'est déjà
|
|
# arrivé une fois, au découpage du site en zones.
|
|
- name: Où le SITE sert-il ses paquets et ses noms ?
|
|
ansible.builtin.set_fact:
|
|
# LE CHEMIN DU CONTROLEUR PEUT CONTENIR UNE ESPACE — « Espace Chezlepro/… »
|
|
# chez le mainteneur — et `pipe` passe sa chaine au shell. Sans guillemets, il
|
|
# decoupe le chemin et rend 2. Meme piege que `ansible-galaxy` le 2026-08-23 et
|
|
# que `git bundle` le 2026-08-26 : ce depot l'a paye trois fois.
|
|
modele_cache_site: >-
|
|
{{ (lookup('pipe', 'python3 "' ~ playbook_dir ~ '/../../scripts/underlay.py" --adresses serveur_artefacts')
|
|
| trim | split('\n') | first | default('', true)) }}
|
|
modele_resolveur_site: >-
|
|
{{ (lookup('pipe', 'python3 "' ~ playbook_dir ~ '/../../scripts/underlay.py" --adresses serveur_resolveur')
|
|
| trim | split('\n') | first | default('', true)) }}
|
|
delegate_to: localhost
|
|
become: false
|
|
# PAS de `run_once` : la fabrication ne vise qu'une machine de toute facon, et
|
|
# `run_once` se comporte autrement sous la strategie `free` — une garde qui depend
|
|
# de la strategie n'en est pas une.
|
|
|
|
- name: Exiger que le site offre ce qu'il faut pour fabriquer son gabarit
|
|
ansible.builtin.assert:
|
|
that:
|
|
- modele_cache_site | length > 0
|
|
- modele_resolveur_site | length > 0
|
|
fail_msg: >-
|
|
Le plan du SITE ne déclare pas de `serveur_artefacts` et/ou de
|
|
`serveur_resolveur`. Le gabarit est un artefact du site : le fabriquer sans eux
|
|
le ferait dépendre d'Internet et de l'ancien LAN, alors que tout ce dont il a
|
|
besoin doit venir du site.
|
|
|
|
# UNE ADRESSE, PAS UN NOM : au moment où ces deux fichiers servent, la machine ne
|
|
# résout encore rien — c'est justement ce qu'on est en train de lui donner.
|
|
- name: Poser le résolveur du SITE
|
|
ansible.builtin.copy:
|
|
dest: /etc/resolv.conf
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
content: |
|
|
# Géré par Set-OPS pendant la FABRICATION du gabarit — le résolveur du SITE.
|
|
# `template_cleanup` le remet à zéro : un gabarit ne transporte pas d'adresse.
|
|
nameserver {{ modele_resolveur_site }}
|
|
|
|
- name: Poser le cache d'artefacts du SITE
|
|
ansible.builtin.copy:
|
|
dest: /etc/apt/apt.conf.d/00-setops-amorcage-artefacts
|
|
owner: root
|
|
group: root
|
|
mode: "0644"
|
|
content: |
|
|
// Géré par Set-OPS pendant la FABRICATION du gabarit — le cache du SITE.
|
|
// Les VM clonées le remplacent par celui de leur écosystème (client_artefacts).
|
|
Acquire::http::Proxy "http://{{ modele_cache_site }}:3142";
|
|
// `DIRECT` obligatoire : apt fait HÉRITER la valeur HTTPS de la valeur HTTP.
|
|
Acquire::https::Proxy "DIRECT";
|
|
|
|
- name: Vérifier que la cible est Debian
|
|
ansible.builtin.assert:
|
|
that:
|
|
- ansible_facts.distribution == "Debian"
|
|
fail_msg: "Ce playbook est prévu pour Debian."
|
|
|
|
- name: Avertir si la version Debian n'est pas 13
|
|
ansible.builtin.debug:
|
|
msg: "Attention : Debian {{ ansible_facts.distribution_version }} détecté. Le modèle cible est Debian 13."
|
|
when: ansible_facts.distribution_major_version != "13"
|
|
|
|
# ─── LE GABARIT EST MINIMAL, ET C'EST UNE DECISION (2026-09-01) ──────────────
|
|
#
|
|
# Il portait DIX-SEPT roles : exactement ceux du socle et du durcissement, que le
|
|
# deploiement rejoue ensuite a l'identique. Le gabarit etait donc un CACHE du socle —
|
|
# et comme tout cache, il perimait sans le dire.
|
|
#
|
|
# Mesure du 2026-09-01 : derniere recapture le 2026-08-09, et SIX de ses roles avaient
|
|
# change depuis (common_packages, cloud_init, ssh_baseline, ssh_hardening, auditd,
|
|
# nftables_baseline). Rien ne le signalait — le deploiement masquait la derive en
|
|
# reappliquant tout, donc personne ne pouvait la voir.
|
|
#
|
|
# CE QUI RESTE ICI N'EST PAS UN CHOIX D'EFFICACITE, C'EST UNE CONDITION D'EXISTENCE :
|
|
# chacun doit etre en place AVANT qu'Ansible puisse agir. Tout le reste appartient au
|
|
# socle, qui l'applique de toute facon — et P56 refuse qu'un role retire ne soit repris
|
|
# par personne.
|
|
#
|
|
# `qemu_guest_agent` l'agent invite repond AVANT SSH. C'est par lui que `creer-vm`
|
|
# confirme la materialisation sans entrer chez le tenant (P52).
|
|
# `cloud_init` le seul chemin vers la premiere seconde — adresse, nom d'hote,
|
|
# cles de naissance. Sans lui, personne ne peut joindre la VM.
|
|
# `sudo_ansible` le compte technique et son sudo : la porte par ou tout entre.
|
|
# `ssh_baseline` le serveur SSH. Meme raison, un cran plus bas.
|
|
#
|
|
# CE QUE LA REDUCTION COUTE, ET QUI EST COUVERT : une VM neuve n'est plus durcie a la
|
|
# naissance. Elle nait cependant DERRIERE LE PARE-FEU DE L'HYPERVISEUR,
|
|
# `policy_in=REJECT` arme au clonage (verifie le 2026-09-01 sur `obs-01`) : seuls les
|
|
# flux declares l'atteignent, avant meme son premier paquet. La fenetre d'exposition est
|
|
# fermee par la fabric, pas par le gabarit.
|
|
#
|
|
# CE QU'ELLE RAPPORTE : un gabarit qui ne contient presque rien ne peut presque pas
|
|
# perimer.
|
|
roles:
|
|
- qemu_guest_agent
|
|
- cloud_init
|
|
- sudo_ansible
|
|
- ssh_baseline
|