l edge du site est debout, et quatre replis silencieux l ont retarde

Les quatre defauts ont la MEME forme : un repli qui rend un succes au lieu d un
refus.

1. Le gabarit dore porte l adresse du cache d avant le renumerotage, et
   site_inventaire derivait dns_amorcage sans deriver son jumeau
   artefacts_amorcage. Le site fournissait cette valeur a ses locataires sans se
   la donner a lui-meme.

2. opnsense_if_zones ignorait la zone neuve, et _if_de retombe sur l ancienne
   patte PLATE : 20 regles posees sur vlan030, correctes et jamais rencontrees.
   Le fichier documentait deja le meme incident un mois plus tot.

3. serveur_nginx chargeait domaines.yml sans condition — un SITE ne publie rien
   a l Internet et n a pas ce registre. Il releve maintenant ce qui existe.

4. Sans registre de domaines, l edge d une exposition retombe sur le GROUPE DE
   L APPLICATION, jamais serveur_nginx : le vhost genere faisait 43 octets et le
   deploiement rendait vert. Une derivation qui ne trouve rien ne se distingue
   pas d une derivation qui n a rien a trouver.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
Daniel Allaire 2026-09-14 20:57:09 -04:00
parent 09a6a49089
commit 4f68182ac6
3 changed files with 133 additions and 3 deletions

View file

@ -1,5 +1,85 @@
# CHANGELOG — Set-OPS
## 2026-09-14 (22) — L'edge du site est debout, et quatre replis silencieux l'ont retarde
`site-edge-01` est nee, deployee, et sert `forge`, `observatoire` et `vigie` en 443. Le
chemin jusque-la a traverse quatre defauts qui ont tous la MEME forme : un repli qui rend
un succes au lieu d'un refus.
### 1. Le gabarit dore porte une adresse d'avant le renumerotage
Failed to update apt cache after 5 retries
Acquire::http::Proxy "http://10.0.33.21:3142"
Le fichier le dit lui-meme : *« Gere par Set-OPS pendant la FABRICATION DU GABARIT »*,
date du 2026-09-01, avec l'ancienne adresse du cache. Le socle ne le remplace que
`when artefacts_amorcage is defined` — et `site_inventaire.py` derivait `dns_amorcage`
sans deriver son JUMEAU. Les machines nees AVANT le renumerotage n'ont rien vu :
l'adresse etait juste, puis `client_artefacts` a pose un fichier qui trie apres.
**La premiere machine neuve du site l'a revele.** Le site fournissait deja cette valeur a
ses locataires (`site_intrants.py`) ; il ne se la donnait pas a lui-meme.
### 2. Une table de pattes tenue a la main, et un repli qui deplace au lieu d'omettre
Le devis rendait « rien a faire », et le cache restait injoignable. `opnsense_if_zones`
associe chaque zone du site a sa patte de frontiere ; `site-publication` n'y etait pas, et
`_if_de()` retombe alors sur l'ANCIENNE PATTE PLATE. Les 20 regles de l'edge etaient
posees sur `vlan030` — syntaxiquement correctes, jamais rencontrees, puisque le trafic de
l'edge entre par `vlan037`.
Le fichier documentait deja un incident identique, un mois plus tot, pour la patte de la
fabric : *« La regle etait syntaxiquement correcte et ne correspondait jamais. »* Ajoutee,
le devis a rendu **20 a creer, 20 a retirer** — le meme jeu de regles qui change de patte.
### 3. Un registre facultatif qui faisait echouer un role
`serveur_nginx` chargeait `applications.yml` ET `domaines.yml` sans condition. Un SITE ne
publie rien a l'Internet : son plan n'a pas le second.
Could not find or access '.../SITE-Chezlepro/plan/domaines.yml'
Le role releve desormais ce qui EXISTE avant de charger. Un registre absent laisse
`domaines_publics` indefini, et le filtre le traite deja comme vide.
### 4. Le vhost genere faisait 43 octets, et le deploiement etait vert
C'est le plus retors des quatre. `expositions_des_applications` resout, pour chaque nom
expose, l'edge de son domaine PARENT — et sans registre, retombe sur **le groupe de
l'application elle-meme** (`serveur_grafana`, `serveur_icingaweb2`). Jamais
`serveur_nginx`. Aucune exposition n'etait donc retenue, le fichier ne contenait que son
en-tete, et rien n'echouait.
*Une derivation qui ne trouve rien ne se distingue pas d'une derivation qui n'a rien a
trouver.* Le site declare donc `plan/domaines.yml` : `genese.internal`, autorite
`auto-heberge`, edge `serveur_nginx`, sans DNSSEC — le TLD `internal.` est nie par la
racine signee, signer sous une chaine rompue ajoute du travail sans ajouter de preuve.
Et `grafana` n'avait pas de `port:` : le vhost le disait dans son propre en-tete — *« une
application sans hote actif, ou sans port, est listee mais NON publiee »*.
### Etat
site-edge-01 10.37.37.11 deployee (174 taches, 66 changements)
nginx ecoute 80 et 443
vhosts forge -> 10.37.33.11:443
observatoire -> 10.37.36.11:3000
vigie -> 10.37.36.11:8080
frontiere 274 regles, devis muet
### Ce qui reste, et c'est precis
**Le certificat de l'edge ne porte encore que `site-edge-01.genese.internal`.** Il a ete
emis avant que les expositions existent, et `client_pki` rend `changed=0` : il ne compare
pas son jeu de SAN a celui qu'il derive maintenant. Tant que ce n'est pas fait, les trois
noms repondent sur un certificat qui ne les couvre pas.
`forge` relaie par ailleurs en `http://10.37.33.11:443` — du clair vers un port TLS, d'ou
son `400`. L'amont d'une exposition deja servie en TLS doit etre `https://`.
Deux corrections a faire, et aucune n'est une surprise : ce sont les deux dernieres
jointures entre le plan et ce que l'edge en tire.
## 2026-09-14 (21) — Le site gagne un edge, et P23 a nomme le geste qui manque
Le site servait trois applications web sans jamais les PUBLIER. L'observatoire, la vigie

