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 # 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 ## 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 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 notify: Valider et recharger nginx
# --- Vhosts derives des applications (champ expose) + domaines (edge) --- # --- Vhosts derives des applications (champ expose) + domaines (edge) ---
- name: Charger les registres applications et domaines # LE REGISTRE DES DOMAINES PUBLICS EST FACULTATIF, ET IL A FALLU UN SITE POUR LE VOIR.
ansible.builtin.include_vars: #
file: "{{ item }}" # `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: loop:
- "{{ setops_plan_dir }}/applications.yml" - "{{ setops_plan_dir }}/applications.yml"
- "{{ setops_plan_dir }}/domaines.yml" - "{{ setops_plan_dir }}/domaines.yml"
delegate_to: localhost
become: false
register: serveur_nginx_registres
when: serveur_nginx_publier_expositions | bool 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 - name: Lister les expositions destinees a cet edge
ansible.builtin.set_fact: ansible.builtin.set_fact:
serveur_nginx_expositions: >- serveur_nginx_expositions: >-

View file

@ -304,6 +304,29 @@ def inventaire() -> dict:
communes["dns_amorcage"] = _resolveur communes["dns_amorcage"] = _resolveur
if _cache_site: if _cache_site:
communes["setops_depot_binaires"] = f"http://{_cache_site}:3142/setops-binaires" 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"): for cle in ("domaine_interne", "organisation", "dns_amorcage"):
if intrants.get(cle): if intrants.get(cle):
communes[cle] = str(intrants[cle]) communes[cle] = str(intrants[cle])