--- # Updates the LDAP provider's bind DN / password using kcadm.sh, idempotently. # Sources DN/password from group_vars/all/13_ldap.yml: # - DN: ldap.dn.administrator.data # - Password: ldap.bind_credential - name: "Assert required vars exist" assert: that: - keycloak_realm is defined - keycloak_server_host_url is defined - keycloak_server_internal_url is defined - keycloak_kcadm_path is defined - keycloak_master_api_user_name is defined - keycloak_master_api_user_password is defined - keycloak_ldap_component_name is defined - ldap is defined - ldap.dn.administrator.data is defined - ldap.bind_credential is defined fail_msg: "Missing Keycloak/LDAP vars. Ensure 13_ldap.yml is loaded and credentials are set." - name: "kcadm login (master)" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > {{ keycloak_kcadm_path }} config credentials --server {{ keycloak_server_internal_url }} --realm master --user {{ keycloak_master_api_user_name }} --password {{ keycloak_master_api_user_password }} changed_when: false # Resolve the LDAP component *by name* to avoid picking the wrong one. - name: "Resolve LDAP component id by name '{{ keycloak_ldap_component_name }}'" shell: > {{ keycloak_kcadm_path }} get components -r {{ keycloak_realm }} --query 'name={{ keycloak_ldap_component_name }}' --fields id,name,providerId,config --format json register: kc_ldap_list changed_when: false - name: "Validate that exactly one LDAP component matched" vars: parsed: "{{ kc_ldap_list.stdout | from_json }}" assert: that: - (parsed | length) == 1 fail_msg: >- Expected exactly one LDAP component named '{{ keycloak_ldap_component_name }}', found {{ (kc_ldap_list.stdout | from_json) | length }}. - name: "Extract LDAP component facts" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" set_fact: kc_ldap_component_id: "{{ (kc_ldap_list.stdout | from_json)[0].id }}" kc_ldap_current_bind_dn: "{{ ((kc_ldap_list.stdout | from_json)[0].config['bindDn'] | default(['']))[0] }}" kc_ldap_current_bind_pw: "{{ ((kc_ldap_list.stdout | from_json)[0].config['bindCredential'] | default(['']))[0] }}" - name: "Determine if update is required" set_fact: kc_needs_update: >- {{ (kc_ldap_current_bind_dn != ldap.dn.administrator.data) or (kc_ldap_current_bind_pw != ldap.bind_credential) }} - name: "Update LDAP bind DN / bind password" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > {{ keycloak_kcadm_path }} update components/{{ kc_ldap_component_id }} -r {{ keycloak_realm }} -s 'config.bindDn=["{{ ldap.dn.administrator.data | replace("'", "\\'") }}"]' -s 'config.bindCredential=["{{ ldap.bind_credential | replace("'", "\\'") }}"]' when: kc_needs_update | bool register: kc_bind_update - name: "LDAP bind credentials updated" debug: msg: "LDAP bind DN/password updated on component {{ keycloak_ldap_component_name }}." when: - kc_bind_update is defined - kc_bind_update.rc == 0