La chaine est complete : LDAP cn=sysadmin -> groupe de realm -> role grafana-admin -> Admin dans Grafana. Ajouter quelqu'un au groupe dans l'annuaire lui ouvre Grafana sans deploiement et sans que personne ne soit nomme (D-66). Rejoue : changed=0. Defaut de fond trouve en chemin : la federation LDAP n'etait JAMAIS reconciliee. `federation-ldap.yml` creait le provider s'il manquait puis ne le corrigeait plus — il pointait encore `ldaps://id-ldap-01...`, le nom errone corrige le matin meme dans `resoudre_annuaire`. La synchronisation echouait sur `UnknownHost`. C'est le revers de D-67 au mauvais endroit : l'INFRASTRUCTURE se reconcilie, seules les appartenances ne le sont pas. URL, usersDn et bindDn sont desormais corriges a chaque passage. Et j'avais masque l'echec avec `|| true` : le mapper existait, le realm restait vide, rien ne disait pourquoi. Retire — l'erreur remonte avec son message. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
82 lines
4.2 KiB
YAML
82 lines
4.2 KiB
YAML
---
|
|
# Fédération LDAP via kcadm — idempotent. Crée le realm applicatif + le provider de
|
|
# stockage LDAP (OpenLDAP, READ_ONLY). Éprouvé avant codification (testmail se connecte).
|
|
- name: Attendre que Keycloak réponde
|
|
ansible.builtin.wait_for:
|
|
host: 127.0.0.1
|
|
port: 8080
|
|
timeout: 120
|
|
when: not ansible_check_mode
|
|
|
|
- name: Configurer le realm et la fédération LDAP (kcadm, idempotent)
|
|
ansible.builtin.shell:
|
|
executable: /bin/bash
|
|
cmd: |
|
|
set -euo pipefail
|
|
KC={{ serveur_keycloak_home }}/bin/kcadm.sh
|
|
CHANGED=0
|
|
"$KC" config credentials --server http://localhost:8080 --realm master \
|
|
--user {{ serveur_keycloak_admin_user }} --password "$KC_ADMIN_PW" >/dev/null
|
|
if ! "$KC" get realms/{{ serveur_keycloak_realm }} >/dev/null 2>&1; then
|
|
"$KC" create realms -s realm={{ serveur_keycloak_realm }} -s enabled=true >/dev/null
|
|
CHANGED=1
|
|
fi
|
|
RID=$("$KC" get realms/{{ serveur_keycloak_realm }} --fields id 2>/dev/null \
|
|
| grep -oiE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' | head -1)
|
|
# Le provider est cree S'IL MANQUE, et son URL de connexion est RECONCILIEE
|
|
# s'il existe. Creer sans jamais corriger laissait une valeur perimee vivre
|
|
# indefiniment : le 2026-08-07, le provider pointait encore
|
|
# `ldaps://id-ldap-01...` — le nom d'hote errone corrige le matin meme dans
|
|
# `resoudre_annuaire`. La federation etait muette, et la synchronisation des
|
|
# groupes echouait sur `UnknownHost`.
|
|
#
|
|
# C'est de l'INFRASTRUCTURE : elle se reconcilie. Seules les APPARTENANCES
|
|
# ne le sont pas (D-67), et elles ne vivent pas ici.
|
|
FEDID=$("$KC" get components -r {{ serveur_keycloak_realm }} \
|
|
-q type=org.keycloak.storage.UserStorageProvider \
|
|
--fields id,name --format csv --noquotes 2>/dev/null \
|
|
| awk -F, '$2 == "{{ serveur_keycloak_ldap_nom }}" {print $1}' | head -1)
|
|
if [ -n "$FEDID" ]; then
|
|
URL_ACTUELLE=$("$KC" get components/"$FEDID" -r {{ serveur_keycloak_realm }} 2>/dev/null \
|
|
| grep -o '"connectionUrl" : \[ "[^"]*"' | grep -o 'ldaps\?://[^"]*' | head -1)
|
|
if [ "$URL_ACTUELLE" != "{{ serveur_keycloak_ldap_url }}" ]; then
|
|
"$KC" update components/"$FEDID" -r {{ serveur_keycloak_realm }} \
|
|
-s 'config.connectionUrl=["{{ serveur_keycloak_ldap_url }}"]' \
|
|
-s 'config.usersDn=["{{ serveur_keycloak_ldap_users_dn }}"]' \
|
|
-s 'config.bindDn=["{{ serveur_keycloak_ldap_bind_dn }}"]' >/dev/null
|
|
CHANGED=1
|
|
fi
|
|
fi
|
|
if [ -z "$FEDID" ]; then
|
|
"$KC" create components -r {{ serveur_keycloak_realm }} \
|
|
-s name={{ serveur_keycloak_ldap_nom }} -s providerId=ldap \
|
|
-s providerType=org.keycloak.storage.UserStorageProvider -s parentId="$RID" \
|
|
-s 'config.enabled=["true"]' \
|
|
-s 'config.vendor=["other"]' \
|
|
-s 'config.editMode=["READ_ONLY"]' \
|
|
-s 'config.importEnabled=["true"]' \
|
|
-s 'config.connectionUrl=["{{ serveur_keycloak_ldap_url }}"]' \
|
|
-s 'config.usersDn=["{{ serveur_keycloak_ldap_users_dn }}"]' \
|
|
-s 'config.bindDn=["{{ serveur_keycloak_ldap_bind_dn }}"]' \
|
|
-s "config.bindCredential=[\"$LDAP_BIND_PW\"]" \
|
|
-s 'config.authType=["simple"]' \
|
|
-s 'config.searchScope=["2"]' \
|
|
-s 'config.usernameLDAPAttribute=["{{ serveur_keycloak_ldap_username_attr }}"]' \
|
|
-s 'config.rdnLDAPAttribute=["{{ serveur_keycloak_ldap_username_attr }}"]' \
|
|
-s 'config.uuidLDAPAttribute=["{{ serveur_keycloak_ldap_uuid_attr }}"]' \
|
|
-s 'config.userObjectClasses=["{{ serveur_keycloak_ldap_object_classes }}"]' \
|
|
-s 'config.useTruststoreSpi=["always"]' \
|
|
-s 'config.connectionPooling=["true"]' >/dev/null
|
|
CHANGED=1
|
|
fi
|
|
[ "$CHANGED" = 1 ] && echo SETOPS_CHANGED || echo SETOPS_OK
|
|
environment:
|
|
KC_ADMIN_PW: "{{ serveur_keycloak_admin_password }}"
|
|
LDAP_BIND_PW: "{{ serveur_keycloak_ldap_bind_password }}"
|
|
register: serveur_keycloak_fed
|
|
changed_when: "'SETOPS_CHANGED' in serveur_keycloak_fed.stdout"
|
|
no_log: true
|
|
retries: 5
|
|
delay: 6
|
|
until: serveur_keycloak_fed.rc == 0
|
|
when: not ansible_check_mode
|