diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d71b46..de65d72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,4 +16,4 @@ jobs: with: fqcn: 'middleware_automation/keycloak' molecule_tests: >- - [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] + [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21ddc18..95b60ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,7 +24,7 @@ virtualenv $PATH_TO_DEV_VIRTUALENV # activate the virtual env source $PATH_TO_DEV_VIRTUALENV/bin/activate # install ansible and tools onto the virtualenv -pip install yamllint 'molecule>=6.0' 'molecule-plugins[docker]' 'ansible-core>=2.15' ansible-lint +pip install yamllint 'molecule>=6.0' 'molecule-plugins[docker]' 'ansible-core>=2.16' ansible-lint # install collection dependencies ansible-galaxy collection install -r requirements.yml # install python dependencies diff --git a/README.md b/README.md index e8c289e..9e9867d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Re ## Ansible version compatibility -This collection has been tested against following Ansible versions: **>=2.15.0**. +This collection has been tested against following Ansible versions: **>=2.16.0**. Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions. diff --git a/docs/requirements.txt b/docs/requirements.txt index c8f8e2d..303f3a6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,7 @@ antsibull>=0.17.0 antsibull-docs antsibull-changelog -ansible-core>=2.14.1 +ansible-core>=2.16.0 ansible-pygments sphinx-rtd-theme git+https://github.com/felixfontein/ansible-basic-sphinx-ext diff --git a/galaxy.yml b/galaxy.yml index a782353..76c46c4 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: middleware_automation name: keycloak -version: "2.4.3" +version: "3.0.0" readme: README.md authors: - Romain Pelisse diff --git a/meta/runtime.yml b/meta/runtime.yml index 1e85b01..49c7554 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -1,2 +1,2 @@ --- -requires_ansible: ">=2.15.0" +requires_ansible: ">=2.16.0" diff --git a/molecule/debian/converge.yml b/molecule/debian/converge.yml index 1a7d267..e853b38 100644 --- a/molecule/debian/converge.yml +++ b/molecule/debian/converge.yml @@ -3,16 +3,19 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: instance + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_start_dev: true keycloak_quarkus_proxy_mode: none roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_users: - username: TestUser password: password diff --git a/molecule/debian/prepare.yml b/molecule/debian/prepare.yml index 6025ef9..267386e 100644 --- a/molecule/debian/prepare.yml +++ b/molecule/debian/prepare.yml @@ -7,5 +7,6 @@ ansible.builtin.apt: name: - sudo + # - openjdk-21-jdk-headless # this is not available in ghcr.io/hspaans/molecule-containers:debian-11 (neither in debian-12) since the images are using outdated package sources - openjdk-17-jdk-headless state: present diff --git a/molecule/debian/verify.yml b/molecule/debian/verify.yml index 59bf483..863b820 100644 --- a/molecule/debian/verify.yml +++ b/molecule/debian/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}" keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}" keycloak_jboss_port_offset: 10 diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 417713f..de97748 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -3,9 +3,9 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: instance + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_log_level: debug keycloak_quarkus_log_target: /tmp/keycloak @@ -16,7 +16,10 @@ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_users: - username: TestUser password: password diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index c133eee..011c08e 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" provisioner: name: ansible config_options: diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml index 899dabd..eefd5cf 100644 --- a/molecule/default/prepare.yml +++ b/molecule/default/prepare.yml @@ -22,7 +22,7 @@ - name: Download keycloak archive to controller directory ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user - url: https://github.com/keycloak/keycloak/releases/download/24.0.5/keycloak-24.0.5.zip + url: https://github.com/keycloak/keycloak/releases/download/26.0.7/keycloak-26.0.7.zip dest: /tmp/keycloak mode: '0640' delegate_to: localhost diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index b880105..ae21396 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -2,7 +2,8 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_uri: "http://localhost:8080" tasks: - name: Populate service facts @@ -16,7 +17,7 @@ ansible.builtin.uri: url: "{{ keycloak_uri }}/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username={{ keycloak_quarkus_bootstrap_admin_user }}&password={{ keycloak_quarkus_bootstrap_admin_user }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/molecule/https_revproxy/converge.yml b/molecule/https_revproxy/converge.yml index b490721..92994fa 100644 --- a/molecule/https_revproxy/converge.yml +++ b/molecule/https_revproxy/converge.yml @@ -3,15 +3,14 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" - keycloak_realm: TestRealm - keycloak_quarkus_host: instance + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_hostname: https://proxy keycloak_quarkus_log: file keycloak_quarkus_http_enabled: True keycloak_quarkus_http_port: 8080 keycloak_quarkus_proxy_mode: edge keycloak_quarkus_http_relative_path: / - keycloak_quarkus_frontend_url: https://proxy/ + keycloak_quarkus_health_check_url: http://proxy:8080/realms/master/.well-known/openid-configuration roles: - role: keycloak_quarkus diff --git a/molecule/https_revproxy/molecule.yml b/molecule/https_revproxy/molecule.yml index 48bf375..7ad8db8 100644 --- a/molecule/https_revproxy/molecule.yml +++ b/molecule/https_revproxy/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" @@ -14,7 +14,7 @@ platforms: published_ports: - 0.0.0.0:8080:8080/tcp - name: proxy - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" diff --git a/molecule/overridexml/molecule.yml b/molecule/overridexml/molecule.yml index c133eee..011c08e 100644 --- a/molecule/overridexml/molecule.yml +++ b/molecule/overridexml/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" provisioner: name: ansible config_options: diff --git a/molecule/quarkus-devmode/converge.yml b/molecule/quarkus-devmode/converge.yml index 2e5d351..6c0b14f 100644 --- a/molecule/quarkus-devmode/converge.yml +++ b/molecule/quarkus-devmode/converge.yml @@ -3,18 +3,21 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm keycloak_quarkus_log: file - keycloak_quarkus_frontend_url: 'http://localhost:8080/' + keycloak_quarkus_hostname: 'http://localhost:8080' keycloak_quarkus_start_dev: True keycloak_quarkus_proxy_mode: none keycloak_quarkus_java_home: /opt/openjdk/ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: "{{ keycloak_quarkus_hostname }}" keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/molecule/quarkus-devmode/molecule.yml b/molecule/quarkus-devmode/molecule.yml index 191234d..2da7e01 100644 --- a/molecule/quarkus-devmode/molecule.yml +++ b/molecule/quarkus-devmode/molecule.yml @@ -3,15 +3,17 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" port_bindings: - "8080/tcp" - "8009/tcp" + - "9000/tcp" published_ports: - 0.0.0.0:8080:8080/tcp + - 0.0.0.0:9000:9000/TCP provisioner: name: ansible config_options: diff --git a/molecule/quarkus/converge.yml b/molecule/quarkus/converge.yml index 0860a42..b7c15e1 100644 --- a/molecule/quarkus/converge.yml +++ b/molecule/quarkus/converge.yml @@ -3,10 +3,10 @@ hosts: all vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" keycloak_realm: TestRealm - keycloak_quarkus_host: instance + keycloak_quarkus_hostname: https://instance:8443 keycloak_quarkus_log: file keycloak_quarkus_log_level: debug # needed for the verify step keycloak_quarkus_https_key_file_enabled: true @@ -22,6 +22,7 @@ keycloak_quarkus_systemd_wait_for_timeout: 20 keycloak_quarkus_systemd_wait_for_delay: 2 keycloak_quarkus_systemd_wait_for_log: true + keycloak_quarkus_restart_health_check: false # would fail because of self-signed cert keycloak_quarkus_providers: - id: http-client spi: connections @@ -37,7 +38,7 @@ repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4 group_id: org.keycloak artifact_id: keycloak-kerberos-federation - version: 24.0.5 # optional + version: 26.0.7 # optional # username: myUser # optional # password: myPAT # optional # - id: my-static-theme @@ -51,7 +52,10 @@ roles: - role: keycloak_quarkus - role: keycloak_realm + keycloak_url: http://instance:8080 keycloak_context: '' + keycloak_admin_user: "{{ keycloak_quarkus_bootstrap_admin_user }}" + keycloak_admin_password: "{{ keycloak_quarkus_bootstrap_admin_password }}" keycloak_client_default_roles: - TestRoleAdmin - TestRoleUser diff --git a/molecule/quarkus/molecule.yml b/molecule/quarkus/molecule.yml index c04e300..cf975e5 100644 --- a/molecule/quarkus/molecule.yml +++ b/molecule/quarkus/molecule.yml @@ -3,7 +3,7 @@ driver: name: docker platforms: - name: instance - image: registry.access.redhat.com/ubi8/ubi-init:latest + image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true privileged: true command: "/usr/sbin/init" @@ -11,6 +11,7 @@ platforms: - "8080/tcp" - "8443/tcp" - "8009/tcp" + - "9000/tcp" published_ports: - 0.0.0.0:8443:8443/tcp provisioner: @@ -30,6 +31,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PYTHONHTTPSVERIFY: 0 verifier: name: ansible scenario: diff --git a/molecule/quarkus/prepare.yml b/molecule/quarkus/prepare.yml index 21a0f30..d8ef369 100644 --- a/molecule/quarkus/prepare.yml +++ b/molecule/quarkus/prepare.yml @@ -24,7 +24,7 @@ - name: Make sure a jre is available (for keytool to prepare keystore) delegate_to: localhost ansible.builtin.package: - name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}" + name: "{{ 'java-21-openjdk-headless' if hera_home | length > 0 else 'openjdk-21-jdk-headless' }}" state: present become: true failed_when: false diff --git a/molecule/quarkus/verify.yml b/molecule/quarkus/verify.yml index 63769dc..1d9d2c3 100644 --- a/molecule/quarkus/verify.yml +++ b/molecule/quarkus/verify.yml @@ -2,7 +2,8 @@ - name: Verify hosts: all vars: - keycloak_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" tasks: - name: Populate service facts ansible.builtin.service_facts: @@ -35,10 +36,10 @@ - name: Verify endpoint URLs ansible.builtin.assert: that: - - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance/realms/master/protocol/openid-connect/ext/ciba/auth' - - (openid_config.stdout | from_json)['issuer'] == 'https://instance/realms/master' - - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth' - - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token' + - (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'https://instance:8443/realms/master/protocol/openid-connect/ext/ciba/auth' + - (openid_config.stdout | from_json)['issuer'] == 'https://instance:8443/realms/master' + - (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/auth' + - (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance:8443/realms/master/protocol/openid-connect/token' delegate_to: localhost - name: Check log folder @@ -91,7 +92,7 @@ ansible.builtin.uri: url: "https://instance:8443/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username={{ keycloak_quarkus_bootstrap_admin_user }}&password={{ keycloak_quarkus_bootstrap_admin_password}}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 @@ -101,8 +102,8 @@ - name: "Get Clients" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_clients @@ -113,15 +114,15 @@ - name: "Get Client {{ keycloak_client_uuid }}" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" register: keycloak_test_client - name: "Get Client roles" ansible.builtin.uri: url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles" + validate_certs: false headers: - validate_certs: false Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" - register: keycloak_test_client_roles \ No newline at end of file + register: keycloak_test_client_roles diff --git a/molecule/quarkus_ha/converge.yml b/molecule/quarkus_ha/converge.yml index 00246b8..fa5314f 100644 --- a/molecule/quarkus_ha/converge.yml +++ b/molecule/quarkus_ha/converge.yml @@ -3,10 +3,9 @@ hosts: keycloak vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_admin_password: "remembertochangeme" - keycloak_realm: TestRealm - keycloak_quarkus_host: "{{ inventory_hostname }}" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_user: "remembertochangeme" + keycloak_quarkus_hostname: "http://{{ inventory_hostname }}:8080" keycloak_quarkus_log: file keycloak_quarkus_log_level: info keycloak_quarkus_https_key_file_enabled: true @@ -25,6 +24,6 @@ keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_db_user: keycloak keycloak_quarkus_db_pass: mysecretpass - keycloak_quarkus_jdbc_url: jdbc:postgresql://postgres:5432/keycloak + keycloak_quarkus_db_url: jdbc:postgresql://postgres:5432/keycloak roles: - role: keycloak_quarkus diff --git a/molecule/quarkus_ha/molecule.yml b/molecule/quarkus_ha/molecule.yml index 8e07e0f..ed09971 100644 --- a/molecule/quarkus_ha/molecule.yml +++ b/molecule/quarkus_ha/molecule.yml @@ -14,6 +14,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" + - "9000/tcp" - name: instance2 image: registry.access.redhat.com/ubi9/ubi-init:latest pre_build_image: true @@ -26,6 +27,7 @@ platforms: port_bindings: - "8080/tcp" - "8443/tcp" + - "9000/tcp" - name: postgres image: ubuntu/postgres:14-22.04_beta pre_build_image: true @@ -63,6 +65,7 @@ provisioner: ansible_python_interpreter: "{{ ansible_playbook_python }}" env: ANSIBLE_FORCE_COLOR: "true" + PYTHONHTTPSVERIFY: 0 verifier: name: ansible scenario: diff --git a/molecule/quarkus_upgrade/converge.yml b/molecule/quarkus_upgrade/converge.yml index 6025b7c..9b57436 100644 --- a/molecule/quarkus_upgrade/converge.yml +++ b/molecule/quarkus_upgrade/converge.yml @@ -5,6 +5,6 @@ - vars.yml vars: keycloak_quarkus_show_deprecation_warnings: false - keycloak_quarkus_version: 24.0.3 + keycloak_quarkus_version: 26.0.7 roles: - role: keycloak_quarkus diff --git a/molecule/quarkus_upgrade/molecule.yml b/molecule/quarkus_upgrade/molecule.yml index 77f687f..21782e8 100644 --- a/molecule/quarkus_upgrade/molecule.yml +++ b/molecule/quarkus_upgrade/molecule.yml @@ -13,8 +13,10 @@ platforms: privileged: true port_bindings: - 8080:8080 + - "9000/tcp" published_ports: - 0.0.0.0:8080:8080/TCP + - 0.0.0.0:9000:9000/TCP provisioner: name: ansible playbooks: diff --git a/molecule/quarkus_upgrade/prepare.yml b/molecule/quarkus_upgrade/prepare.yml index bebfc68..a6892e3 100644 --- a/molecule/quarkus_upgrade/prepare.yml +++ b/molecule/quarkus_upgrade/prepare.yml @@ -5,7 +5,7 @@ - vars.yml vars: sudo_pkg_name: sudo - keycloak_quarkus_version: 23.0.7 + keycloak_quarkus_version: 24.0.5 pre_tasks: - name: Install sudo ansible.builtin.apt: diff --git a/molecule/quarkus_upgrade/vars.yml b/molecule/quarkus_upgrade/vars.yml index 81d56b5..1567ae4 100644 --- a/molecule/quarkus_upgrade/vars.yml +++ b/molecule/quarkus_upgrade/vars.yml @@ -1,9 +1,8 @@ --- keycloak_quarkus_offline_install: false -keycloak_quarkus_admin_password: "remembertochangeme" -keycloak_quarkus_admin_pass: "remembertochangeme" +keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_realm: TestRealm -keycloak_quarkus_host: instance +keycloak_quarkus_hostname: http://instance:8080 keycloak_quarkus_log: file keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_log_target: /tmp/keycloak diff --git a/molecule/quarkus_upgrade/verify.yml b/molecule/quarkus_upgrade/verify.yml index f5edfd0..1c4a0ba 100644 --- a/molecule/quarkus_upgrade/verify.yml +++ b/molecule/quarkus_upgrade/verify.yml @@ -2,7 +2,7 @@ - name: Verify hosts: instance vars: - keycloak_quarkus_admin_password: "remembertochangeme" + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" keycloak_quarkus_port: http://localhost:8080 tasks: - name: Populate service facts @@ -17,14 +17,14 @@ - name: Verify we are running on requested jvm ansible.builtin.shell: | set -eo pipefail - ps -ef | grep 'etc/alternatives/.*17' | grep -v grep + ps -ef | grep 'etc/alternatives/.*21' | grep -v grep changed_when: false - name: Verify token api call ansible.builtin.uri: url: "{{ keycloak_quarkus_port }}/realms/master/protocol/openid-connect/token" method: POST - body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_admin_password }}&grant_type=password" + body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_bootstrap_admin_password }}&grant_type=password" validate_certs: no register: keycloak_auth_response until: keycloak_auth_response.status == 200 diff --git a/playbooks/keycloak_quarkus.yml b/playbooks/keycloak_quarkus.yml index f2649a5..b8aedf2 100644 --- a/playbooks/keycloak_quarkus.yml +++ b/playbooks/keycloak_quarkus.yml @@ -2,8 +2,8 @@ - name: Playbook for Keycloak X Hosts with HTTPS enabled hosts: all vars: - keycloak_quarkus_admin_pass: "remembertochangeme" - keycloak_quarkus_host: localhost + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8443 keycloak_quarkus_log: file keycloak_quarkus_proxy_mode: none diff --git a/playbooks/keycloak_quarkus_dev.yml b/playbooks/keycloak_quarkus_dev.yml index 533db79..c8bb54e 100644 --- a/playbooks/keycloak_quarkus_dev.yml +++ b/playbooks/keycloak_quarkus_dev.yml @@ -2,8 +2,8 @@ - name: Playbook for Keycloak X Hosts in develop mode hosts: all vars: - keycloak_admin_password: "remembertochangeme" - keycloak_quarkus_host: localhost + keycloak_quarkus_bootstrap_admin_password: "remembertochangeme" + keycloak_quarkus_hostname: http://localhost keycloak_quarkus_port: 8080 keycloak_quarkus_log: file keycloak_quarkus_start_dev: true diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml index cfa9a3f..137111f 100644 --- a/roles/keycloak/defaults/main.yml +++ b/roles/keycloak/defaults/main.yml @@ -118,3 +118,7 @@ keycloak_no_log: true ### logging configuration keycloak_log_target: /var/log/keycloak + +# locations +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml index a27afb8..59499e6 100644 --- a/roles/keycloak/meta/main.yml +++ b/roles/keycloak/meta/main.yml @@ -12,7 +12,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL diff --git a/roles/keycloak/tasks/rhsso_cli.yml b/roles/keycloak/tasks/rhsso_cli.yml index fd41dd6..e40dec8 100644 --- a/roles/keycloak/tasks/rhsso_cli.yml +++ b/roles/keycloak/tasks/rhsso_cli.yml @@ -2,12 +2,12 @@ - name: Ensure required params for CLI have been provided ansible.builtin.assert: that: - - query is defined + - cli_query is defined fail_msg: "Missing required parameters to execute CLI." quiet: true -- name: "Execute CLI query: {{ query }}" +- name: "Execute CLI query: {{ cli_query }}" ansible.builtin.command: > - {{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} + {{ keycloak.cli_path }} --connect --command='{{ cli_query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} changed_when: false register: cli_result diff --git a/roles/keycloak/tasks/rhsso_patch.yml b/roles/keycloak/tasks/rhsso_patch.yml index e7ac3f0..23d75bf 100644 --- a/roles/keycloak/tasks/rhsso_patch.yml +++ b/roles/keycloak/tasks/rhsso_patch.yml @@ -106,7 +106,7 @@ - name: "Check installed patches" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch info" + cli_query: "patch info" args: apply: become: true @@ -121,7 +121,7 @@ - name: "Apply patch {{ patch_version }} to server" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch apply {{ patch_archive }}" + cli_query: "patch apply {{ patch_archive }}" args: apply: become: true @@ -130,7 +130,7 @@ - name: "Restart server to ensure patch content is running" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "shutdown --restart" + cli_query: "shutdown --restart" when: - cli_result.rc == 0 args: @@ -149,7 +149,7 @@ - name: "Query installed patch after restart" ansible.builtin.include_tasks: rhsso_cli.yml vars: - query: "patch info" + cli_query: "patch info" args: apply: become: true diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml index 7f7dfd1..fe706db 100644 --- a/roles/keycloak/vars/main.yml +++ b/roles/keycloak/vars/main.yml @@ -1,9 +1,6 @@ --- # internal variables below -# locations -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" keycloak: diff --git a/roles/keycloak_quarkus/README.md b/roles/keycloak_quarkus/README.md index 034c021..7f93a9f 100644 --- a/roles/keycloak_quarkus/README.md +++ b/roles/keycloak_quarkus/README.md @@ -33,7 +33,7 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_version`| keycloak.org package version | `24.0.5` | +|`keycloak_quarkus_version`| keycloak.org package version | `26.0.7` | |`keycloak_quarkus_offline_install` | Perform an offline install | `False`| |`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` | |`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` | @@ -44,45 +44,27 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_admin_user`| Administration console user account | `admin` | -|`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | -|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | -|`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` | -|`keycloak_quarkus_path`| This should be set if proxy uses a different context-path for Keycloak | | -|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | -|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | -|`keycloak_quarkus_ajp_port`| AJP port | `8009` | +|`keycloak_quarkus_bootstrap_admin_user`| Administration console user account | `admin` | +|`keycloak_quarkus_admin_user`| Deprecated, use `keycloak_quarkus_bootstrap_admin_user` instead. | | +|`keycloak_quarkus_bind_address`| Deprecated, use `keycloak_quarkus_http_host` instead | `0.0.0.0` | +|`keycloak_quarkus_host`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_port`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | |`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | -|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | +|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-21-openjdk-headless` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak | |`keycloak_quarkus_java_opts`| JVM arguments; if overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` | |`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` | -|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | -|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | -|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | -|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | -|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` | -|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | -|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | -|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | -|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | -|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| -|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | -|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` | -|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | -|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || -|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| -|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | -|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | -|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | -|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | -|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | +|`keycloak_quarkus_frontend_url`| Deprecated, use `keycloak_quarkus_hostname` instead. | | +|`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_hostname_admin` instead. | | +|`keycloak_quarkus_health_check_url`| Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default | `` | +|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property | `realms/master/.well-known/openid-configuration` | |`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` | |`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password != ''`, else `''` | |`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` | @@ -106,7 +88,7 @@ Role Defaults |`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` | |`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `true` | |`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` | -|`keycloak_quarkus_restart_health_check_reries`| Number of attempts for successful health check before failing | `25` | +|`keycloak_quarkus_restart_health_check_retries`| Number of attempts for successful health check before failing | `25` | |`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` | @@ -114,49 +96,67 @@ Role Defaults | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_hostname`| Address at which is the server exposed. Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. | | +|`keycloak_quarkus_hostname_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` | -|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | +|`keycloak_quarkus_hostname_backchannel_dynamic`| Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. | `false` | +|`keycloak_quarkus_hostname_strict_backchannel`| Deprecated, use (the inverted!)`keycloak_quarkus_hostname_backchannel_dynamic` instead. | | + + +#### HTTP(S) configuration +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_http_host`| The http host, ie. the address used to bind the service | `0.0.0.0` | +|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | +|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | +|`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` | +|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | +|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | +|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | +|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` | +|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` | +|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | +|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | +|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | +|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` | +|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`| +|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` | +|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` | +|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | +|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || +|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| +|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | +|`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` | +|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | #### Database configuration | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres,mssql] | `postgres` | +|`keycloak_quarkus_db_engine` | Database engine [mariadb,postres,mssql] | `postgres` | |`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` | |`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` | -|`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | -|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | +|`keycloak_quarkus_db_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` | +|`keycloak_quarkus_db_driver_version` | Version for JDBC engine driver | `9.4.1212` | -#### Remote caches configuration +#### Cache configuration | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` | -|`keycloak_quarkus_ispn_hosts` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | -|`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | -|`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` | -|`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` | -|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | +|`keycloak_quarkus_cache_remote_username` | Username for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_cache_remote_password` | Password for connecting to infinispan | `supervisor` | +|`keycloak_quarkus_cache_remote_host` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` | +|`keycloak_quarkus_cache_remote_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` | +|`keycloak_quarkus_cache_remote_tls_enabled` | Whether infinispan uses TLS connection | `false` | -#### Miscellaneous configuration +#### Logging configuration | Variable | Description | Default | |:---------|:------------|:--------| -|`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` | -|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints | `True` | -|`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` | -|`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` | -|`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` | -|`keycloak_quarkus_config_dir` | Path for configuration | `{{ keycloak_quarkus_home }}/conf` | -|`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` | -|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | -|`keycloak_force_install` | Remove pre-existing versions of service | `False` | -|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` | |`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` | |`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` | |`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` | @@ -165,6 +165,21 @@ Role Defaults |`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` | |`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` | |`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` | + + +#### Miscellaneous configuration + +| Variable | Description | Default | +|:---------|:------------|:--------| +|`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` | +|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints on the management interface | `True` | +|`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` | +|`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` | +|`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` | +|`keycloak_quarkus_config_dir` | Path for configuration | `{{ keycloak_quarkus_home }}/conf` | +|`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` | +|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` | +|`keycloak_force_install` | Remove pre-existing versions of service | `False` | |`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` | |`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | @@ -172,7 +187,7 @@ Role Defaults |`keycloak_quarkus_show_deprecation_warnings`| Whether deprecation warnings should be shown | `True` | -#### Vault SPI +#### Vault configuration | Variable | Description | Default | |:---------|:------------|:--------| @@ -200,7 +215,7 @@ keycloak_quarkus_providers: - id: http-client # required; "{{ id }}.jar" identifies the file name on RHBK spi: connections # required if neither url, local_path nor maven are specified; required for setting properties default: true # optional, whether to set default for spi, default false - restart: true # optional, whether to restart, default true + restart: true # optional, whether to rebuild config and restart the service after deploying, default true url: https://.../.../custom_spi.jar # optional, url for download via http local_path: my_theme_spi.jar # optional, path on local controller for SPI to be uploaded maven: # optional, for download using maven @@ -243,9 +258,8 @@ Role Variables | Variable | Description | Required | |:---------|:------------|----------| -|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | -|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | -|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | +|`keycloak_quarkus_bootstrap_admin_password`| Password of console admin account | `yes` | +|`keycloak_quarkus_admin_pass`| Deprecated, use `keycloak_quarkus_bootstrap_admin_password` instead. | | |`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` | |`keycloak_quarkus_alternate_download_url`| Alternate location with optional authentication for downloading RHBK | `no` | |`keycloak_quarkus_download_user`| Optional username for http authentication | `no*` | @@ -265,7 +279,7 @@ The role uses the following [custom facts](https://docs.ansible.com/ansible/late | Variable | Description | |:---------|:------------| -|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_admin_user[_pass]` gets created | +|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_bootstrap_admin_user[_password]` gets created | License ------- diff --git a/roles/keycloak_quarkus/defaults/main.yml b/roles/keycloak_quarkus/defaults/main.yml index 148d84d..7fefc5a 100644 --- a/roles/keycloak_quarkus/defaults/main.yml +++ b/roles/keycloak_quarkus/defaults/main.yml @@ -1,6 +1,6 @@ --- ### Configuration specific to keycloak -keycloak_quarkus_version: 24.0.5 +keycloak_quarkus_version: 26.0.7 keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" @@ -27,19 +27,17 @@ keycloak_quarkus_configure_firewalld: false keycloak_quarkus_configure_iptables: false ### administrator console password -keycloak_quarkus_admin_user: admin -keycloak_quarkus_admin_pass: +keycloak_quarkus_bootstrap_admin_user: admin +keycloak_quarkus_bootstrap_admin_password: keycloak_quarkus_master_realm: master ### Configuration settings -keycloak_quarkus_bind_address: 0.0.0.0 -keycloak_quarkus_host: localhost -keycloak_quarkus_port: -1 -keycloak_quarkus_path: +keycloak_quarkus_bind_address: 0.0.0.0 # deprecated use keycloak_quarkus_http_host +keycloak_quarkus_http_host: 0.0.0.0 keycloak_quarkus_http_enabled: true keycloak_quarkus_http_port: 8080 keycloak_quarkus_https_port: 8443 -keycloak_quarkus_ajp_port: 8009 +keycloak_quarkus_http_management_port: 9000 keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 @@ -81,8 +79,8 @@ keycloak_quarkus_systemd_wait_for_timeout: 60 keycloak_quarkus_systemd_wait_for_delay: 10 ### keycloak frontend url -keycloak_quarkus_frontend_url: -keycloak_quarkus_admin_url: +keycloak_quarkus_hostname: +keycloak_quarkus_hostname_admin: ### Set the path relative to / for serving resources. The path must start with a / ### (set to `/auth` for retrocompatibility with pre-quarkus releases) @@ -91,9 +89,9 @@ keycloak_quarkus_http_relative_path: / # Disables dynamically resolving the hostname from request headers. # Should always be set to true in production, unless proxy verifies the Host header. keycloak_quarkus_hostname_strict: true -# By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. -# If all applications use the public URL this option should be enabled. -keycloak_quarkus_hostname_strict_backchannel: false +# Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. +# Set to true if your application accesses Keycloak via a private network. If set to true, keycloak_quarkus_hostname option needs to be specified as a full URL. +keycloak_quarkus_hostname_backchannel_dynamic: false # The proxy headers that should be accepted by the server. ['', 'forwarded', 'xforwarded'] keycloak_quarkus_proxy_headers: "" @@ -122,12 +120,12 @@ keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts keycloak_quarkus_ispn_trust_store_password: changeit ### database backend engine: values [ 'postgres', 'mariadb' ] -keycloak_quarkus_jdbc_engine: postgres +keycloak_quarkus_db_engine: postgres ### database backend credentials keycloak_quarkus_db_user: keycloak-user keycloak_quarkus_db_pass: keycloak-pass -keycloak_quarkus_jdbc_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" -keycloak_quarkus_jdbc_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" +keycloak_quarkus_db_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}" +keycloak_quarkus_db_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}" # override the variables above, following defaults show minimum supported versions keycloak_quarkus_default_jdbc: postgres: @@ -138,9 +136,9 @@ keycloak_quarkus_default_jdbc: version: 2.7.4 mssql: url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' - version: 12.4.2 - driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.4.2.jre11/mssql-jdbc-12.4.2.jre11.jar" - # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver + version: 12.8.1 + driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.8.1.jre11/mssql-jdbc-12.8.1.jre11.jar" + # cf. https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/server_configuration_guide/index#db-installing-the-microsoft-sql-server-driver ### logging configuration keycloak_quarkus_log: file keycloak_quarkus_log_level: info @@ -165,5 +163,5 @@ keycloak_quarkus_supported_policy_types: ['password-blacklists'] keycloak_quarkus_restart_strategy: restart/serial.yml keycloak_quarkus_restart_health_check: true keycloak_quarkus_restart_health_check_delay: 10 -keycloak_quarkus_restart_health_check_reries: 25 +keycloak_quarkus_restart_health_check_retries: 25 keycloak_quarkus_restart_pause: 15 diff --git a/roles/keycloak_quarkus/handlers/main.yml b/roles/keycloak_quarkus/handlers/main.yml index 37d65c5..eec7789 100644 --- a/roles/keycloak_quarkus/handlers/main.yml +++ b/roles/keycloak_quarkus/handlers/main.yml @@ -1,4 +1,7 @@ --- +- name: "Invalidate {{ keycloak.service_name }} theme cache" + ansible.builtin.include_tasks: invalidate_theme_cache.yml + listen: "invalidate keycloak theme cache" # handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes - name: "Rebuild {{ keycloak.service_name }} config" ansible.builtin.include_tasks: rebuild_config.yml diff --git a/roles/keycloak_quarkus/meta/argument_specs.yml b/roles/keycloak_quarkus/meta/argument_specs.yml index 51fd6d8..51b0d1f 100644 --- a/roles/keycloak_quarkus/meta/argument_specs.yml +++ b/roles/keycloak_quarkus/meta/argument_specs.yml @@ -2,7 +2,7 @@ argument_specs: main: options: keycloak_quarkus_version: - default: "24.0.5" + default: "26.0.7" description: "keycloak.org package version" type: "str" keycloak_quarkus_archive: @@ -22,7 +22,7 @@ argument_specs: description: "Perform an offline install" type: "bool" keycloak_quarkus_jvm_package: - default: "java-11-openjdk-headless" + default: "java-21-openjdk-headless" description: "RHEL java package runtime" type: "str" keycloak_quarkus_java_home: @@ -68,13 +68,13 @@ argument_specs: default: "10s" description: "systemd RestartSec for service" type: "str" - keycloak_quarkus_admin_user: + keycloak_quarkus_bootstrap_admin_user: default: "admin" - description: "Administration console user account" + description: "Administration user account, only for bootstrapping" type: "str" - keycloak_quarkus_admin_pass: + keycloak_quarkus_bootstrap_admin_password: required: true - description: "Password of console admin account" + description: "Password of admin account, only for bootstrapping" type: "str" keycloak_quarkus_master_realm: default: "master" @@ -82,31 +82,40 @@ argument_specs: type: "str" keycloak_quarkus_bind_address: default: "0.0.0.0" - description: "Address for binding service ports" + description: "Deprecated, use `keycloak_quarkus_http_host`" + type: "str" + keycloak_quarkus_hostname: + description: >- + Address at which is the server exposed. + Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. type: "str" keycloak_quarkus_host: - default: "localhost" - description: "Hostname for the Keycloak server" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "str" keycloak_quarkus_port: - default: -1 - description: "The port used by the proxy when exposing the hostname" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "int" keycloak_quarkus_path: - required: false - description: "This should be set if proxy uses a different context-path for Keycloak" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." type: "str" keycloak_quarkus_http_enabled: default: true description: "Enable listener on HTTP port" type: "bool" + keycloak_quarkus_http_host: + default: '0.0.0.0' + description: "HTTP host, address for binding service ports" + type: "str" keycloak_quarkus_http_port: default: 8080 description: "HTTP port" type: "int" + keycloak_quarkus_health_check_url: + description: "Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default" + type: "str" keycloak_quarkus_health_check_url_path: default: "realms/master/.well-known/openid-configuration" - description: "Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically" + description: "Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property" type: "str" keycloak_quarkus_https_key_file_enabled: default: false @@ -182,9 +191,9 @@ argument_specs: default: 8443 description: "HTTPS port" type: "int" - keycloak_quarkus_ajp_port: - default: 8009 - description: "AJP port" + keycloak_quarkus_http_management_port: + default: 9000 + description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details." type: "int" keycloak_quarkus_jgroups_port: default: 7800 @@ -226,13 +235,21 @@ argument_specs: default: / description: "Set the path relative to / for serving resources. The path must start with a /" type: "str" + keycloak_quarkus_http_management_relative_path: + required: false + description: "Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details." + type: "str" keycloak_quarkus_frontend_url: required: false - description: "Service public URL" + description: "Deprecated in v26, use keycloak_quarkus_hostname instead." + type: "str" + keycloak_quarkus_hostname_admin: + required: false + description: "Service URL for the admin console" type: "str" keycloak_quarkus_admin_url: required: false - description: "Service URL for the admin console" + description: "Deprecated in v26, use keycloak_quarkus_hostname_admin instead." type: "str" keycloak_quarkus_metrics_enabled: default: false @@ -240,37 +257,29 @@ argument_specs: type: "bool" keycloak_quarkus_health_enabled: default: true - description: "If the server should expose health check endpoints" + description: "If the server should expose health check endpoints on the management interface" type: "bool" - keycloak_quarkus_ispn_user: + keycloak_quarkus_cache_remote_username: default: "supervisor" description: "Username for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_pass: + keycloak_quarkus_cache_remote_password: default: "supervisor" description: "Password for connecting to infinispan" type: "str" - keycloak_quarkus_ispn_hosts: + keycloak_quarkus_cache_remote_host: default: "localhost:11222" description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" type: "str" - keycloak_quarkus_ispn_sasl_mechanism: + keycloak_quarkus_cache_remote_sasl_mechanism: default: "SCRAM-SHA-512" description: "Infinispan auth mechanism" type: "str" - keycloak_quarkus_ispn_use_ssl: + keycloak_quarkus_cache_remote_tls_enabled: default: false description: "Whether infinispan uses TLS connection" type: "bool" - keycloak_quarkus_ispn_trust_store_path: - default: "/etc/pki/java/cacerts" - description: "Path to infinispan server trust certificate" - type: "str" - keycloak_quarkus_ispn_trust_store_password: - default: "changeit" - description: "Password for infinispan certificate keystore" - type: "str" - keycloak_quarkus_jdbc_engine: + keycloak_quarkus_db_engine: default: "postgres" description: "Database engine [mariadb,postres,mssql]" type: "str" @@ -282,12 +291,12 @@ argument_specs: default: "keycloak-pass" description: "Password for database connection" type: "str" - keycloak_quarkus_jdbc_url: - default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" + keycloak_quarkus_db_url: + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}" description: "JDBC URL for connecting to database" type: "str" - keycloak_quarkus_jdbc_driver_version: - default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" + keycloak_quarkus_db_driver_version: + default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}" description: "Version for JDBC driver" type: "str" keycloak_quarkus_log: @@ -348,24 +357,18 @@ argument_specs: description: > Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header. - keycloak_quarkus_hostname_strict_backchannel: + keycloak_quarkus_hostname_backchannel_dynamic: default: false type: "bool" description: > - By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all - applications use the public URL this option should be enabled. + Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. + Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: default: true type: "bool" description: > If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy - keycloak_quarkus_hostname_strict_https: - type: "bool" - required: false - description: > - By default, Keycloak requires running using TLS/HTTPS. If the service MUST run without TLS/HTTPS, then set - this option to "true" keycloak_quarkus_ks_vault_enabled: default: false type: "bool" @@ -453,7 +456,7 @@ argument_specs: description: "Seconds to let pass before starting healch checks" default: 10 type: 'int' - keycloak_quarkus_restart_health_check_reries: + keycloak_quarkus_restart_health_check_retries: description: "Number of attempts for successful health check before failing" default: 25 type: 'int' @@ -468,7 +471,7 @@ argument_specs: downstream: options: rhbk_version: - default: "24.0.3" + default: "26.0.7" description: "Red Hat Build of Keycloak version" type: "str" rhbk_archive: diff --git a/roles/keycloak_quarkus/meta/main.yml b/roles/keycloak_quarkus/meta/main.yml index 40a487f..65b5e50 100644 --- a/roles/keycloak_quarkus/meta/main.yml +++ b/roles/keycloak_quarkus/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL diff --git a/roles/keycloak_quarkus/tasks/deprecations.yml b/roles/keycloak_quarkus/tasks/deprecations.yml index 27ea6e3..0d370d5 100644 --- a/roles/keycloak_quarkus/tasks/deprecations.yml +++ b/roles/keycloak_quarkus/tasks/deprecations.yml @@ -49,5 +49,114 @@ notify: - print deprecation warning +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_frontend_url -> keycloak_quarkus_hostname + when: + - keycloak_quarkus_hostname is not defined + - keycloak_quarkus_frontend_url is defined + - keycloak_quarkus_frontend_url != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname: "{{ keycloak_quarkus_frontend_url }}" + deprecated_variable: "keycloak_quarkus_frontend_url" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_hostname_strict_https + keycloak_quarkus_host + keycloak_quarkus_port + keycloak_quarkus_path -> keycloak_quarkus_hostname + when: + - keycloak_quarkus_hostname is not defined + - keycloak_quarkus_hostname_strict_https is defined or keycloak_quarkus_frontend_url is defined or keycloak_quarkus_port is defined or keycloak_quarkus_path is defined + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname: >- + {% set protocol = '' %} + {% if keycloak_quarkus_hostname_strict_https %} + {% set protocol = 'https://' %} + {% elif keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is False %} + {% set protocol = 'http://' %} + {% endif %} + {{ protocol }}{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_port }}/{{ keycloak_quarkus_path }} + deprecated_variable: "keycloak_quarkus_hostname_strict_https or keycloak_quarkus_frontend_url or keycloak_quarkus_frontend_url or keycloak_quarkus_hostname" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_admin_url -> keycloak_quarkus_hostname_admin + when: + - keycloak_quarkus_hostname_admin is not defined + - keycloak_quarkus_admin_url is defined + - keycloak_quarkus_admin_url != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname_admin: "{{ keycloak_quarkus_admin_url }}" + deprecated_variable: "keycloak_quarkus_admin_url" # read in deprecation handler + notify: + - print deprecation warning + +# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options +- name: Check deprecation of keycloak_quarkus_hostname_strict_backchannel -> keycloak_quarkus_hostname_backchannel_dynamic + when: + - keycloak_quarkus_hostname_backchannel_dynamic is not defined + - keycloak_quarkus_hostname_strict_backchannel is defined + - keycloak_quarkus_hostname_strict_backchannel != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_hostname_backchannel_dynamic: "{{ keycloak_quarkus_hostname_strict_backchannel == False }}" + deprecated_variable: "keycloak_quarkus_hostname_backchannel_dynamic" # read in deprecation handler + notify: + - print deprecation warning + +# https://github.com/keycloak/keycloak/issues/30009 +- name: Check deprecation of keycloak_quarkus_admin_user -> keycloak_quarkus_bootstrap_admin_user + when: + - keycloak_quarkus_bootstrap_admin_user is not defined + - keycloak_quarkus_admin_user is defined + - keycloak_quarkus_admin_user != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_user }}" + deprecated_variable: "keycloak_quarkus_admin_user" # read in deprecation handler + notify: + - print deprecation warning + +# https://github.com/keycloak/keycloak/issues/30009 +- name: Check deprecation of keycloak_quarkus_admin_pass -> keycloak_quarkus_bootstrap_admin_password + when: + - keycloak_quarkus_bootstrap_admin_password is not defined + - keycloak_quarkus_admin_pass is defined + - keycloak_quarkus_admin_pass != '' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_pass }}" + deprecated_variable: "keycloak_quarkus_admin_pass" # read in deprecation handler + notify: + - print deprecation warning + +- name: Check deprecation of keycloak_quarkus_bind_address -> keycloak_quarkus_http_host + when: + - keycloak_quarkus_bind_address is defined + - keycloak_quarkus_bind_address != '0.0.0.0' + delegate_to: localhost + run_once: true + changed_when: keycloak_quarkus_show_deprecation_warnings + ansible.builtin.set_fact: + keycloak_quarkus_http_host: "{{ keycloak_quarkus_bind_address }}" + deprecated_variable: "keycloak_quarkus_bind_address" # read in deprecation handler + notify: + - print deprecation warning + - name: Flush handlers ansible.builtin.meta: flush_handlers diff --git a/roles/keycloak_quarkus/tasks/firewalld.yml b/roles/keycloak_quarkus/tasks/firewalld.yml index 2c3ef74..2d48124 100644 --- a/roles/keycloak_quarkus/tasks/firewalld.yml +++ b/roles/keycloak_quarkus/tasks/firewalld.yml @@ -12,7 +12,7 @@ enabled: true state: started -- name: "Configure firewall for {{ keycloak.service_name }} ports" +- name: "Configure firewall for {{ keycloak.service_name }} http port" become: true ansible.posix.firewalld: port: "{{ item }}" @@ -21,5 +21,16 @@ immediate: true loop: - "{{ keycloak_quarkus_http_port }}/tcp" + when: keycloak_quarkus_http_enabled | bool + +- name: "Configure firewall for {{ keycloak.service_name }} ports" + become: true + ansible.posix.firewalld: + port: "{{ item }}" + permanent: true + state: enabled + immediate: true + loop: - "{{ keycloak_quarkus_https_port }}/tcp" + - "{{ keycloak_quarkus_http_management_port }}/tcp" - "{{ keycloak_quarkus_jgroups_port }}/tcp" diff --git a/roles/keycloak_quarkus/tasks/install.yml b/roles/keycloak_quarkus/tasks/install.yml index 809e07e..c664d05 100644 --- a/roles/keycloak_quarkus/tasks/install.yml +++ b/roles/keycloak_quarkus/tasks/install.yml @@ -202,11 +202,11 @@ - keycloak_quarkus_cert_file_copy_enabled is defined and keycloak_quarkus_cert_file_copy_enabled - keycloak_quarkus_cert_file_src | length > 0 -- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" +- name: "Install {{ keycloak_quarkus_db_engine }} JDBC driver" ansible.builtin.include_tasks: jdbc_driver.yml when: - rhbk_enable is defined and rhbk_enable - - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined + - keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url is defined - name: "Download custom providers via http" ansible.builtin.get_url: @@ -218,7 +218,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.url is defined and item.url | length > 0 - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" # this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts - name: "Download custom providers to localhost using maven" @@ -235,7 +235,7 @@ loop: "{{ keycloak_quarkus_providers }}" when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" - notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}" + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: "Copy maven providers" ansible.builtin.copy: @@ -249,7 +249,7 @@ when: item.maven is defined no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}" -- name: "Copy providers" +- name: "Copy local providers" ansible.builtin.copy: src: "{{ item.local_path }}" dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar" @@ -259,6 +259,7 @@ become: true loop: "{{ keycloak_quarkus_providers }}" when: item.local_path is defined + notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}" - name: Ensure required folder structure for policies exists ansible.builtin.file: diff --git a/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml b/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml new file mode 100644 index 0000000..90ff67f --- /dev/null +++ b/roles/keycloak_quarkus/tasks/invalidate_theme_cache.yml @@ -0,0 +1,11 @@ +--- +# From https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/24.0/html/server_developer_guide/themes#creating_a_theme: +# If you want to manually delete the content of the themes cache, +# you can do so by deleting the data/tmp/kc-gzip-cache directory of the server distribution +# It can be useful for instance if you redeployed custom providers or custom themes without +# disabling themes caching in the previous server executions. +- name: "Delete {{ keycloak.service_name }} theme cache directory" + ansible.builtin.file: + path: "{{ keycloak.home }}/data/tmp/kc-gzip-cache" + state: absent + become: true diff --git a/roles/keycloak_quarkus/tasks/jdbc_driver.yml b/roles/keycloak_quarkus/tasks/jdbc_driver.yml index 880a915..ba3f4b8 100644 --- a/roles/keycloak_quarkus/tasks/jdbc_driver.yml +++ b/roles/keycloak_quarkus/tasks/jdbc_driver.yml @@ -7,9 +7,9 @@ (keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or (keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined) -- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" +- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}" ansible.builtin.get_url: - url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" + url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}" dest: "{{ keycloak.home }}/providers" owner: "{{ keycloak.service_user }}" group: "{{ keycloak.service_group }}" diff --git a/roles/keycloak_quarkus/tasks/main.yml b/roles/keycloak_quarkus/tasks/main.yml index bb86b2c..cca6764 100644 --- a/roles/keycloak_quarkus/tasks/main.yml +++ b/roles/keycloak_quarkus/tasks/main.yml @@ -91,7 +91,7 @@ register: keycloak_service_status changed_when: false -- name: "Notify to remove `keycloak_quarkus_admin_user[_pass]` env vars" +- name: "Notify to remove `keycloak_quarkus_bootstrap_admin_user[_password]` env vars" when: - not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution - keycloak_service_status.status.ActiveState == "active" # but it is now diff --git a/roles/keycloak_quarkus/tasks/prereqs.yml b/roles/keycloak_quarkus/tasks/prereqs.yml index 0835aab..9b633f3 100644 --- a/roles/keycloak_quarkus/tasks/prereqs.yml +++ b/roles/keycloak_quarkus/tasks/prereqs.yml @@ -2,12 +2,12 @@ - name: Validate admin console password ansible.builtin.assert: that: - - keycloak_quarkus_admin_pass | length > 12 + - keycloak_quarkus_bootstrap_admin_password | length > 12 quiet: true - fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass to a 12+ char long string" + fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_bootstrap_admin_password to a 12+ char long string" success_msg: "{{ 'Console administrator password OK' }}" -- name: Validate relative path +- name: Validate http_relative_path ansible.builtin.assert: that: - keycloak_quarkus_http_relative_path is regex('^/.*') @@ -15,6 +15,15 @@ fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /" success_msg: "{{ 'Relative path OK' }}" +- name: Validate http_management_relative_path + ansible.builtin.assert: + that: + - keycloak_quarkus_http_management_relative_path is regex('^/.*') + quiet: true + fail_msg: "The relative path for keycloak_quarkus_http_management_relative_path must begin with /" + success_msg: "{{ 'Relative mgmt path OK' }}" + when: keycloak_quarkus_http_management_relative_path is defined + - name: Validate configuration ansible.builtin.assert: that: diff --git a/roles/keycloak_quarkus/tasks/restart.yml b/roles/keycloak_quarkus/tasks/restart.yml index 61356d5..3aa97f6 100644 --- a/roles/keycloak_quarkus/tasks/restart.yml +++ b/roles/keycloak_quarkus/tasks/restart.yml @@ -12,7 +12,7 @@ url: "{{ keycloak.health_url }}" register: keycloak_status until: keycloak_status.status == 200 - retries: "{{ keycloak_quarkus_restart_health_check_reries }}" + retries: "{{ keycloak_quarkus_restart_health_check_retries }}" delay: "{{ keycloak_quarkus_restart_health_check_delay }}" when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) diff --git a/roles/keycloak_quarkus/tasks/start.yml b/roles/keycloak_quarkus/tasks/start.yml index a640e89..5a3ad5f 100644 --- a/roles/keycloak_quarkus/tasks/start.yml +++ b/roles/keycloak_quarkus/tasks/start.yml @@ -14,3 +14,4 @@ until: keycloak_status.status == 200 retries: 25 delay: 10 + when: internal_force_health_check | default(keycloak_quarkus_restart_health_check) diff --git a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 index fb11cda..e546ab8 100644 --- a/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 +++ b/roles/keycloak_quarkus/templates/cache-ispn.xml.j2 @@ -18,15 +18,15 @@ + xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd" + xmlns="urn:infinispan:config:15.0"> {% set stack_expression='' %} {% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %} {% set stack_expression='stack="tcpping"' %} - + + + + + @@ -98,4 +102,4 @@ - \ No newline at end of file + diff --git a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 index 2c260a3..244d9aa 100644 --- a/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 +++ b/roles/keycloak_quarkus/templates/keycloak-sysconfig.j2 @@ -1,7 +1,7 @@ {{ ansible_managed | comment }} {% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %} -KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} -KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' +KC_BOOTSTRAP_ADMIN_USERNAME={{ keycloak_quarkus_bootstrap_admin_user }} +KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}' {% else %} {{ keycloak.bootstrap_mnemonic }} {% endif %} diff --git a/roles/keycloak_quarkus/templates/keycloak.conf.j2 b/roles/keycloak_quarkus/templates/keycloak.conf.j2 index ab4024b..99790c3 100644 --- a/roles/keycloak_quarkus/templates/keycloak.conf.j2 +++ b/roles/keycloak_quarkus/templates/keycloak.conf.j2 @@ -2,26 +2,18 @@ {% if keycloak_quarkus_db_enabled %} # Database -db={{ keycloak_quarkus_jdbc_engine }} -db-url={{ keycloak_quarkus_jdbc_url }} +db={{ keycloak_quarkus_db_engine }} +db-url={{ keycloak_quarkus_db_url }} db-username={{ keycloak_quarkus_db_user }} {% if not keycloak.config_key_store_enabled %} db-password={{ keycloak_quarkus_db_pass }} {% endif %} {% endif %} -{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas true -%} -hostname-strict-https=true -{% endif -%} -{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas false -%} -hostname-strict-https=false -{% endif -%} - {% if keycloak.config_key_store_enabled %} # Config store config-keystore={{ keycloak_quarkus_config_key_store_file }} config-keystore-password={{ keycloak_quarkus_config_key_store_password }} -config-keystore-type=PKCS12 {% endif %} # Observability @@ -30,8 +22,17 @@ health-enabled={{ keycloak_quarkus_health_enabled | lower }} # HTTP http-enabled={{ keycloak_quarkus_http_enabled | lower }} +{% if keycloak_quarkus_http_enabled %} http-port={{ keycloak_quarkus_http_port }} +{% endif %} http-relative-path={{ keycloak_quarkus_http_relative_path }} +http-host={{ keycloak_quarkus_http_host }} + +# Management +http-management-port={{ keycloak_quarkus_http_management_port }} +{% if keycloak_quarkus_http_management_relative_path is defined and keycloak_quarkus_http_management_relative_path | length > 0 %} +http-management-relative-path={{ keycloak_quarkus_http_management_relative_path }} +{% endif %} # HTTPS https-port={{ keycloak_quarkus_https_port }} @@ -49,16 +50,10 @@ https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }} {% endif %} # Client URL configuration -{% if keycloak_quarkus_frontend_url %} -hostname-url={{ keycloak_quarkus_frontend_url }} -{% else %} -hostname={{ keycloak_quarkus_host }} -hostname-port={{ keycloak_quarkus_port }} -hostname-path={{ keycloak_quarkus_path }} -{% endif %} -hostname-admin-url={{ keycloak_quarkus_admin_url }} +hostname={{ keycloak_quarkus_hostname }} +hostname-admin={{ keycloak_quarkus_hostname_admin }} hostname-strict={{ keycloak_quarkus_hostname_strict | lower }} -hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lower }} +hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | lower }} # Cluster {% if keycloak_quarkus_ha_enabled %} diff --git a/roles/keycloak_quarkus/vars/main.yml b/roles/keycloak_quarkus/vars/main.yml index e59af55..997d7dc 100644 --- a/roles/keycloak_quarkus/vars/main.yml +++ b/roles/keycloak_quarkus/vars/main.yml @@ -4,8 +4,7 @@ keycloak: # noqa var-naming this is an internal dict of interpolated values config_dir: "{{ keycloak_quarkus_config_dir }}" bundle: "{{ keycloak_quarkus_archive }}" service_name: "keycloak" - health_url: "{{ 'https' if keycloak_quarkus_http_enabled == False else 'http' }}://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_https_port if keycloak_quarkus_http_enabled == False else keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ - if keycloak_quarkus_http_relative_path | length > 1 else '' }}{{ keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration') }}" + health_url: "{{ keycloak_quarkus_health_check_url | default(keycloak_quarkus_hostname ~ '/' ~ (keycloak_quarkus_health_check_url_path | default('realms/master/.well-known/openid-configuration'))) }}" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" service_user: "{{ keycloak_quarkus_service_user }}" service_group: "{{ keycloak_quarkus_service_group }}" diff --git a/roles/keycloak_quarkus/vars/redhat.yml b/roles/keycloak_quarkus/vars/redhat.yml index c311321..9af167f 100644 --- a/roles/keycloak_quarkus/vars/redhat.yml +++ b/roles/keycloak_quarkus/vars/redhat.yml @@ -1,5 +1,5 @@ --- -keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-17-openjdk-headless') }}" +keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-21-openjdk-headless') }}" keycloak_quarkus_prereq_package_list: - "{{ keycloak_quarkus_varjvm_package }}" - unzip diff --git a/roles/keycloak_realm/defaults/main.yml b/roles/keycloak_realm/defaults/main.yml index b9e1e45..a294cbe 100644 --- a/roles/keycloak_realm/defaults/main.yml +++ b/roles/keycloak_realm/defaults/main.yml @@ -54,3 +54,7 @@ keycloak_client_users: [] ### List of Keycloak User Federation keycloak_user_federation: [] + +# other settings +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}" diff --git a/roles/keycloak_realm/meta/main.yml b/roles/keycloak_realm/meta/main.yml index ab861ed..97c69d2 100644 --- a/roles/keycloak_realm/meta/main.yml +++ b/roles/keycloak_realm/meta/main.yml @@ -8,7 +8,7 @@ galaxy_info: license: Apache License 2.0 - min_ansible_version: "2.15" + min_ansible_version: "2.16" platforms: - name: EL diff --git a/roles/keycloak_realm/tasks/main.yml b/roles/keycloak_realm/tasks/main.yml index 962016c..7595ba3 100644 --- a/roles/keycloak_realm/tasks/main.yml +++ b/roles/keycloak_realm/tasks/main.yml @@ -15,6 +15,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}" method: GET + validate_certs: false status_code: - 200 - 404 @@ -110,3 +111,6 @@ loop_control: loop_var: client when: "'users' in client" + +- name: Provide Access token lifespan + ansible.builtin.include_tasks: manage_token_lifespan.yml diff --git a/roles/keycloak_realm/tasks/manage_token_lifespan.yml b/roles/keycloak_realm/tasks/manage_token_lifespan.yml new file mode 100644 index 0000000..f16b938 --- /dev/null +++ b/roles/keycloak_realm/tasks/manage_token_lifespan.yml @@ -0,0 +1,14 @@ +--- +- name: "Update Access token lifespan" + ansible.builtin.uri: + url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}" + method: PUT + body: + accessTokenLifespan: 300 + validate_certs: false + body_format: json + status_code: + - 200 + - 204 + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" diff --git a/roles/keycloak_realm/tasks/manage_user_client_roles.yml b/roles/keycloak_realm/tasks/manage_user_client_roles.yml index 3884f42..f9e0329 100644 --- a/roles/keycloak_realm/tasks/manage_user_client_roles.yml +++ b/roles/keycloak_realm/tasks/manage_user_client_roles.yml @@ -3,6 +3,7 @@ ansible.builtin.uri: url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}" method: GET + validate_certs: false status_code: - 200 headers: @@ -16,6 +17,7 @@ default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \ selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" method: GET + validate_certs: false status_code: - 200 headers: diff --git a/roles/keycloak_realm/vars/main.yml b/roles/keycloak_realm/vars/main.yml index 7664f8c..ad9bd8e 100644 --- a/roles/keycloak_realm/vars/main.yml +++ b/roles/keycloak_realm/vars/main.yml @@ -3,7 +3,3 @@ # name of the realm to create, this is a required variable keycloak_realm: - -# other settings -keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}" -keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}"