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
131 lines
4.4 KiB
YAML
131 lines
4.4 KiB
YAML
---
|
|
- name: "Load meta"
|
|
include_tasks: 01_meta.yml
|
|
when: not KEYCLOAK_LOAD_DEPENDENCIES | bool
|
|
|
|
- name: "Load cleanup routine for '{{ application_id }}'"
|
|
include_tasks: 02_cleanup.yml
|
|
|
|
- name: "Load init routine for '{{ application_id }}'"
|
|
include_tasks: 03_init.yml
|
|
|
|
- name: "Load the depdendencies required by '{{ application_id }}'"
|
|
include_tasks: 04_dependencies.yml
|
|
when: KEYCLOAK_LOAD_DEPENDENCIES | bool
|
|
|
|
- name: "Wait until '{{ KEYCLOAK_CONTAINER }}' container is healthy"
|
|
community.docker.docker_container_info:
|
|
name: "{{ KEYCLOAK_CONTAINER }}"
|
|
register: kc_info
|
|
retries: 60
|
|
delay: 5
|
|
until: >
|
|
kc_info is succeeded and
|
|
(kc_info.container | default({})) != {} and
|
|
(kc_info.container.State | default({})) != {} and
|
|
(kc_info.container.State.Health | default({})) != {} and
|
|
(kc_info.container.State.Health.Status | default('')) == 'healthy'
|
|
|
|
- name: kcadm login (master)
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
shell: >
|
|
{{ KEYCLOAK_EXEC_KCADM }} config credentials
|
|
--server {{ KEYCLOAK_SERVER_INTERNAL_URL }}
|
|
--realm master
|
|
--user {{ KEYCLOAK_MASTER_API_USER_NAME }}
|
|
--password {{ KEYCLOAK_MASTER_API_USER_PASSWORD }}
|
|
changed_when: false
|
|
|
|
- name: Verify kcadm session works (quick read)
|
|
shell: >
|
|
{{ KEYCLOAK_EXEC_KCADM }} get realms --format json | jq -r '.[0].realm' | head -n1
|
|
register: kcadm_verify
|
|
changed_when: false
|
|
failed_when: >
|
|
(kcadm_verify.rc != 0)
|
|
or ('HTTP 401' in (kcadm_verify.stderr | default('')))
|
|
or ((kcadm_verify.stdout | trim) == '')
|
|
|
|
# --- Create & grant automation service account (Option A) ---
|
|
- name: "Ensure automation service account client (Option A)"
|
|
include_tasks: 05a_service_account.yml
|
|
when: applications | get_app_conf(application_id, 'actions.create_automation_client', True)
|
|
|
|
# --- Switch session to the service account for all subsequent API work ---
|
|
- name: kcadm login (realm) using service account
|
|
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 }}
|
|
changed_when: false
|
|
|
|
- name: Verify kcadm session works (exact realm via service account)
|
|
shell: >
|
|
{{ KEYCLOAK_EXEC_KCADM }} get realms/{{ KEYCLOAK_REALM }} --format json | jq -r '.realm'
|
|
register: kcadm_verify_sa
|
|
changed_when: false
|
|
failed_when: >
|
|
(kcadm_verify_sa.rc != 0)
|
|
or ('HTTP 401' in (kcadm_verify_sa.stderr | default('')))
|
|
or ((kcadm_verify_sa.stdout | trim) != (KEYCLOAK_REALM | trim))
|
|
|
|
- name: "Update Client settings"
|
|
vars:
|
|
kc_object_kind: "client"
|
|
kc_lookup_value: "{{ KEYCLOAK_CLIENT_ID }}"
|
|
kc_desired: >-
|
|
{{
|
|
KEYCLOAK_DICTIONARY_REALM.clients
|
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
| list | first
|
|
}}
|
|
kc_force_attrs:
|
|
publicClient: >-
|
|
{{
|
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
| map(attribute='publicClient')
|
|
| first)
|
|
}}
|
|
serviceAccountsEnabled: >-
|
|
{{
|
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
| map(attribute='serviceAccountsEnabled')
|
|
| first )
|
|
}}
|
|
frontchannelLogout: >-
|
|
{{
|
|
(KEYCLOAK_DICTIONARY_REALM.clients
|
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
| map(attribute='frontchannelLogout')
|
|
| first)
|
|
}}
|
|
attributes: >-
|
|
{{
|
|
( (KEYCLOAK_DICTIONARY_REALM.clients
|
|
| selectattr('clientId','equalto', KEYCLOAK_CLIENT_ID)
|
|
| list | first | default({}) ).attributes | default({}) )
|
|
| combine({'frontchannel.logout.url': KEYCLOAK_FRONTCHANNEL_LOGOUT_URL}, recursive=True)
|
|
}}
|
|
include_tasks: _update.yml
|
|
|
|
- name: "Update REALM mail settings from realm dictionary (SPOT)"
|
|
include_tasks: _update.yml
|
|
vars:
|
|
kc_object_kind: "realm"
|
|
kc_lookup_field: "id"
|
|
kc_lookup_value: "{{ KEYCLOAK_REALM }}"
|
|
kc_desired:
|
|
smtpServer: "{{ KEYCLOAK_DICTIONARY_REALM.smtpServer | default({}, true) }}"
|
|
kc_merge_path: "smtpServer"
|
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
|
|
|
- include_tasks: 05_rbac_client_scope.yml
|
|
|
|
- include_tasks: 06_ldap.yml
|
|
when: KEYCLOAK_LDAP_ENABLED | bool
|