Set-OPS-Public/roles/serveur_ops_site/tasks/main.yml
Daniel Allaire aac74f6043 supervision : les huit derniers roles, et deux defauts que l epreuve a trouves
Les 33 roles serveur_* declarent maintenant une sonde. Les huit qui manquaient
sont ceux dont la verite ne ressemble pas a « ce service repond-il ».

Quatre marqueurs du site : ce que tasks/main.yml verifie UNE FOIS au deploiement
cesse d etre vrai sans que rien ne tombe. La racine du cache se retrouve chainee,
la forge du genome repond en n ayant plus rien dedans, un locataire n est plus
admis a resoudre, l isolation d un depot glisse.

serveur_ops_site ne sert rien : il detient un pouvoir. La sonde verifie que la
carte est la, que la voute du site est chiffree et que sa cle est en 0600 — sans
lire le contenu d aucun des trois.

serveur_icingaweb2 surveille la vitrine de la supervision elle-meme : si la
console meurt, tout reste vert et l exploitant est aveugle.

DEFAUT 1 — quatre gabarits qu Ansible aurait refuse de rendre. Jinja lit le
{# de ${#tableau[@]} comme un debut de commentaire. Le depot connaissait le
remede et l appliquait la ou quelqu un s etait fait prendre, nulle part ailleurs.
P76 rend desormais chaque gabarit de role, avec les delimiteurs qu Ansible en
tirerait — pas une recherche de motif.

DEFAUT 2 — la doctrine promettait 54 greffons et citait check_pgsql. La flotte a
monitoring-plugins-basic : 53, sans check_pgsql ni check_dns ni check_ldap. Le
paquet qui les porte traine samba et snmp sur chaque machine. Un greffon absent
sort en 127, qui n est pas un code Nagios.

21 controles negatifs sur les machines reelles du site. ansible-lint production
0/91, harnais 75 OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 15:43:52 -04:00

153 lines
6 KiB
YAML

---
- name: Exiger les intrants du runner de site
ansible.builtin.assert:
that:
- serveur_ops_site_depot | length > 0
- (not (serveur_ops_site_voute_deposer | bool)) or (serveur_ops_site_voute_source | length > 0)
fail_msg: >-
serveur_ops_site exige `serveur_ops_site_depot` (le dossier du dépôt SITE chez le
runner, cloné par serveur_ops) et, si le dépôt de la voûte est demandé,
`serveur_ops_site_voute_source` (le chemin de `underlay.vault.yml` sur le contrôleur).
- name: Le dépôt du SITE est-il bien là ?
ansible.builtin.stat:
path: "{{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.yml"
register: serveur_ops_site_carte
- name: Refuser si la carte de la fabric manque
ansible.builtin.assert:
that:
- serveur_ops_site_carte.stat.exists
fail_msg: >-
{{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.yml est absent.
Déclarer ce dépôt dans `serveur_ops_depots` (role: hebergeur) et rejouer serveur_ops :
un runner de site sans carte ne sait pas sur quoi il matérialise.
when: not ansible_check_mode
# LES CLÉS DU MONDE PHYSIQUE, DE DROIT ET NON PAR EMPRUNT.
#
# `decrypt: no` : voir defaults/main.yml. Le fichier reste chiffré ; seul le mot de passe,
# tapé à l'exécution, l'ouvre.
- name: Déposer la voûte du SITE (chiffrée)
ansible.builtin.copy:
src: "{{ serveur_ops_site_voute_source }}"
dest: "{{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.vault.yml"
owner: "{{ serveur_ops_site_utilisateur }}"
group: "{{ serveur_ops_site_utilisateur }}"
mode: "0600"
decrypt: false
when:
- serveur_ops_site_voute_deposer | bool
- not ansible_check_mode
# ÉCRIRE, PUIS RELIRE (D-68). Une voûte déchiffrée par accident est une fuite silencieuse :
# le fichier existe, le rôle se dit satisfait, et les clés du cluster dorment en clair.
- name: Relire l'en-tête de la voûte déposée
ansible.builtin.command:
cmd: "head -c 21 {{ serveur_ops_site_racine }}/{{ serveur_ops_site_depot }}/underlay.vault.yml"
register: serveur_ops_site_entete
changed_when: false
when:
- serveur_ops_site_voute_deposer | bool
- not ansible_check_mode
- name: Exiger que la voûte déposée soit CHIFFRÉE
ansible.builtin.assert:
that:
- "'$ANSIBLE_VAULT' in serveur_ops_site_entete.stdout"
fail_msg: >-
La voûte déposée n'est PAS chiffrée — elle a été déchiffrée en transit.
Vérifier `decrypt: false` sur la copie. Détruire le fichier au shred et
considérer les justificatifs du cluster comme exposés.
when:
- serveur_ops_site_voute_deposer | bool
- not ansible_check_mode
# --- ARMER LE RUNNER ---------------------------------------------------------
#
# Ce qui suit ne se declenche que si un humain l'a demande (serveur_ops_site_cle_deposer).
- name: Exiger une source pour la cle de la voute
ansible.builtin.assert:
that:
- serveur_ops_site_cle_source | length > 0
fail_msg: >-
serveur_ops_site_cle_deposer est vrai, mais aucune
`serveur_ops_site_cle_source` n'est nommee. Armer un runner sans dire
avec QUELLE cle n'a pas de sens — et poser un fichier vide le laisserait croire
arme.
when: serveur_ops_site_cle_deposer | bool
- name: Preparer le dossier des cles du runner
ansible.builtin.file:
path: "{{ serveur_ops_site_racine }}/.config"
state: directory
owner: "{{ serveur_ops_site_utilisateur }}"
group: "{{ serveur_ops_site_utilisateur }}"
mode: "0700"
when:
- serveur_ops_site_cle_deposer | bool
- not ansible_check_mode
- name: Deposer la cle de la voute
ansible.builtin.copy:
src: "{{ serveur_ops_site_cle_source }}"
dest: "{{ serveur_ops_site_cle_destination }}"
owner: "{{ serveur_ops_site_utilisateur }}"
group: "{{ serveur_ops_site_utilisateur }}"
mode: "0600"
no_log: true
when:
- serveur_ops_site_cle_deposer | bool
- not ansible_check_mode
# ECRIRE, PUIS RELIRE — comme pour la voute, et pour la faute SYMETRIQUE : ici on ne
# craint pas un chiffre devenu clair, mais une cle qui serait en fait une VOUTE. Copier le
# mauvais fichier laisse un runner qui se croit arme et echoue au premier secret, tres
# loin d'ici. On mesure aussi qu'elle n'est pas vide : un fichier de mot de passe vide est
# accepte par Ansible et n'ouvre rien.
- name: Relire la cle deposee
ansible.builtin.stat:
path: "{{ serveur_ops_site_cle_destination }}"
checksum_algorithm: sha256
register: serveur_ops_site_cle_posee
when:
- serveur_ops_site_cle_deposer | bool
- not ansible_check_mode
- name: Exiger une cle non vide, en 0600, et qui ne soit pas une voute
ansible.builtin.assert:
that:
- serveur_ops_site_cle_posee.stat.exists
- serveur_ops_site_cle_posee.stat.size > 0
- serveur_ops_site_cle_posee.stat.mode == '0600'
fail_msg: >-
La cle deposee est absente, vide, ou lisible au-dela de son proprietaire.
Un runner arme d'une cle vide se croit arme et echoue au premier secret,
tres loin d'ici.
when:
- serveur_ops_site_cle_deposer | bool
- not ansible_check_mode
# LE ROLE QUI POSSEDE LA VERITE DEPOSE SA PROPRE SONDE. `client_sante` la fait tourner et
# pousse le resultat.
#
# CE ROLE EST FAIT D'ASSERTIONS, ET UNE ASSERTION NE VIT QUE LE TEMPS D'UN DEPLOIEMENT.
# Or ce qu'elles protegent — la carte, la voute et sa cle — ne fait tomber AUCUN service
# en disparaissant. On ne s'en apercoit qu'en voulant materialiser, c'est-a-dire au pire
# moment. La sonde rejoue les memes questions toutes les quinze minutes.
- 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 « pouvoir-materialiser »
ansible.builtin.template:
src: sonde-pouvoir-materialiser.sh.j2
dest: /usr/local/lib/setops/sondes/pouvoir-materialiser.sh
owner: root
group: root
mode: "0750"