2026-06-24 20:17:46 -04:00
|
|
|
---
|
2026-08-07 15:33:32 -04:00
|
|
|
|
observabilite : le site cesse de ne rien voir de lui-meme
D-87 disait que l hebergeur n a pas le droit de voir les journaux de ses
locataires. La decision avait une face cachee : a force de refuser de voir
ceux des autres, le site s etait prive des siens. Ses sept machines
n expediaient nulle part.
Il prend donc sa propre pile : prometheus, loki et grafana sur site-mon-01,
sans aucun lien avec ceux d un tenant. L exemption qui bloquait portait sa
propre condition de levee, ecrite cinq jours plus tot dans le plan.
Grafana au site n a pas de SSO, et le role l ignorait : il reclamait l IdP
avant de regarder s il en voulait un. L interrupteur existait, il n etait
pas honore. Le role refuse desormais SSO eteint ET formulaire local eteint
- la combinaison deploie un Grafana en sante ou personne ne peut entrer -
et le reglage du formulaire sort du if du SSO, ou il disparaissait en
laissant le defaut amont decider en silence.
Deux manques se cachaient l un l autre dans le devis de la frontiere, et
Prometheus voyait 1 cible sur 7 :
- le devis derivait les groupes d une machine du site de applications.yml
seul, et ne voyait donc aucune integration universelle - alors que
client_metrique ouvre un port d ecoute ;
- une sortie vers un role du site visait !SETOPS_INTERNES, qui exclut
precisement la machine nommee. Le devis autorisait a expedier les
journaux du site a n importe quel Loki du monde, et a nul autre endroit
qu a celui-la. Neuf flux dans ce cas.
Et deux declarations justes ne font qu une regle : appliquer_opnsense pose
tout en direction: in (D-61).
Les deux agents se supervisent enfin eux-memes. La sonde des journaux ne
demande pas si Alloy tourne, elle lit ce qu il a du JETER. Elle a fait ses
preuves le jour meme : Alloy actif, /-/ready a 200, et cinquante lignes
perdues sur six machines.
Mesure : metriques 7/7 vert, journaux 1/7 - les six autres attendent la
regle de frontiere, et le disent. prouver 64 OK, ansible-lint 0 defaut.
Reste a la main de l exploitant : make frontiere-appliquer CONFIRMER=true,
et le secret vault_grafana_admin a deposer dans underlay.vault.yml.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 04:43:01 -04:00
|
|
|
# UNE PORTE AU MOINS. Sans SSO et sans formulaire local, Grafana demarre, se porte
|
|
|
|
|
# bien, et personne n'entre. Les deux reglages sont independants et se sont deja
|
|
|
|
|
# retrouves a `false` ensemble : la combinaison se refuse ici, pas apres le
|
|
|
|
|
# deploiement, quand plus aucun chemin ne mene a la console.
|
|
|
|
|
- name: Exiger au moins un chemin de connexion
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- (serveur_grafana_oidc_actif | bool) or (serveur_grafana_connexion_locale | bool)
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
Ni SSO (`serveur_grafana_oidc_actif`) ni formulaire local
|
|
|
|
|
(`serveur_grafana_connexion_locale`) : Grafana n'aurait aucune porte d'entree.
|
|
|
|
|
|
2026-08-07 15:33:32 -04:00
|
|
|
# L'URL PUBLIQUE de l'IdP se derive de l'exposition declaree au plan, elle ne se
|
|
|
|
|
# fabrique pas : `keycloak.<domaine>` n'est publie nulle part (voir resoudre_idp).
|
observabilite : le site cesse de ne rien voir de lui-meme
D-87 disait que l hebergeur n a pas le droit de voir les journaux de ses
locataires. La decision avait une face cachee : a force de refuser de voir
ceux des autres, le site s etait prive des siens. Ses sept machines
n expediaient nulle part.
Il prend donc sa propre pile : prometheus, loki et grafana sur site-mon-01,
sans aucun lien avec ceux d un tenant. L exemption qui bloquait portait sa
propre condition de levee, ecrite cinq jours plus tot dans le plan.
Grafana au site n a pas de SSO, et le role l ignorait : il reclamait l IdP
avant de regarder s il en voulait un. L interrupteur existait, il n etait
pas honore. Le role refuse desormais SSO eteint ET formulaire local eteint
- la combinaison deploie un Grafana en sante ou personne ne peut entrer -
et le reglage du formulaire sort du if du SSO, ou il disparaissait en
laissant le defaut amont decider en silence.
Deux manques se cachaient l un l autre dans le devis de la frontiere, et
Prometheus voyait 1 cible sur 7 :
- le devis derivait les groupes d une machine du site de applications.yml
seul, et ne voyait donc aucune integration universelle - alors que
client_metrique ouvre un port d ecoute ;
- une sortie vers un role du site visait !SETOPS_INTERNES, qui exclut
precisement la machine nommee. Le devis autorisait a expedier les
journaux du site a n importe quel Loki du monde, et a nul autre endroit
qu a celui-la. Neuf flux dans ce cas.
Et deux declarations justes ne font qu une regle : appliquer_opnsense pose
tout en direction: in (D-61).
Les deux agents se supervisent enfin eux-memes. La sonde des journaux ne
demande pas si Alloy tourne, elle lit ce qu il a du JETER. Elle a fait ses
preuves le jour meme : Alloy actif, /-/ready a 200, et cinquante lignes
perdues sur six machines.
Mesure : metriques 7/7 vert, journaux 1/7 - les six autres attendent la
regle de frontiere, et le disent. prouver 64 OK, ansible-lint 0 defaut.
Reste a la main de l exploitant : make frontiere-appliquer CONFIRMER=true,
et le secret vault_grafana_admin a deposer dans underlay.vault.yml.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 04:43:01 -04:00
|
|
|
#
|
|
|
|
|
# ON NE RESOUT QUE CE QU'ON UTILISE. Le role reclamait l'IdP AVANT de regarder s'il
|
|
|
|
|
# en voulait un : au site, qui n'a ni Keycloak ni `domaines.yml` (D-87 : l'identite
|
|
|
|
|
# ne monte pas), le deploiement echouait sur un registre absent — pour derive une URL
|
|
|
|
|
# qu'aucun gabarit n'allait ecrire. L'interrupteur existait, il n'etait pas honore.
|
2026-08-07 15:33:32 -04:00
|
|
|
- name: Resoudre le fournisseur d'identite (role partage)
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: resoudre_idp
|
|
|
|
|
vars:
|
|
|
|
|
resoudre_idp_realm: "{{ serveur_grafana_oidc_realm }}"
|
observabilite : le site cesse de ne rien voir de lui-meme
D-87 disait que l hebergeur n a pas le droit de voir les journaux de ses
locataires. La decision avait une face cachee : a force de refuser de voir
ceux des autres, le site s etait prive des siens. Ses sept machines
n expediaient nulle part.
Il prend donc sa propre pile : prometheus, loki et grafana sur site-mon-01,
sans aucun lien avec ceux d un tenant. L exemption qui bloquait portait sa
propre condition de levee, ecrite cinq jours plus tot dans le plan.
Grafana au site n a pas de SSO, et le role l ignorait : il reclamait l IdP
avant de regarder s il en voulait un. L interrupteur existait, il n etait
pas honore. Le role refuse desormais SSO eteint ET formulaire local eteint
- la combinaison deploie un Grafana en sante ou personne ne peut entrer -
et le reglage du formulaire sort du if du SSO, ou il disparaissait en
laissant le defaut amont decider en silence.
Deux manques se cachaient l un l autre dans le devis de la frontiere, et
Prometheus voyait 1 cible sur 7 :
- le devis derivait les groupes d une machine du site de applications.yml
seul, et ne voyait donc aucune integration universelle - alors que
client_metrique ouvre un port d ecoute ;
- une sortie vers un role du site visait !SETOPS_INTERNES, qui exclut
precisement la machine nommee. Le devis autorisait a expedier les
journaux du site a n importe quel Loki du monde, et a nul autre endroit
qu a celui-la. Neuf flux dans ce cas.
Et deux declarations justes ne font qu une regle : appliquer_opnsense pose
tout en direction: in (D-61).
Les deux agents se supervisent enfin eux-memes. La sonde des journaux ne
demande pas si Alloy tourne, elle lit ce qu il a du JETER. Elle a fait ses
preuves le jour meme : Alloy actif, /-/ready a 200, et cinquante lignes
perdues sur six machines.
Mesure : metriques 7/7 vert, journaux 1/7 - les six autres attendent la
regle de frontiere, et le disent. prouver 64 OK, ansible-lint 0 defaut.
Reste a la main de l exploitant : make frontiere-appliquer CONFIRMER=true,
et le secret vault_grafana_admin a deposer dans underlay.vault.yml.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 04:43:01 -04:00
|
|
|
when: serveur_grafana_oidc_actif | bool
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Exiger le mot de passe admin Grafana (Vault)
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- serveur_grafana_admin_password | length > 0
|
|
|
|
|
fail_msg: "serveur_grafana_admin_password est requis (Ansible Vault)."
|
|
|
|
|
|
|
|
|
|
- name: Assurer le repertoire des trousseaux apt
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /etc/apt/keyrings
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
2026-08-09 14:05:25 -04:00
|
|
|
# Recuperee UNE FOIS. Sans garde, chaque deploiement recontactait le serveur du
|
|
|
|
|
# fournisseur : cinq cles x quatorze hotes = soixante-dix allers-retours externes pour
|
|
|
|
|
# des cles deja installees, et autant d'occasions qu'un tiers lent fasse tomber le
|
|
|
|
|
# deploiement. Arbitrage rendu le 2026-08-09 : une plateforme souveraine ne depend pas
|
|
|
|
|
# de six serveurs etrangers pour redeployer ce qu'elle possede deja.
|
|
|
|
|
#
|
|
|
|
|
# CONSEQUENCE ASSUMEE : une rotation de cle amont n'est plus recuperee toute seule. Elle
|
|
|
|
|
# ne passe pas inapercue pour autant — `apt` refuse alors le depot, bruyamment. Pour
|
|
|
|
|
# forcer le rafraichissement : supprimer le fichier et rejouer le role.
|
un fichier vide existe, et une sonde pour les correctifs
LA GARDE FICHIER ENTIER, en deux corrections. Un telechargement
interrompu laisse un fichier de zero octet QUI EXISTE, et toutes les gardes
demandaient seulement s il etait la. infra-mail-01 a garde une cle
smallstep de 0 octet apres l epreuve hors ligne.
La premiere correction n a pas suffi. Ajouter le controle de taille faisait
bien s executer la tache - et le fichier faisait toujours 0 octet au
passage suivant. get_url sur une destination existante emet une requete
CONDITIONNELLE : l amont repond non modifie, le module rend ok, la ruine
reste. Le play etait vert et ne reparait rien. Il faut effacer avant de
redemander.
Controle negatif : 0 -> 1022 octets, 0 erreur apt. Cinq roles.
LA SONDE CORRECTIFS, 23e. Set-OPS desarme unattended-upgrades et applique
les correctifs au deploiement - choix defendable, le verrou dpkg a fait
decrocher une machine d une reconstruction entiere le matin meme. Mais rien
ne disait QUAND le geste etait du : une flotte pouvait deriver des mois en
restant verte.
Elle mesure les paquets de securite en attente ET depuis quand. Elle ne
lance pas apt-get update - une sonde qui rafraichit l index toutes les
quinze minutes deviendrait la cause de la panne qu elle surveille. Et le
seuil de 72 h est un choix d exploitation, pas une derivation : le
mecanisme qui applique les correctifs est un geste humain.
P64 REFUSAIT UNE DECLARATION CORRECTE. serveur_debian et serveur_durci sont
des roles de declaration pure, sans une tache ; le travail est fait par les
roles que leur playbook applique. La preuve exigeait declaration et depot
dans le meme role - vrai des vingt-deux premieres sondes, faux des qu une
sonde appartient au socle. Une garde qui force a contourner ce qu elle
protege est un defaut. Elle suit desormais le playbook du groupe.
Mesure : 21/21 machines vertes, 65 preuves, 23 sondes, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 17:26:35 -04:00
|
|
|
# UN FICHIER VIDE EXISTE (mesure du 2026-09-10).
|
|
|
|
|
#
|
|
|
|
|
# Cette garde demandait « ce fichier est-il la ? ». Un telechargement interrompu — un 503,
|
|
|
|
|
# un delai depasse, une coupure — laisse un fichier de ZERO octet, qui existe. La tache
|
|
|
|
|
# est donc sautee a tous les passages suivants, et la machine garde une ressource morte
|
|
|
|
|
# pour toujours, en silence.
|
|
|
|
|
#
|
|
|
|
|
# CE QUE CA A COUTE : `infra-mail-01` a garde une cle smallstep de 0 octet apres une
|
|
|
|
|
# epreuve hors ligne. Treize machines portaient 1022 octets, elle portait le vide :
|
|
|
|
|
#
|
|
|
|
|
# E: Le depot http://packages.smallstep.com/... n'est pas signe.
|
|
|
|
|
#
|
|
|
|
|
# Le meme jour, l'index `dists/trixie` du cache du site etait tombe de 140 416 a 4 332
|
|
|
|
|
# octets — meme famille, autre endroit. Un telechargement partiel ne se signale pas : il
|
|
|
|
|
# se fait passer pour un succes.
|
|
|
|
|
#
|
|
|
|
|
# On demande donc « est-il ENTIER ? » — a defaut de pouvoir demander « est-il JUSTE ? »,
|
|
|
|
|
# ce qui exigerait une empreinte de reference que l'amont ne publie pas toujours.
|
2026-08-09 14:05:25 -04:00
|
|
|
- name: Cette ressource est-elle deja recuperee ? (Telecharger la cle de signature Gr)
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ serveur_grafana_depot_cle_fichier }}"
|
|
|
|
|
register: telecharger_la_cle_de_signature_grafana_present
|
|
|
|
|
|
un fichier vide existe, et une sonde pour les correctifs
LA GARDE FICHIER ENTIER, en deux corrections. Un telechargement
interrompu laisse un fichier de zero octet QUI EXISTE, et toutes les gardes
demandaient seulement s il etait la. infra-mail-01 a garde une cle
smallstep de 0 octet apres l epreuve hors ligne.
La premiere correction n a pas suffi. Ajouter le controle de taille faisait
bien s executer la tache - et le fichier faisait toujours 0 octet au
passage suivant. get_url sur une destination existante emet une requete
CONDITIONNELLE : l amont repond non modifie, le module rend ok, la ruine
reste. Le play etait vert et ne reparait rien. Il faut effacer avant de
redemander.
Controle negatif : 0 -> 1022 octets, 0 erreur apt. Cinq roles.
LA SONDE CORRECTIFS, 23e. Set-OPS desarme unattended-upgrades et applique
les correctifs au deploiement - choix defendable, le verrou dpkg a fait
decrocher une machine d une reconstruction entiere le matin meme. Mais rien
ne disait QUAND le geste etait du : une flotte pouvait deriver des mois en
restant verte.
Elle mesure les paquets de securite en attente ET depuis quand. Elle ne
lance pas apt-get update - une sonde qui rafraichit l index toutes les
quinze minutes deviendrait la cause de la panne qu elle surveille. Et le
seuil de 72 h est un choix d exploitation, pas une derivation : le
mecanisme qui applique les correctifs est un geste humain.
P64 REFUSAIT UNE DECLARATION CORRECTE. serveur_debian et serveur_durci sont
des roles de declaration pure, sans une tache ; le travail est fait par les
roles que leur playbook applique. La preuve exigeait declaration et depot
dans le meme role - vrai des vingt-deux premieres sondes, faux des qu une
sonde appartient au socle. Une garde qui force a contourner ce qu elle
protege est un defaut. Elle suit desormais le playbook du groupe.
Mesure : 21/21 machines vertes, 65 preuves, 23 sondes, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 17:26:35 -04:00
|
|
|
# ... ET IL FAUT LE RETIRER, PAS SEULEMENT LE REDEMANDER (mesure du 2026-09-10).
|
|
|
|
|
#
|
|
|
|
|
# Laisser la garde autoriser la tache ne suffit PAS. `get_url` sur une destination qui
|
|
|
|
|
# existe emet une requete CONDITIONNELLE : l'amont repond « non modifie », le module rend
|
|
|
|
|
# `ok`, et le fichier corrompu reste en place. Mesure : la tache s'executait bien
|
|
|
|
|
# (`ok: [infra-mail-01]`), et la cle faisait toujours 0 octet au passage suivant. Un
|
|
|
|
|
# `force: yes` manuel l'a reparee en une seconde.
|
|
|
|
|
#
|
|
|
|
|
# On efface donc la ruine avant de reconstruire. `state: absent` ne mord que sur un
|
|
|
|
|
# fichier vide : une cle valide n'est jamais retiree, et la doctrine « on ne retelecharge
|
|
|
|
|
# pas ce qu'on possede deja » reste intacte.
|
|
|
|
|
- name: Retirer une ressource VIDE avant de la redemander
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_grafana_depot_cle_fichier }}"
|
|
|
|
|
state: absent
|
|
|
|
|
when:
|
|
|
|
|
- telecharger_la_cle_de_signature_grafana_present.stat.exists
|
|
|
|
|
- (telecharger_la_cle_de_signature_grafana_present.stat.size | default(0)) == 0
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Telecharger la cle de signature Grafana
|
un fichier vide existe, et une sonde pour les correctifs
LA GARDE FICHIER ENTIER, en deux corrections. Un telechargement
interrompu laisse un fichier de zero octet QUI EXISTE, et toutes les gardes
demandaient seulement s il etait la. infra-mail-01 a garde une cle
smallstep de 0 octet apres l epreuve hors ligne.
La premiere correction n a pas suffi. Ajouter le controle de taille faisait
bien s executer la tache - et le fichier faisait toujours 0 octet au
passage suivant. get_url sur une destination existante emet une requete
CONDITIONNELLE : l amont repond non modifie, le module rend ok, la ruine
reste. Le play etait vert et ne reparait rien. Il faut effacer avant de
redemander.
Controle negatif : 0 -> 1022 octets, 0 erreur apt. Cinq roles.
LA SONDE CORRECTIFS, 23e. Set-OPS desarme unattended-upgrades et applique
les correctifs au deploiement - choix defendable, le verrou dpkg a fait
decrocher une machine d une reconstruction entiere le matin meme. Mais rien
ne disait QUAND le geste etait du : une flotte pouvait deriver des mois en
restant verte.
Elle mesure les paquets de securite en attente ET depuis quand. Elle ne
lance pas apt-get update - une sonde qui rafraichit l index toutes les
quinze minutes deviendrait la cause de la panne qu elle surveille. Et le
seuil de 72 h est un choix d exploitation, pas une derivation : le
mecanisme qui applique les correctifs est un geste humain.
P64 REFUSAIT UNE DECLARATION CORRECTE. serveur_debian et serveur_durci sont
des roles de declaration pure, sans une tache ; le travail est fait par les
roles que leur playbook applique. La preuve exigeait declaration et depot
dans le meme role - vrai des vingt-deux premieres sondes, faux des qu une
sonde appartient au socle. Une garde qui force a contourner ce qu elle
protege est un defaut. Elle suit desormais le playbook du groupe.
Mesure : 21/21 machines vertes, 65 preuves, 23 sondes, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 17:26:35 -04:00
|
|
|
when: not (telecharger_la_cle_de_signature_grafana_present.stat.exists and telecharger_la_cle_de_signature_grafana_present.stat.size | default(0) > 0)
|
depot de binaires : le site tient ce que les runners allaient chercher
Le cache du site couvrait apt ; quatre artefacts arrivaient autrement, parce qu ils
ne vivent dans aucun depot apt. Le controleur les tire puis les pousse par SSH.
Mesure du 2026-09-12 : le cache du runner du site est ABSENT. Un second locataire
monte depuis lui sortait chercher 570 Mo sur codeberg.org, github.com et
download.nextcloud.com, alors que le meme ecosysteme ne demandait plus un seul
paquet a Debian. Le poste du mainteneur les a depuis toujours : personne ne l avait vu.
Pas de relais transparent, et la mesure tranche : github.com redirige vers une URL
signee valable une heure, differente a chaque requete. Un cache qui la prend pour
cle ne fait jamais mouche. Le relais marcherait pour deux amonts sur quatre.
Donc un vrai depot, dans le service qui existe deja. LocalDirs d apt-cacher-ng publie
un repertoire du disque sous un prefixe, eprouve AVANT d ecrire le role. Aucun service,
aucun port, aucun certificat, aucun flux nouveaux : l ingress 3142 pair flotte couvre
exactement ce chemin.
Les versions ne sont pas recopiees : le role lit les defauts des quatre consommateurs.
Les quatre roles recoivent une tache AJOUTEE, placee avant leur stat de cache — si le
depot sert, le stat le voit et la tache amont se saute d elle-meme. Aucune tache
existante n a change.
P70 exige que tout dest ecrit sous un cache_local figure au depot. Une liste qui suit
une autre prend du retard ; celle-ci est nee avec sa garde.
Deux marches payees en chemin :
- failed_when: false REECRIT le verdict, donc la premiere garde de signature ne
gardait rien. Elles mesurent le fichier desormais.
- file: state=directory cree les parents en 0750 : apt-cacher-ng, qui ne tourne pas
en root, rendait 403 sur chaque fichier. Un chemin se traverse en entier.
Verifie sur l infrastructure : 6/6 artefacts servis (200/206) depuis le runner du site
ET depuis une machine du locataire a travers la frontiere ; les 6 empreintes SHA-256
sont identiques a celles qui ont construit Chezlepro ; second passage changed=0.
make prouver : 69 OK, 0 echec, 1 saute. ansible-lint : 0 failure, profil production.
Inclut aussi force: true sur cinq telechargements de cles : une reprise conditionnelle
ne reprend rien (304 Not Modified, size 0, attempts 5).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 23:45:00 -04:00
|
|
|
# `force` PARCE QU'UNE REPRISE CONDITIONNELLE NE REPREND RIEN (2026-09-12).
|
|
|
|
|
#
|
|
|
|
|
# Sans lui, `get_url` envoie un `If-Modified-Since` des que le fichier existe. Le cache
|
|
|
|
|
# repond `304 Not Modified`, la tache reussit sans rien ecrire, et la boucle `until`
|
|
|
|
|
# — qui exige une taille non nulle — retente cinq fois contre un serveur qui repondra
|
|
|
|
|
# toujours 304 :
|
|
|
|
|
#
|
|
|
|
|
# HTTP Error 304: Not Modified size: 0 attempts: 5
|
|
|
|
|
#
|
|
|
|
|
# C'est la boucle de reprise qui se bat contre elle-meme. Le `when:` ci-dessus garantit
|
|
|
|
|
# deja qu'on ne retelecharge pas une cle valide ; `force` ne concerne donc que le cas
|
|
|
|
|
# ou l'on a DECIDE d'aller chercher.
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.get_url:
|
depot de binaires : le site tient ce que les runners allaient chercher
Le cache du site couvrait apt ; quatre artefacts arrivaient autrement, parce qu ils
ne vivent dans aucun depot apt. Le controleur les tire puis les pousse par SSH.
Mesure du 2026-09-12 : le cache du runner du site est ABSENT. Un second locataire
monte depuis lui sortait chercher 570 Mo sur codeberg.org, github.com et
download.nextcloud.com, alors que le meme ecosysteme ne demandait plus un seul
paquet a Debian. Le poste du mainteneur les a depuis toujours : personne ne l avait vu.
Pas de relais transparent, et la mesure tranche : github.com redirige vers une URL
signee valable une heure, differente a chaque requete. Un cache qui la prend pour
cle ne fait jamais mouche. Le relais marcherait pour deux amonts sur quatre.
Donc un vrai depot, dans le service qui existe deja. LocalDirs d apt-cacher-ng publie
un repertoire du disque sous un prefixe, eprouve AVANT d ecrire le role. Aucun service,
aucun port, aucun certificat, aucun flux nouveaux : l ingress 3142 pair flotte couvre
exactement ce chemin.
Les versions ne sont pas recopiees : le role lit les defauts des quatre consommateurs.
Les quatre roles recoivent une tache AJOUTEE, placee avant leur stat de cache — si le
depot sert, le stat le voit et la tache amont se saute d elle-meme. Aucune tache
existante n a change.
P70 exige que tout dest ecrit sous un cache_local figure au depot. Une liste qui suit
une autre prend du retard ; celle-ci est nee avec sa garde.
Deux marches payees en chemin :
- failed_when: false REECRIT le verdict, donc la premiere garde de signature ne
gardait rien. Elles mesurent le fichier desormais.
- file: state=directory cree les parents en 0750 : apt-cacher-ng, qui ne tourne pas
en root, rendait 403 sur chaque fichier. Un chemin se traverse en entier.
Verifie sur l infrastructure : 6/6 artefacts servis (200/206) depuis le runner du site
ET depuis une machine du locataire a travers la frontiere ; les 6 empreintes SHA-256
sont identiques a celles qui ont construit Chezlepro ; second passage changed=0.
make prouver : 69 OK, 0 echec, 1 saute. ansible-lint : 0 failure, profil production.
Inclut aussi force: true sur cinq telechargements de cles : une reprise conditionnelle
ne reprend rien (304 Not Modified, size 0, attempts 5).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-12 23:45:00 -04:00
|
|
|
force: true
|
2026-06-24 20:17:46 -04:00
|
|
|
url: "{{ serveur_grafana_depot_cle_url }}"
|
|
|
|
|
dest: "{{ serveur_grafana_depot_cle_fichier }}"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
2026-09-10 15:41:56 -04:00
|
|
|
# LA CLE PASSE PAR LE CACHE, ELLE AUSSI (mesure du 2026-09-10).
|
|
|
|
|
#
|
|
|
|
|
# `get_url` ignore la configuration d'apt : le mandataire pose dans
|
|
|
|
|
# `/etc/apt/apt.conf.d/` ne vaut que pour apt. Les cles de signature sortaient donc
|
|
|
|
|
# TOUJOURS en direct, meme apres que tous les depots soient passes par le cache — un
|
|
|
|
|
# trou reste ouvert derriere une porte qu'on croyait fermee.
|
|
|
|
|
#
|
|
|
|
|
# Et ce n'est pas theorique : depuis `collab-01`, la route directe vers
|
|
|
|
|
# `www.collaboraoffice.com` EXPIRE, quand le cache l'atteint sans peine.
|
|
|
|
|
#
|
|
|
|
|
# en direct grafana 200 collabora TIMEOUT
|
|
|
|
|
# via le cache collabora 200
|
|
|
|
|
#
|
|
|
|
|
# Le meme geste corrige donc les deux : plus rien ne sort, et la machine qui n'avait
|
|
|
|
|
# pas de route en trouve une.
|
|
|
|
|
#
|
|
|
|
|
# DEGRADE, JAMAIS DEVINE : sans cache d'amorcage declare, la valeur est VIDE et
|
|
|
|
|
# `get_url` sort en direct comme avant. On n'invente pas un mandataire.
|
|
|
|
|
environment:
|
|
|
|
|
http_proxy: >-
|
|
|
|
|
{{ ('http://' ~ artefacts_amorcage) if (artefacts_amorcage | default('') | string | length > 0) else '' }}
|
|
|
|
|
https_proxy: ""
|
reconstruction a froid : les noms derives naissent justes, et une cle vide tombe
Quatrieme reconstruction depuis zero, 32 min 14 s, 14/14. Elle avait un but
precis : trois roles dependent desormais d une variable que le generateur
pose. A froid, si instancier ne la posait pas, le defaut du role reprendrait
la main en silence — juste pour forge et cloud, faux pour observatoire.
Le certificat ne a froid porte observatoire et vigie, aucun ancien nom, et les
deux retours SSO derivent juste sans reprise.
Un seul echec, sans rapport : sur une machine des quatorze, get_url a rendu
0 octet SANS ERREUR — le cache a servi un 200 au corps vide. Le defaut s est
lu deux cents lignes plus loin, dans un apt qui accusait la signature. La
garde posee hier ne mordait pas : retirer une ressource vide ne vaut qu au
passage suivant, quand le fichier existe deja.
Les cinq roles qui telechargent une cle la mesurent maintenant dans la meme
execution. P68 garde le motif. infra-mail-01 redeployee, make valider a
0 echec sur 14 machines.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-11 07:57:24 -04:00
|
|
|
register: serveur_grafana_cle_depot
|
|
|
|
|
retries: 5
|
|
|
|
|
delay: 6
|
|
|
|
|
until: serveur_grafana_cle_depot is succeeded and (serveur_grafana_cle_depot.size | default(0)) > 0
|
2026-06-24 20:17:46 -04:00
|
|
|
|
les depots tiers passent par le cache, et le tenant n a plus le sien
Deux mouvements d une seule doctrine : le site fournit tout ce dont un
tenant a besoin pour venir au monde.
1. LES DEPOTS TIERS. Grafana, Icinga, Smallstep et Collabora ne publient
qu en HTTPS ; apt-cacher-ng ne relaie pas un tunnel, et le socle pose donc
Acquire::https::Proxy DIRECT. Chaque machine sortait elle-meme sur
Internet. Le cache declare desormais un Remap par fournisseur, et chaque
role demande en {{ ..._depot_schema }}:// - http des qu un cache est
declare, https sinon. Le TLS n est rompu nulle part : il est TERMINE au
cache, qui est notre machine, et l integrite vient des signatures.
avant : 4 fournisseurs en HTTPS direct, 14 machines sortant seules
apres : 0 source en HTTPS direct, 0 erreur apt sur 14 machines
Trois lecons. Le remap appartient au cache qui SORT : pose sur un cache
chaine, il tente le HTTPS a travers son amont et rend 503. apt_repository
AJOUTE au lieu de remplacer, donc l ancienne ligne https sortait toujours.
Et la liste des fournisseurs ne se devine pas - j en avais trois, l audit
en a revele un quatrieme.
2. LE CACHE DU TENANT. Sa ligne portait son propre retrait depuis toujours
- service MUTUALISABLE, un ecosysteme au premier age peut pointer sur celui
de son hote. Retiree. Ce qu on perd, dit franchement : plus de trafic
inter-zone et plus de charge sur site-cache-01, contre un service de moins
a poser, superviser et reproduire.
3. UN ROLE QU ON RETIRE DOIT DEFAIRE CE QU IL A FAIT. Le retrait a montre
que rien ne nettoie derriere. Le fichier apt visait un cache eteint en
ecrasant le plancher qui fonctionnait - le defaut deja paye a quinze
machines. Et les sondes du cache restaient, le porteur poussant pour des
services qu Icinga ne definit plus (404). Le socle retire le premier,
client_sante derive les sondes attendues et retire les orphelines.
P65 refuse tout role visant un depot relaye en https ecrit en dur. Sa
limite est dite : elle empeche une regression sur ce qui est connu, elle ne
decouvre pas l inconnu.
Mesure : Icinga 87 OK sur 96, prouver 65 OK, lint 0 defaut.
Reste, et c est dit : apt-cacher-ng tourne toujours sur forge-01 que plus
aucun plan ne declare.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 14:53:48 -04:00
|
|
|
# `apt_repository` AJOUTE, IL NE REMPLACE PAS (mesure du 2026-09-10).
|
|
|
|
|
#
|
|
|
|
|
# Passer une source de `https://` a `http://` y ecrit une SECONDE ligne au lieu de
|
|
|
|
|
# corriger la premiere. apt interroge alors les deux — et l'ancienne continue de sortir
|
|
|
|
|
# en direct sur Internet, ce que le passage au cache visait justement a supprimer. Le
|
|
|
|
|
# symptome le disait, sur les quatorze machines :
|
|
|
|
|
#
|
|
|
|
|
# W: La cible Packages est specifiee plusieurs fois dans grafana.list:1 et :2
|
|
|
|
|
#
|
|
|
|
|
# On retire donc explicitement la forme precedente. `state: absent` ne mord que si la
|
|
|
|
|
# ligne existe : sur une machine neuve, cette tache ne fait rien.
|
reconstruction a froid : les noms derives naissent justes, et une cle vide tombe
Quatrieme reconstruction depuis zero, 32 min 14 s, 14/14. Elle avait un but
precis : trois roles dependent desormais d une variable que le generateur
pose. A froid, si instancier ne la posait pas, le defaut du role reprendrait
la main en silence — juste pour forge et cloud, faux pour observatoire.
Le certificat ne a froid porte observatoire et vigie, aucun ancien nom, et les
deux retours SSO derivent juste sans reprise.
Un seul echec, sans rapport : sur une machine des quatorze, get_url a rendu
0 octet SANS ERREUR — le cache a servi un 200 au corps vide. Le defaut s est
lu deux cents lignes plus loin, dans un apt qui accusait la signature. La
garde posee hier ne mordait pas : retirer une ressource vide ne vaut qu au
passage suivant, quand le fichier existe deja.
Les cinq roles qui telechargent une cle la mesurent maintenant dans la meme
execution. P68 garde le motif. infra-mail-01 redeployee, make valider a
0 echec sur 14 machines.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-11 07:57:24 -04:00
|
|
|
- name: Mesurer la cle de signature Grafana qui vient d'etre posee
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ serveur_grafana_depot_cle_fichier }}"
|
|
|
|
|
register: cle_grafana_posee
|
|
|
|
|
|
|
|
|
|
- name: Exiger une cle NON VIDE avant de s'en servir
|
|
|
|
|
# UNE REUSSITE N'EST PAS UN CONTENU (mesure du 2026-09-11). Sur une reconstruction a
|
|
|
|
|
# froid, `get_url` a rendu 0 octet sans erreur sur UNE machine des quatorze : le cache
|
|
|
|
|
# a servi un 200 au corps vide. La garde « retirer une ressource VIDE » ne mord qu'au
|
|
|
|
|
# passage SUIVANT, quand le fichier existe deja — au premier, elle n'a rien a retirer.
|
|
|
|
|
#
|
|
|
|
|
# Le defaut ne se lisait pas ici. Il se lisait deux cents lignes plus loin, dans un
|
|
|
|
|
# `apt` qui accusait la SIGNATURE : « Missing key ..., which is needed to verify
|
|
|
|
|
# signature ». Un message qui envoie chercher une cle revoquee chez le fournisseur,
|
|
|
|
|
# alors que le fichier local fait zero octet.
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- (cle_grafana_posee.stat.size | default(0)) > 0
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
La cle de signature Grafana ({{ serveur_grafana_depot_cle_fichier }}) fait 0 octet.
|
|
|
|
|
Le depot a repondu sans corps — cache vide, ou amont injoignable. apt echouera
|
|
|
|
|
plus loin en accusant la signature : c'est ICI qu'il faut regarder.
|
|
|
|
|
|
les depots tiers passent par le cache, et le tenant n a plus le sien
Deux mouvements d une seule doctrine : le site fournit tout ce dont un
tenant a besoin pour venir au monde.
1. LES DEPOTS TIERS. Grafana, Icinga, Smallstep et Collabora ne publient
qu en HTTPS ; apt-cacher-ng ne relaie pas un tunnel, et le socle pose donc
Acquire::https::Proxy DIRECT. Chaque machine sortait elle-meme sur
Internet. Le cache declare desormais un Remap par fournisseur, et chaque
role demande en {{ ..._depot_schema }}:// - http des qu un cache est
declare, https sinon. Le TLS n est rompu nulle part : il est TERMINE au
cache, qui est notre machine, et l integrite vient des signatures.
avant : 4 fournisseurs en HTTPS direct, 14 machines sortant seules
apres : 0 source en HTTPS direct, 0 erreur apt sur 14 machines
Trois lecons. Le remap appartient au cache qui SORT : pose sur un cache
chaine, il tente le HTTPS a travers son amont et rend 503. apt_repository
AJOUTE au lieu de remplacer, donc l ancienne ligne https sortait toujours.
Et la liste des fournisseurs ne se devine pas - j en avais trois, l audit
en a revele un quatrieme.
2. LE CACHE DU TENANT. Sa ligne portait son propre retrait depuis toujours
- service MUTUALISABLE, un ecosysteme au premier age peut pointer sur celui
de son hote. Retiree. Ce qu on perd, dit franchement : plus de trafic
inter-zone et plus de charge sur site-cache-01, contre un service de moins
a poser, superviser et reproduire.
3. UN ROLE QU ON RETIRE DOIT DEFAIRE CE QU IL A FAIT. Le retrait a montre
que rien ne nettoie derriere. Le fichier apt visait un cache eteint en
ecrasant le plancher qui fonctionnait - le defaut deja paye a quinze
machines. Et les sondes du cache restaient, le porteur poussant pour des
services qu Icinga ne definit plus (404). Le socle retire le premier,
client_sante derive les sondes attendues et retire les orphelines.
P65 refuse tout role visant un depot relaye en https ecrit en dur. Sa
limite est dite : elle empeche une regression sur ce qui est connu, elle ne
decouvre pas l inconnu.
Mesure : Icinga 87 OK sur 96, prouver 65 OK, lint 0 defaut.
Reste, et c est dit : apt-cacher-ng tourne toujours sur forge-01 que plus
aucun plan ne declare.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 14:53:48 -04:00
|
|
|
- name: Retirer la forme HTTPS du depot (elle contournait le cache)
|
|
|
|
|
ansible.builtin.apt_repository:
|
|
|
|
|
repo: "{{ serveur_grafana_depot_source | replace('http://', 'https://') }}"
|
|
|
|
|
filename: grafana
|
|
|
|
|
state: absent
|
|
|
|
|
when: serveur_grafana_depot_schema == 'http'
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Ajouter le depot apt Grafana
|
|
|
|
|
ansible.builtin.apt_repository:
|
|
|
|
|
repo: "{{ serveur_grafana_depot_source }}"
|
|
|
|
|
filename: grafana
|
|
|
|
|
state: present
|
|
|
|
|
|
paquets tiers : passer par le cache du controleur, plus par Internet
Trois depots tiers etaient en HTTPS, et client_artefacts pose
Acquire::https::Proxy DIRECT — sans quoi le cache du site refuse les tunnels et
aucun depot tiers n est joignable. La ligne est juste ; sa consequence ne l avait
pas ete vue : ces trois depots CONTOURNENT le cache, et chaque VM neuve allait
les chercher sur Internet a sa naissance.
step-cli et alloy sont poses par des integrations UNIVERSELLES. Sans lien, une
machine neuve n obtenait ni son client d autorite ni ses metriques — elle n
entrait dans aucun flux chiffre. Dernier obstacle a une reconstruction hors
ligne, et il tenait dans un mot.
make cacher-paquets tire les 21 deb aux versions epinglees, empreinte SHA256
verifiee depuis l index du depot. Le role partage paquets_tiers les depose et les
installe EN UN SEUL appel a apt — il sait resoudre un ensemble de fichiers locaux
qui se dependent, la ou paquet par paquet echouerait sur l ordre (Icinga en
apporte dix-sept). Six roles branches ; chacun retombe sur le depot distant pour
ce que le cache n a PAS fourni, et rien d autre.
Eprouve pour de vrai : packages.smallstep.com renvoye vers 127.0.0.1, step-cli
desinstalle, cache local efface. Le role rejoue installe 0.30.6-1 depuis le cache
et la machine obtient ses certificats. Zero echec.
Deux defauts de mon propre outil, trouves en le construisant : Smallstep sert son
index NON COMPRESSE (404 sur .gz) donc step-cli n etait jamais mis en cache ; et
un depot injoignable faisait continue AVANT d incrementer le total, si bien que
le script rapportait 20 sur 20 alors qu il en manquait un. Une garde qui ne peut
pas echouer ne garde rien — troisieme fois cette semaine. Corrige puis eprouve en
le faisant echouer.
Reste hors ligne : NTP externe, et l expedition des alertes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-05 08:22:14 -04:00
|
|
|
# LE CACHE DU CONTROLEUR D'ABORD, LE DEPOT DISTANT POUR LE RESTE (2026-09-03).
|
|
|
|
|
#
|
|
|
|
|
# Les depots tiers sont en HTTPS, et `client_artefacts` pose
|
|
|
|
|
# `Acquire::https::Proxy "DIRECT"` — ils CONTOURNENT donc le cache du site et sortent sur
|
|
|
|
|
# Internet a chaque construction de VM. `make cacher-paquets` les tire une fois, versions
|
|
|
|
|
# epinglees et empreintes verifiees ; ce role les depose depuis ce cache.
|
|
|
|
|
- name: Poser les paquets tiers depuis le cache du controleur
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: paquets_tiers
|
|
|
|
|
vars:
|
|
|
|
|
paquets_tiers_noms: "{{ serveur_grafana_paquets }}"
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Installer Grafana
|
|
|
|
|
ansible.builtin.apt:
|
paquets tiers : passer par le cache du controleur, plus par Internet
Trois depots tiers etaient en HTTPS, et client_artefacts pose
Acquire::https::Proxy DIRECT — sans quoi le cache du site refuse les tunnels et
aucun depot tiers n est joignable. La ligne est juste ; sa consequence ne l avait
pas ete vue : ces trois depots CONTOURNENT le cache, et chaque VM neuve allait
les chercher sur Internet a sa naissance.
step-cli et alloy sont poses par des integrations UNIVERSELLES. Sans lien, une
machine neuve n obtenait ni son client d autorite ni ses metriques — elle n
entrait dans aucun flux chiffre. Dernier obstacle a une reconstruction hors
ligne, et il tenait dans un mot.
make cacher-paquets tire les 21 deb aux versions epinglees, empreinte SHA256
verifiee depuis l index du depot. Le role partage paquets_tiers les depose et les
installe EN UN SEUL appel a apt — il sait resoudre un ensemble de fichiers locaux
qui se dependent, la ou paquet par paquet echouerait sur l ordre (Icinga en
apporte dix-sept). Six roles branches ; chacun retombe sur le depot distant pour
ce que le cache n a PAS fourni, et rien d autre.
Eprouve pour de vrai : packages.smallstep.com renvoye vers 127.0.0.1, step-cli
desinstalle, cache local efface. Le role rejoue installe 0.30.6-1 depuis le cache
et la machine obtient ses certificats. Zero echec.
Deux defauts de mon propre outil, trouves en le construisant : Smallstep sert son
index NON COMPRESSE (404 sur .gz) donc step-cli n etait jamais mis en cache ; et
un depot injoignable faisait continue AVANT d incrementer le total, si bien que
le script rapportait 20 sur 20 alors qu il en manquait un. Une garde qui ne peut
pas echouer ne garde rien — troisieme fois cette semaine. Corrige puis eprouve en
le faisant echouer.
Reste hors ligne : NTP externe, et l expedition des alertes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-05 08:22:14 -04:00
|
|
|
# CE QUE LE CACHE N'A PAS FOURNI, ET RIEN D'AUTRE. Les dependances Debian passent
|
|
|
|
|
# par le cache du site en HTTP ; seuls les paquets tiers non caches exigent Internet.
|
|
|
|
|
# Reinstaller ce que le cache vient de poser ferait un `update_cache` inutile — et
|
|
|
|
|
# hors ligne, il echouerait APRES un travail deja fait.
|
|
|
|
|
name: "{{ serveur_grafana_paquets | difference((paquets_tiers_disponibles | default({})).keys() | list) }}"
|
2026-06-24 20:17:46 -04:00
|
|
|
state: present
|
|
|
|
|
update_cache: true
|
|
|
|
|
|
paquets tiers : passer par le cache du controleur, plus par Internet
Trois depots tiers etaient en HTTPS, et client_artefacts pose
Acquire::https::Proxy DIRECT — sans quoi le cache du site refuse les tunnels et
aucun depot tiers n est joignable. La ligne est juste ; sa consequence ne l avait
pas ete vue : ces trois depots CONTOURNENT le cache, et chaque VM neuve allait
les chercher sur Internet a sa naissance.
step-cli et alloy sont poses par des integrations UNIVERSELLES. Sans lien, une
machine neuve n obtenait ni son client d autorite ni ses metriques — elle n
entrait dans aucun flux chiffre. Dernier obstacle a une reconstruction hors
ligne, et il tenait dans un mot.
make cacher-paquets tire les 21 deb aux versions epinglees, empreinte SHA256
verifiee depuis l index du depot. Le role partage paquets_tiers les depose et les
installe EN UN SEUL appel a apt — il sait resoudre un ensemble de fichiers locaux
qui se dependent, la ou paquet par paquet echouerait sur l ordre (Icinga en
apporte dix-sept). Six roles branches ; chacun retombe sur le depot distant pour
ce que le cache n a PAS fourni, et rien d autre.
Eprouve pour de vrai : packages.smallstep.com renvoye vers 127.0.0.1, step-cli
desinstalle, cache local efface. Le role rejoue installe 0.30.6-1 depuis le cache
et la machine obtient ses certificats. Zero echec.
Deux defauts de mon propre outil, trouves en le construisant : Smallstep sert son
index NON COMPRESSE (404 sur .gz) donc step-cli n etait jamais mis en cache ; et
un depot injoignable faisait continue AVANT d incrementer le total, si bien que
le script rapportait 20 sur 20 alors qu il en manquait un. Une garde qui ne peut
pas echouer ne garde rien — troisieme fois cette semaine. Corrige puis eprouve en
le faisant echouer.
Reste hors ligne : NTP externe, et l expedition des alertes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-09-05 08:22:14 -04:00
|
|
|
when: (serveur_grafana_paquets
|
|
|
|
|
| difference((paquets_tiers_disponibles | default({})).keys() | list)) | length > 0
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Provisionner les datasources (Prometheus + Loki)
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: datasources.yaml.j2
|
|
|
|
|
dest: /etc/grafana/provisioning/datasources/setops.yaml
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0640"
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
2026-07-04 16:10:59 -04:00
|
|
|
- name: Assurer le repertoire des dashboards
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_grafana_dashboards_dir }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0750"
|
|
|
|
|
|
|
|
|
|
- name: Deployer le provisioning des dashboards
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: dashboards.yaml.j2
|
|
|
|
|
dest: /etc/grafana/provisioning/dashboards/setops.yaml
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0640"
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
|
|
|
|
- name: Deployer les dashboards Set-OPS
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
src: dashboards/
|
|
|
|
|
dest: "{{ serveur_grafana_dashboards_dir }}/"
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0640"
|
|
|
|
|
directory_mode: "0750"
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
grafana : les panneaux declares deviennent des tableaux
La moitie qui manquait. Les roles declaraient leurs panneaux, Prometheus en
derivait ses cibles, les expressions repondaient, et rien ne les assemblait.
serveur_grafana lit les memes meta/metriques.yml que serveur_prometheus et en
assemble un tableau par role — la raison du panneau devient sa description dans
Grafana. Moisson des tableaux orphelins, prefixe setops-role- pour ne jamais
toucher un tableau ecrit a la main, JSON valide avant d etre pose (Grafana ne
tombe pas sur un tableau illisible : il le saute en silence).
client_metrique declare quatre panneaux sans exportateur — le cas symetrique.
Celui qui compte : la memoire disponible, depuis que le ballon est actif.
Eprouve sur le site : les deux tableaux charges dans le stockage unifie, un
temoin orphelin retire, les quatre panneaux de flotte a 10 series chacun.
Un panneau etait faux — /var/lib/lxcfs rapporte toujours zero octet libre et un
min() en meurt. Corrige en liste blanche : un montage inconnu manque au graphe,
ce qui se voit, au lieu de l ecraser.
P77 garde la table des unites : une unite inventee retombe sur short, lisible et
fausse. 76 OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 16:32:30 -04:00
|
|
|
# --- UN TABLEAU PAR ROLE QUI DECLARE DES PANNEAUX (2026-09-14) -------------------------
|
|
|
|
|
#
|
|
|
|
|
# LA MOITIE QUI MANQUAIT. Les roles declaraient leurs panneaux dans `meta/metriques.yml`,
|
|
|
|
|
# Prometheus en derivait deja ses cibles, les expressions repondaient — et RIEN ne les
|
|
|
|
|
# assemblait. Un panneau declare que personne ne peut regarder n'est pas une
|
|
|
|
|
# observabilite, c'est une intention.
|
|
|
|
|
#
|
|
|
|
|
# EXACTEMENT LE PATRON DE `serveur_prometheus`, qui lit les memes fichiers pour en tirer
|
|
|
|
|
# ses cibles de scrutation. Les deux moities de `metriques.yml` trouvent ainsi leur
|
|
|
|
|
# consommateur : l'`exportateur` chez Prometheus, les `panneaux` ici.
|
|
|
|
|
#
|
|
|
|
|
# `run_once` ET `delegate_to: localhost` : les declarations vivent dans le DEPOT, sur le
|
|
|
|
|
# controleur — pas sur la machine. On les lit une fois, on les rend pour tout le monde.
|
|
|
|
|
- name: Relever les metriques que les roles declarent
|
|
|
|
|
ansible.builtin.find:
|
|
|
|
|
paths: "{{ role_path }}/.."
|
|
|
|
|
patterns: metriques.yml
|
|
|
|
|
recurse: true
|
|
|
|
|
depth: 3
|
|
|
|
|
delegate_to: localhost
|
|
|
|
|
become: false
|
|
|
|
|
run_once: true
|
|
|
|
|
check_mode: false
|
|
|
|
|
register: serveur_grafana_metas
|
|
|
|
|
|
|
|
|
|
- name: Lire chaque declaration de metriques
|
|
|
|
|
ansible.builtin.slurp:
|
|
|
|
|
src: "{{ item.path }}"
|
|
|
|
|
delegate_to: localhost
|
|
|
|
|
become: false
|
|
|
|
|
run_once: true
|
|
|
|
|
check_mode: false
|
|
|
|
|
loop: "{{ serveur_grafana_metas.files }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.path | dirname | dirname | basename }}"
|
|
|
|
|
register: serveur_grafana_declarations
|
|
|
|
|
|
|
|
|
|
# CE QUI SERA POSE, CALCULE UNE FOIS. On ne garde que les roles qui declarent vraiment des
|
|
|
|
|
# `panneaux` : un `metriques.yml` peut n'avoir qu'un `exportateur` — il aura une cible
|
|
|
|
|
# Prometheus et aucun tableau, et c'est un etat legitime, pas un oubli.
|
|
|
|
|
- name: Retenir les roles qui ont des panneaux a montrer
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
serveur_grafana_tableaux: >-
|
|
|
|
|
{{ serveur_grafana_declarations.results
|
|
|
|
|
| map(attribute='item.path') | map('dirname') | map('dirname') | map('basename')
|
|
|
|
|
| zip(serveur_grafana_declarations.results
|
|
|
|
|
| map(attribute='content') | map('b64decode') | map('from_yaml'))
|
|
|
|
|
| selectattr(1, 'mapping')
|
|
|
|
|
| selectattr('1.panneaux', 'defined')
|
|
|
|
|
| rejectattr('1.panneaux', 'none')
|
|
|
|
|
| list }}
|
|
|
|
|
run_once: true
|
|
|
|
|
|
|
|
|
|
- name: Assembler le tableau de chaque role
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: tableau-role.json.j2
|
|
|
|
|
dest: "{{ serveur_grafana_dashboards_dir }}/{{ serveur_grafana_tableaux_prefixe }}{{ item.0 }}.json"
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0640"
|
|
|
|
|
# LE JSON EST VALIDE AVANT D'ETRE POSE. Grafana n'echoue pas sur un tableau illisible :
|
|
|
|
|
# il le SAUTE, en silence, et le tableau disparait simplement de la liste. Sans cette
|
|
|
|
|
# validation, une expression PromQL mal repliee ferait perdre un tableau sans qu'aucune
|
|
|
|
|
# tache ne devienne rouge.
|
|
|
|
|
validate: "python3 -c \"import json,sys; json.load(open(sys.argv[1]))\" %s"
|
|
|
|
|
loop: "{{ serveur_grafana_tableaux }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.0 }} ({{ item.1.panneaux | length }} panneau(x))"
|
|
|
|
|
vars:
|
|
|
|
|
tableau_role: "{{ item.0 }}"
|
|
|
|
|
tableau_panneaux: "{{ item.1.panneaux }}"
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
2026-09-17 10:13:43 -04:00
|
|
|
# --- LE MATERIEL (2026-09-17) -----------------------------------------------------------
|
|
|
|
|
#
|
|
|
|
|
# Les hyperviseurs n'ont aucun role Set-OPS pour declarer leurs capteurs : ils ne sont pas
|
|
|
|
|
# de la flotte. Le catalogue vient donc de l'inventaire du site (`scripts/materiel.py`), et
|
|
|
|
|
# c'est le meme que la sonde Icinga lit. Pas de prefixe `setops-role-` : la moisson des
|
|
|
|
|
# tableaux de roles orphelins ne doit pas le voir.
|
|
|
|
|
- name: Assembler le tableau du matériel
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: tableau-materiel.json.j2
|
|
|
|
|
dest: "{{ serveur_grafana_dashboards_dir }}/setops-materiel.json"
|
|
|
|
|
owner: root
|
|
|
|
|
group: grafana
|
|
|
|
|
mode: "0640"
|
|
|
|
|
validate: "python3 -c \"import json,sys; json.load(open(sys.argv[1]))\" %s"
|
|
|
|
|
when: setops_materiel is defined
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
grafana : les panneaux declares deviennent des tableaux
La moitie qui manquait. Les roles declaraient leurs panneaux, Prometheus en
derivait ses cibles, les expressions repondaient, et rien ne les assemblait.
serveur_grafana lit les memes meta/metriques.yml que serveur_prometheus et en
assemble un tableau par role — la raison du panneau devient sa description dans
Grafana. Moisson des tableaux orphelins, prefixe setops-role- pour ne jamais
toucher un tableau ecrit a la main, JSON valide avant d etre pose (Grafana ne
tombe pas sur un tableau illisible : il le saute en silence).
client_metrique declare quatre panneaux sans exportateur — le cas symetrique.
Celui qui compte : la memoire disponible, depuis que le ballon est actif.
Eprouve sur le site : les deux tableaux charges dans le stockage unifie, un
temoin orphelin retire, les quatre panneaux de flotte a 10 series chacun.
Un panneau etait faux — /var/lib/lxcfs rapporte toujours zero octet libre et un
min() en meurt. Corrige en liste blanche : un montage inconnu manque au graphe,
ce qui se voit, au lieu de l ecraser.
P77 garde la table des unites : une unite inventee retombe sur short, lisible et
fausse. 76 OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 16:32:30 -04:00
|
|
|
# --- UN ROLE QU'ON RETIRE DOIT POUVOIR DEFAIRE CE QU'IL A FAIT ------------------------
|
|
|
|
|
#
|
|
|
|
|
# Meme lecon que les sondes orphelines de `client_sante`, et elle s'est deja payee ici :
|
|
|
|
|
# quand un ecosysteme cesse de declarer un service, plus rien ne retire ce qu'on avait pose
|
|
|
|
|
# pour lui. Un tableau orphelin est moins grave qu'une sonde orpheline — il n'echoue pas,
|
|
|
|
|
# il MENT : il affiche « aucune donnee » pour un service qui n'existe plus, et celui qui
|
|
|
|
|
# regarde croit a une panne.
|
|
|
|
|
#
|
|
|
|
|
# LE PREFIXE EST CE QUI PROTEGE `journaux-flotte.json` : il n'en porte pas, donc la moisson
|
|
|
|
|
# ne le voit pas. On n'efface jamais un tableau ecrit a la main.
|
|
|
|
|
- name: Relever les tableaux derives reellement poses
|
|
|
|
|
ansible.builtin.find:
|
|
|
|
|
paths: "{{ serveur_grafana_dashboards_dir }}"
|
|
|
|
|
patterns: "{{ serveur_grafana_tableaux_prefixe }}*.json"
|
|
|
|
|
register: serveur_grafana_poses
|
|
|
|
|
|
|
|
|
|
- name: Retirer les tableaux qu'aucun role ne declare plus
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ item.path }}"
|
|
|
|
|
state: absent
|
|
|
|
|
loop: "{{ serveur_grafana_poses.files }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.path | basename }}"
|
|
|
|
|
when: >-
|
|
|
|
|
(item.path | basename
|
|
|
|
|
| regex_replace('^' ~ serveur_grafana_tableaux_prefixe, '')
|
|
|
|
|
| regex_replace('\.json$', ''))
|
|
|
|
|
not in (serveur_grafana_tableaux | map(attribute=0) | list)
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Assurer le repertoire de drop-in systemd
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /etc/systemd/system/grafana-server.service.d
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Deployer la configuration d'environnement (domaine + secret)
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: setops.conf.j2
|
|
|
|
|
dest: /etc/systemd/system/grafana-server.service.d/setops.conf
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0600"
|
|
|
|
|
no_log: true
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
|
|
|
|
- name: Activer et demarrer Grafana
|
2026-07-01 21:01:53 -04:00
|
|
|
when: not ansible_check_mode
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "{{ serveur_grafana_service }}"
|
|
|
|
|
enabled: true
|
|
|
|
|
state: started
|
|
|
|
|
daemon_reload: true
|
2026-08-07 21:10:47 -04:00
|
|
|
|
|
|
|
|
# --- ROTATION DU COMPTE DE SECOURS -------------------------------------------
|
|
|
|
|
# `GF_SECURITY_ADMIN_PASSWORD` n'agit qu'a la CREATION du compte : changer la voute
|
|
|
|
|
# ne changeait rien, et la voute se mettait a mentir en silence. Le runbook de
|
|
|
|
|
# reprise (docs/autorisation.md §6) promet pourtant cette rotation — c'est ce qui
|
|
|
|
|
# transforme une livraison en transfert. Constate le 2026-08-07.
|
|
|
|
|
#
|
|
|
|
|
# Idempotence par EMPREINTE : on garde le sha256 du secret applique. Tant qu'il ne
|
|
|
|
|
# change pas, on ne touche a rien ; des qu'il change, on reapplique. On ne peut pas
|
|
|
|
|
# lire le mot de passe en place, donc on memorise ce qu'on a pose.
|
keycloak : un jeton frais la ou on s'en sert ; grafana : un echec lisible
Technolibre remonte depuis zero une seconde fois — 14 hotes, 2588 taches ok,
0 failed. Deux defauts trouves en chemin.
LE JETON KEYCLOAK VIVAIT 60 SECONDES. Il etait pris dans politique-mdp.yml —
le 2e des neuf fichiers du role — et reutilise jusqu'au 8e. Entre les deux,
six fichiers de travail dont groupes-ldap.yml et ses reprises espacees de
15 s. Sur une construction NEUVE le temps depasse la minute : 401. Sur un
REJEU tout est converge, ca va vite, ca passe.
D'ou les deux echecs du matin, chaque fois suivis d'un succes au rejeu, qui
donnaient l'illusion d'une course au demarrage de Keycloak. J'avais ecrit
alors ne pas avoir de mesure qui le prouve — c'etait juste, et la cause etait
l'AGE du jeton. jeton-admin.yml en prend un frais la ou on s'en sert.
GRAFANA : UN ECHEC TRANSITOIRE RENDU ILLISIBLE. Premier demarrage, apres 67 s
de migrations : « failed to create admin user: no such column: uid », alors
que la migration qui ajoute cette colonne etait journalisee comme reussie.
Base neuve : tout remigre, service actif, colonne presente. L'incident ne
s'est pas reproduit et Chezlepro ne l'a jamais eu — je n'ai donc PAS corrige
la cause, faute de l'avoir reproduite. J'ai corrige ce qui la rendait
indechiffrable :
- Restart=on-failure venait du paquet SANS RestartSec, donc 100 ms : six
relances en une seconde, chacune rejouant les migrations sur la meme base
SQLite. Un echec unique se presentait comme un desastre. RestartSec=10 ;
- la rotation du compte de secours echouait cinq fois sous no_log en
annoncant « the output has been hidden », alors que la vraie cause etait
ailleurs et lisible : le serveur ne demarrait pas. Une attente explicite sur
le port precede desormais la CLI, avec un message qui renvoie a la PREMIERE
erreur du journal.
Troisieme fois dans la journee que no_log masque la cause au moment ou elle
sert : une garde qui protege un secret ne doit pas emporter le diagnostic.
Verifie : 7 devis sur Technolibre — MTU, identite, certificats, PostgreSQL,
courriel, frontiere CONFORME ; prouver.py 35 OK ; ansible-lint production.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 20:19:50 -04:00
|
|
|
# EXIGER QUE LE SERVEUR REPONDE AVANT DE TOUCHER A SA BASE. La CLI qui suit echouait
|
|
|
|
|
# sinon cinq fois de suite sous `no_log`, en annoncant « the output has been hidden » —
|
|
|
|
|
# alors que la vraie cause etait ailleurs et parfaitement lisible : `grafana-server` ne
|
|
|
|
|
# demarrait pas, sa base ayant echoue une migration au premier lancement (2026-08-10,
|
|
|
|
|
# `no such column: uid`). Cinq reprises censurees contre un message clair : on prefere
|
|
|
|
|
# le message.
|
|
|
|
|
- name: Attendre que Grafana réponde avant de toucher au compte de secours
|
|
|
|
|
ansible.builtin.wait_for:
|
|
|
|
|
host: 127.0.0.1
|
|
|
|
|
port: "{{ serveur_grafana_port | default(3000) }}"
|
|
|
|
|
timeout: 120
|
|
|
|
|
register: serveur_grafana_pret
|
|
|
|
|
failed_when: false
|
|
|
|
|
when: not ansible_check_mode
|
|
|
|
|
|
|
|
|
|
- name: Dire que Grafana ne répond pas, plutôt que d'échouer sur sa CLI
|
|
|
|
|
ansible.builtin.fail:
|
|
|
|
|
msg: >-
|
|
|
|
|
Grafana n'écoute pas sur le port {{ serveur_grafana_port | default(3000) }} après
|
|
|
|
|
120 s : la rotation du compte de secours ne peut pas aboutir, et sa CLI ne dirait
|
|
|
|
|
rien d'utile. Regarder `journalctl -u grafana-server` — et y chercher la PREMIÈRE
|
|
|
|
|
erreur, pas la dernière : `Restart=on-failure` en empile plusieurs.
|
|
|
|
|
when:
|
|
|
|
|
- not ansible_check_mode
|
|
|
|
|
- serveur_grafana_pret is failed
|
|
|
|
|
|
2026-08-07 21:10:47 -04:00
|
|
|
- name: Empreinte du mot de passe admin en place
|
|
|
|
|
ansible.builtin.slurp:
|
|
|
|
|
src: "{{ serveur_grafana_marqueur_admin }}"
|
|
|
|
|
register: serveur_grafana_marque
|
|
|
|
|
failed_when: false
|
|
|
|
|
changed_when: false
|
|
|
|
|
no_log: true
|
|
|
|
|
|
|
|
|
|
- name: Appliquer le mot de passe du compte de secours (rotation)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv:
|
|
|
|
|
- grafana-cli
|
|
|
|
|
- "--homepath={{ serveur_grafana_homepath }}"
|
|
|
|
|
# `paths.data` DOIT etre impose : la CLI le prend par defaut a
|
|
|
|
|
# `<homepath>/data`, alors que le paquet Debian range la base dans
|
|
|
|
|
# /var/lib/grafana. Sans lui, la CLI cree une base FANTOME, y ecrit, et
|
|
|
|
|
# annonce « Admin password changed successfully » — pendant que le serveur
|
|
|
|
|
# lit l'autre. Constate le 2026-08-07 : le compte n'avait pas bouge depuis
|
|
|
|
|
# le deploiement initial, malgre quatre reinitialisations « reussies ».
|
|
|
|
|
- "--configOverrides=cfg:default.paths.data={{ serveur_grafana_donnees }}"
|
|
|
|
|
- admin
|
|
|
|
|
- reset-admin-password
|
|
|
|
|
- "{{ serveur_grafana_admin_password }}"
|
|
|
|
|
no_log: true
|
|
|
|
|
# La tache ne s'execute QUE si l'empreinte differe : quand elle tourne, elle
|
|
|
|
|
# change reellement le mot de passe.
|
|
|
|
|
changed_when: true
|
2026-08-08 23:47:34 -04:00
|
|
|
# PATIENTE : sur une machine neuve, cette commande suit de peu le premier
|
|
|
|
|
# demarrage de grafana-server, qui cree encore sa base. La CLI echoue alors sur
|
|
|
|
|
# une base absente ou verrouillee. Constate le 2026-08-08 pendant la premiere
|
|
|
|
|
# reconstruction from-zero ; rejouee seule quelques minutes plus tard, la meme
|
|
|
|
|
# commande passe. Meme classe que l'ecriture Keycloak qui suit la synchro LDAP :
|
|
|
|
|
# une COURSE de premier demarrage, pas une panne. On attend une condition, pas
|
|
|
|
|
# une duree.
|
|
|
|
|
register: serveur_grafana_reset
|
|
|
|
|
retries: 5
|
|
|
|
|
delay: 10
|
|
|
|
|
until: serveur_grafana_reset is succeeded
|
2026-08-07 21:10:47 -04:00
|
|
|
when: >-
|
|
|
|
|
(serveur_grafana_marque.content | default('') | b64decode | trim)
|
|
|
|
|
!= (serveur_grafana_admin_password | hash('sha256'))
|
|
|
|
|
notify: Redemarrer grafana
|
|
|
|
|
|
|
|
|
|
- name: Retenir l'empreinte appliquee
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
content: "{{ serveur_grafana_admin_password | hash('sha256') }}\n"
|
|
|
|
|
dest: "{{ serveur_grafana_marqueur_admin }}"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0600"
|
|
|
|
|
no_log: true
|
sondes : les six premieres, et le patron qui les rend eprouvables
Ajout de meta/supervision.yml a six roles, chacun deposant sa propre sonde
selon le contrat des greffons Nagios.
DEUX PRINCIPES POSES AU DOCUMENT DE CONCEPTION, parce que la premiere
sonde les a imposes :
1. UNE SONDE DOIT POUVOIR ETRE MISE EN DEFAUT PAR PARAMETRE. Cible et
seuils sont des variables du role : on la prouve rouge avec un port ferme
ou un seuil impossible, sur une machine reelle, sans rien casser, et
aussi souvent qu on veut. Une sonde qu on ne peut prouver qu en cassant un
service ne sera prouvee qu une fois.
2. LA SONDE VIT LA OU VIT LA VERITE. « Ce noeud est-il collecte ? » est
une sonde de serveur_prometheus, pas de client_metrique : une seule y voit
les N noeuds, et surtout elle voit le cas SILENCIEUX — celui qui a cesse d
etre collecte ne peut pas s en plaindre.
LES SIX : cache-apt (artefacts, repond + place), resolution (resolveur,
zone interne ET Internet — deux chemins distincts), forge (forgejo, son
propre /api/healthz), collecte (prometheus, 15/15 cibles), tableaux
(grafana, base ok), ingestion (loki, PRET a ingerer, pas seulement en
ecoute).
TROIS FOIS J AI ECRIT LA SONDE AVANT DE MESURER, ET TROIS FOIS ELLE A EU
TORT. La forge : port 443 et chemin des depots INVENTES — elle ecoute en
3000 derriere l edge et n a legitimement aucun depot. Loki : j ai conclu
« panne persistante » sur deux lectures prises a quelques secondes d
intervalle, juste apres un redemarrage ; l anneau etait ACTIVE et la
reponse est passee a ready moins d une minute plus tard. Le delai de
stabilisation est desormais un AVERTISSEMENT nomme, pas une panne.
On demande au service ce qu il pense de lui-meme quand il sait le dire
(healthz, /ready, /api/health) plutot que d inventer un critere de l
exterieur.
make prouver : CONFORME.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 02:48:55 -04:00
|
|
|
|
|
|
|
|
# --- Sonde de supervision (docs/supervision-conception.md) --------------------------
|
|
|
|
|
# Le role qui possede la verite depose sa propre sonde ; le porteur (`client_sante`) la
|
|
|
|
|
# fait tourner et pousse le verdict, sans savoir ce qu'elle mesure.
|
|
|
|
|
- name: Assurer le repertoire des sondes de supervision
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /usr/local/lib/setops/sondes
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Deposer la sonde « tableaux »
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: sonde-tableaux.sh.j2
|
|
|
|
|
dest: /usr/local/lib/setops/sondes/tableaux.sh
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0750"
|