mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-10-10 02:38:10 +02:00
Introduce a confidential service-account client (Option A) to replace user-based kcadm sessions. The client is created automatically, granted realm-admin role, and used for all subsequent Keycloak updates. Includes improved error handling for HTTP 401 responses. Discussion: https://chatgpt.com/share/68e01da3-39fc-800f-81be-2d0c8efd81a1
63 lines
2.6 KiB
YAML
63 lines
2.6 KiB
YAML
# 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)) |