# Creates a confidential client with service account, fetches the secret, # and grants realm-management/realm-admin to its service-account user. - name: "Ensure automation client exists (confidential + service accounts)" shell: | {{ KEYCLOAK_EXEC_KCADM }} create clients -r {{ KEYCLOAK_REALM }} \ -s clientId={{ KEYCLOAK_AUTOMATION_CLIENT_ID }} \ -s protocol=openid-connect \ -s publicClient=false \ -s serviceAccountsEnabled=true \ -s directAccessGrantsEnabled=false register: create_client changed_when: create_client.rc == 0 failed_when: create_client.rc != 0 and ('already exists' not in (create_client.stderr | lower)) - name: "Resolve automation client id" shell: > {{ KEYCLOAK_EXEC_KCADM }} get clients -r {{ KEYCLOAK_REALM }} --query 'clientId={{ KEYCLOAK_AUTOMATION_CLIENT_ID }}' --fields id --format json | jq -r '.[0].id' register: auto_client_id_cmd changed_when: false - name: "Fail if client id could not be resolved" assert: that: - "(auto_client_id_cmd.stdout | trim) is match('^[0-9a-f-]+$')" fail_msg: "Automation client id could not be resolved." - name: "Read client secret" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > {{ KEYCLOAK_EXEC_KCADM }} get clients/{{ auto_client_id_cmd.stdout | trim }}/client-secret -r {{ KEYCLOAK_REALM }} --format json | jq -r .value register: auto_client_secret_cmd changed_when: false - name: "Expose client secret as a fact" set_fact: KEYCLOAK_AUTOMATION_CLIENT_SECRET: "{{ auto_client_secret_cmd.stdout | trim }}" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" - name: "Grant {{ KEYCLOAK_AUTOMATION_GRANT_ROLE }} to service account" shell: > {{ KEYCLOAK_EXEC_KCADM }} add-roles -r {{ KEYCLOAK_REALM }} --uusername service-account-{{ KEYCLOAK_AUTOMATION_CLIENT_ID }} --cclientid realm-management --rolename {{ KEYCLOAK_AUTOMATION_GRANT_ROLE }} register: grant_role changed_when: grant_role.rc == 0 failed_when: grant_role.rc != 0 and ('already exists' not in (grant_role.stderr | lower)) - name: "Verify client-credentials login works" no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" shell: > {{ KEYCLOAK_EXEC_KCADM }} config credentials --server {{ KEYCLOAK_SERVER_INTERNAL_URL }} --realm {{ KEYCLOAK_REALM }} --client {{ KEYCLOAK_AUTOMATION_CLIENT_ID }} --client-secret {{ KEYCLOAK_AUTOMATION_CLIENT_SECRET }} && {{ KEYCLOAK_EXEC_KCADM }} get realms/{{ KEYCLOAK_REALM }} --format json | jq -r '.realm' register: verify_cc changed_when: false failed_when: (verify_cc.rc != 0) or ((verify_cc.stdout | trim) != (KEYCLOAK_REALM | trim))