Second defaut trouve par la reconstruction from-zero. groupes-ldap.yml attache grafana-admin a un groupe, mais c'est rbac-oidc.yml qui cree ce role — et il s'executait APRES. Invisible tant que le realm existait avec ses roles crees par un passage precedent ; sur un realm neuf, seuls les roles integres existaient et l'attachement echouait. Scinde plutot que deplace : rbac-oidc.yml fait trois choses aux dependances DISTINCTES — creer les roles (ne depend de rien), poser un mapper sur les clients (depend de clients-oidc), assigner des roles a des utilisateurs. Les melanger etait le defaut. L'ordre est desormais roles -> groupes -> clients -> mappers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
75 lines
3.4 KiB
YAML
75 lines
3.4 KiB
YAML
---
|
|
# RBAC OIDC : rôles de realm + mapper de rôles sur les clients concernés + assignations.
|
|
# Additif et idempotent (create-si-absent, kcadm à chaud — pas de restart Keycloak).
|
|
# Permet à une app (ex. Grafana) de mapper un rôle du realm vers son niveau de droit.
|
|
|
|
- name: Assurer le mapper de roles de realm sur les clients (claim 'roles')
|
|
ansible.builtin.shell:
|
|
executable: /bin/bash
|
|
cmd: |
|
|
set -euo pipefail
|
|
KC={{ serveur_keycloak_home }}/bin/kcadm.sh
|
|
"$KC" config credentials --server http://localhost:8080 --realm master \
|
|
--user {{ serveur_keycloak_admin_user }} --password "$KC_ADMIN_PW" >/dev/null
|
|
CID=$("$KC" get clients -r {{ serveur_keycloak_realm }} -q clientId={{ item }} 2>/dev/null \
|
|
| grep -oP '"id"\s*:\s*"\K[^"]+' | head -1)
|
|
if [ -z "$CID" ]; then echo "SETOPS_OK client absent"; exit 0; fi
|
|
if "$KC" get clients/$CID/protocol-mappers/models -r {{ serveur_keycloak_realm }} 2>/dev/null \
|
|
| grep -q '"realm-roles"'; then
|
|
echo SETOPS_OK
|
|
else
|
|
"$KC" create clients/$CID/protocol-mappers/models -r {{ serveur_keycloak_realm }} \
|
|
-s name=realm-roles -s protocol=openid-connect \
|
|
-s protocolMapper=oidc-usermodel-realm-role-mapper \
|
|
-s 'config."claim.name"=roles' \
|
|
-s 'config."jsonType.label"=String' \
|
|
-s 'config."multivalued"=true' \
|
|
-s 'config."id.token.claim"=true' \
|
|
-s 'config."access.token.claim"=true' \
|
|
-s 'config."userinfo.token.claim"=true' >/dev/null
|
|
echo SETOPS_CHANGED
|
|
fi
|
|
environment:
|
|
KC_ADMIN_PW: "{{ serveur_keycloak_admin_password }}"
|
|
loop: "{{ serveur_keycloak_role_mapper_clients }}"
|
|
register: serveur_keycloak_mapper_reg
|
|
changed_when: "'SETOPS_CHANGED' in serveur_keycloak_mapper_reg.stdout"
|
|
no_log: true
|
|
when:
|
|
- not ansible_check_mode
|
|
- serveur_keycloak_role_mapper_clients | length > 0
|
|
|
|
- name: Assigner les roles de realm aux utilisateurs (add-roles idempotent)
|
|
ansible.builtin.shell:
|
|
executable: /bin/bash
|
|
cmd: |
|
|
set -euo pipefail
|
|
KC={{ serveur_keycloak_home }}/bin/kcadm.sh
|
|
"$KC" config credentials --server http://localhost:8080 --realm master \
|
|
--user {{ serveur_keycloak_admin_user }} --password "$KC_ADMIN_PW" >/dev/null
|
|
# L'utilisateur doit exister dans le realm (Keycloak fédère LDAP à la demande).
|
|
# from-zero : l'annuaire peut être vide -> on n'échoue pas ; l'assignation
|
|
# s'appliquera quand l'utilisateur existera (synchro / 1re connexion).
|
|
if ! "$KC" get users -r {{ serveur_keycloak_realm }} -q username={{ item.user }} --fields username 2>/dev/null \
|
|
| grep -q '"{{ item.user }}"'; then
|
|
echo SETOPS_SKIP
|
|
exit 0
|
|
fi
|
|
if "$KC" get-roles -r {{ serveur_keycloak_realm }} --uusername {{ item.user }} 2>/dev/null \
|
|
| grep -q '"{{ item.role }}"'; then
|
|
echo SETOPS_OK
|
|
else
|
|
"$KC" add-roles -r {{ serveur_keycloak_realm }} --uusername {{ item.user }} --rolename {{ item.role }} >/dev/null
|
|
echo SETOPS_CHANGED
|
|
fi
|
|
environment:
|
|
KC_ADMIN_PW: "{{ serveur_keycloak_admin_password }}"
|
|
loop: "{{ serveur_keycloak_role_assignments }}"
|
|
loop_control:
|
|
label: "{{ item.user }} -> {{ item.role }}"
|
|
register: serveur_keycloak_assign_reg
|
|
changed_when: "'SETOPS_CHANGED' in serveur_keycloak_assign_reg.stdout"
|
|
no_log: true
|
|
when:
|
|
- not ansible_check_mode
|
|
- serveur_keycloak_role_assignments | length > 0
|