--- # LE NOEUD RAPPORTE SES UNITES EN ECHEC. Voir le gabarit du script pour le pourquoi. # # CE ROLE N'A PAS A SE DEMANDER S'IL Y A UNE SUPERVISION — IL EN A UNE (2026-09-09). # # Il portait une branche « aucun serveur_icinga : rien a poser », et un `when` sur tout le # bloc. Ni l'une ni l'autre ne pouvait s'executer : `client_sante` est une INTEGRATION # UNIVERSELLE, et `instancier` ne pose une integration universelle que si son serveur # existe dans l'ecosysteme. Eprouve sur le modele public — sans Icinga au plan, le groupe # `client_sante` est ABSENT de l'inventaire genere ; avec, les quatre noeuds y entrent. # Le role n'est donc jamais appele sans destinataire. # # Une garde qui ne peut pas se declencher n'est pas une garde : elle rassure sans rien # tenir. Ce qui la remplace se declenche vraiment — si ce role s'execute, un destinataire # ET son secret sont exiges, et l'echec dit LEQUEL des deux manque. - name: Exiger un destinataire et de quoi lui parler ansible.builtin.assert: that: - client_sante_icinga_hote | length > 0 - client_sante_icinga_motdepasse | length > 0 fail_msg: >- Rapport de santé impossible : {{ "aucun hôte `serveur_icinga` dans l'inventaire" if not client_sante_icinga_hote else "`vault_icinga_api_depot` absent de la voûte" }}. Le nœud verrait ses unités en échec sans pouvoir le dire. - name: Assurer le répertoire des secrets Set-OPS ansible.builtin.file: path: /etc/setops state: directory owner: root group: root mode: "0755" - name: Déposer le mot de passe d'API Icinga ansible.builtin.copy: content: "{{ client_sante_icinga_motdepasse }}\n" dest: /etc/setops/icinga-api.pass owner: root group: root mode: "0600" no_log: true # L'AC d'ICINGA, PAS CELLE DE step-ca : Icinga refuse de servir un certificat qu'il # n'a pas emis (il renouvelle tout ce qui expire sous 30 jours, nos certificats vivent # 24 h). Domaine de confiance ferme, pair authentifie malgre tout. - name: L'AC d'Icinga est-elle déjà disponible ? ansible.builtin.stat: path: "{{ client_sante_icinga_ca_source }}" delegate_to: "{{ client_sante_icinga_hote }}" register: client_sante_ca_presente - name: Récupérer l'AC d'Icinga depuis l'hôte de supervision when: client_sante_ca_presente.stat.exists ansible.builtin.slurp: src: "{{ client_sante_icinga_ca_source }}" delegate_to: "{{ client_sante_icinga_hote }}" register: client_sante_ca_icinga - name: Déposer l'AC d'Icinga pour la vérification du pair when: client_sante_ca_presente.stat.exists ansible.builtin.copy: content: "{{ client_sante_ca_icinga.content | b64decode }}" dest: "{{ client_sante_ca_verification }}" owner: root group: root mode: "0644" - name: Installer curl pour le rapport passif ansible.builtin.apt: name: curl state: present - name: Déployer le script de rapport de santé ansible.builtin.template: src: setops-sante.sh.j2 dest: /usr/local/sbin/setops-sante.sh owner: root group: root mode: "0750" - name: Déployer l'unité systemd du rapport ansible.builtin.template: src: setops-sante.service.j2 dest: /etc/systemd/system/setops-sante.service owner: root group: root mode: "0644" notify: Recharger systemd - name: Déployer le minuteur du rapport ansible.builtin.template: src: setops-sante.timer.j2 dest: /etc/systemd/system/setops-sante.timer owner: root group: root mode: "0644" notify: Recharger systemd - name: Activer le rapport de santé ansible.builtin.systemd: name: setops-sante.timer enabled: true state: started daemon_reload: true # PREMIER RAPPORT IMMEDIAT, et ce n'est pas une commodite : sans lui, le service # reste « en attente » jusqu'au premier declenchement, et un deploiement qui vient # d'installer la supervision laisserait un tableau vide qu'on prendrait pour un # tableau sain. - name: Rapporter tout de suite (ne pas laisser un tableau vide passer pour sain) ansible.builtin.command: /usr/local/sbin/setops-sante.sh changed_when: false failed_when: false