Set-OPS-Public/roles/serveur_grafana/tasks/main.yml
Daniel Allaire 91d3a736e7 rotation : les comptes de secours peuvent enfin changer de mot de passe
Le runbook promettait cette rotation ; le code ne savait pas la faire. Les trois
roles ne posaient le mot de passe qu'a la CREATION — regenerer la voute aurait
produit le mensonge silencieux corrige toute la journee.

Chaque role sait desormais CHANGER un mot de passe existant, idempotent par
empreinte du secret applique. Pour Nextcloud le secret passe par l'environnement,
pas par la ligne de commande ou il serait visible dans la table des processus.

`grafana-cli` ecrivait dans une base FANTOME en annoncant « changed successfully »
a chaque fois : il prend `paths.data` a `<homepath>/data`, le paquet Debian range
la base dans /var/lib/grafana. Demasque par le champ `updated` du compte, reste a
l'heure du deploiement initial malgre quatre reinitialisations « reussies ». Un
message de succes n'est pas une preuve ; l'etat l'est.

Verifie par authentification reelle : Grafana 200, Nextcloud 200. Forgejo ferme
l'API par doctrine (D-41) — seule preuve disponible : le retour de la commande.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 21:10:47 -04:00

154 lines
5 KiB
YAML

---
# 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).
- name: Resoudre le fournisseur d'identite (role partage)
ansible.builtin.include_role:
name: resoudre_idp
vars:
resoudre_idp_realm: "{{ serveur_grafana_oidc_realm }}"
- 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"
- name: Telecharger la cle de signature Grafana
ansible.builtin.get_url:
url: "{{ serveur_grafana_depot_cle_url }}"
dest: "{{ serveur_grafana_depot_cle_fichier }}"
owner: root
group: root
mode: "0644"
- name: Ajouter le depot apt Grafana
ansible.builtin.apt_repository:
repo: "{{ serveur_grafana_depot_source }}"
filename: grafana
state: present
- name: Installer Grafana
ansible.builtin.apt:
name: "{{ serveur_grafana_paquets }}"
state: present
update_cache: true
- 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
- 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
- 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
when: not ansible_check_mode
ansible.builtin.systemd:
name: "{{ serveur_grafana_service }}"
enabled: true
state: started
daemon_reload: true
# --- 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.
- 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
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