View file

@ -55,14 +55,41 @@
notify: Valider et recharger nginx
# --- Vhosts derives des applications (champ expose) + domaines (edge) ---
- name: Charger les registres applications et domaines
ansible.builtin.include_vars:
file: "{{ item }}"
# LE REGISTRE DES DOMAINES PUBLICS EST FACULTATIF, ET IL A FALLU UN SITE POUR LE VOIR.
#
# `applications.yml` existe dans tout plan ; `domaines.yml` ne recense que les noms
# PUBLICS — ceux qu'un tenant publie a l'Internet. Un SITE n'en publie aucun : ses trois
# services web sont internes, et son plan n'a pas ce fichier.
#
# `include_vars` echouait alors sur le fichier absent, et l'edge du site ne se deployait
# pas :
#
# Could not find or access '.../SITE-Chezlepro/plan/domaines.yml'
#
# On releve donc d'abord ce qui EXISTE, puis on charge. Un registre absent laisse
# `domaines_publics` indefini, et `expositions_des_applications` le traite deja comme
# vide — la suite du role n'a pas besoin d'etre touchee.
- name: Quels registres du plan existent vraiment ?
ansible.builtin.stat:
path: "{{ item }}"
loop:
- "{{ setops_plan_dir }}/applications.yml"
- "{{ setops_plan_dir }}/domaines.yml"
delegate_to: localhost
become: false
register: serveur_nginx_registres
when: serveur_nginx_publier_expositions | bool
- name: Charger les registres applications et domaines
ansible.builtin.include_vars:
file: "{{ item.item }}"
loop: "{{ serveur_nginx_registres.results | default([]) }}"
loop_control:
label: "{{ item.item | basename }}"
when:
- serveur_nginx_publier_expositions | bool
- item.stat.exists | default(false)
- name: Lister les expositions destinees a cet edge
ansible.builtin.set_fact:
serveur_nginx_expositions: >-

View file

@ -304,6 +304,29 @@ def inventaire() -> dict:
communes["dns_amorcage"] = _resolveur
if _cache_site:
communes["setops_depot_binaires"] = f"http://{_cache_site}:3142/setops-binaires"
# L'AMORCAGE APT DES MACHINES DU SITE LUI-MEME (2026-09-14).
#
# `dns_amorcage` etait derive juste au-dessus ; son jumeau ne l'etait pas. Le
# socle n'ecrit `00-setops-amorcage-artefacts` que `when artefacts_amorcage is
# defined` — jamais, donc, pour une machine du site. Le fichier du GABARIT
# survivait alors intact.
#
# CE QUE CA A COUTE, mesure le 2026-09-14 sur `site-edge-01`, premiere machine
# du site creee depuis le renumerotage :
#
# Failed to update apt cache after 5 retries
# Acquire::http::Proxy "http://10.0.33.21:3142" <- adresse d'AVANT
#
# Le gabarit porte cette ligne depuis sa fabrication, le 2026-09-01. Les machines
# nees AVANT le renumerotage n'ont rien vu : l'adresse etait juste, puis
# `client_artefacts` a pose un fichier qui trie APRES et l'a emporte. Une machine
# NEUVE, elle, doit faire son premier `apt update` avec le seul fichier du
# gabarit — et il ment.
#
# LE SITE FOURNIT DEJA CETTE VALEUR A SES LOCATAIRES (`site_intrants.py`). Il ne
# se la donnait pas a lui-meme. C'est encore « le site revele ce que le tenant
# cache », a l'envers : ce que l'hebergeur pretait sans l'appliquer chez lui.
communes["artefacts_amorcage"] = f"{_cache_site}:3142"
for cle in ("domaine_interne", "organisation", "dns_amorcage"):
if intrants.get(cle):
communes[cle] = str(intrants[cle])