diff --git a/README.md b/README.md index 02ef98c..46d7353 100644 --- a/README.md +++ b/README.md @@ -9,17 +9,69 @@ Role Variables The most important variables are listed below: ``` yaml -keycloak_major_version: '10' +keycloak_major_version: '19' keycloak_minor_version: '0' keycloak_point_version: '2' +keycloak_openjdk_runtime_version: 11 +keycloak_openjdk_version: + - '{{ keycloak_openjdk_runtime_version }}' +keycloak_openjdk_bin: '/usr/lib/jvm/java-{{ keycloak_openjdk_runtime_version}}-openjdk-amd64/bin/java' keycloak_install_dir: '/opt/keycloak' +keycloak_distribution_data_directory: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}' +keycloak_conf_directory: '{{ keycloak_runtime_home }}/conf' +keycloak_providers_directory: '{{ keycloak_runtime_home }}/providers' +keycloak_data_directory: '{{ keycloak_runtime_home }}/data' keycloak_log_directory: '/var/log/keycloak' -# domain clustered mode is not supported at this time -keycloak_wildfly_mode: 'standalone' -keycloak_wildfly_clustered: False +keycloak_optimize_build_at_startup: true +keycloak_upgrade_db_at_startup: false +keycloak_disabled_features: [] +keycloak_preview_features: [] + +keycloak_external_avatar_dir_enabled: false +keycloak_external_avatar_dir: '{{ keycloak_data_directory }}/avatar' + +keycloak_https_enabled: true +keycloak_https_protocols: 'TLSv1.3' +keycloak_letsencrypt_certs: '{{ keycloak_https_enabled }}' +keycloak_http_enabled: "{% if keycloak_https_enabled %}'false'{% else %}'true'{% endif %}" keycloak_listen: '127.0.0.1' -keycloak_java_min_heap: '2048m' -keycloak_java_max_heap: '{{ keycloak_java_min_heap }}' +keycloak_http_port: 8080 +keycloak_https_port: 8443 +keycloak_set_hostname: false +keycloak_hostname: '{{ ansible_fqdn }}' + +keycloak_log_handlers: console +keycloak_log_console_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_log_console_output: default +keycloak_log_file: '{{ keycloak_log_directory }}/keycloak.log' +keycloak_log_file_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_log_level: warning +# We keep those together because some health checks are available only when the metrics are enabled. +keycloak_metrics_and_health_checks_enabled: 'true' + +keycloak_use_external_db: true +# postgresql is the only supported choice for the time being +keycloak_db_vendor: 'postgres' +keycloak_database_name: keycloak +keycloak_database_user: keycloak_u +# keycloak_database_password: 'define it into a vault file' +keycloak_database_host: 'localhost' +keycloak_database_max_pool_size: '50' +keycloak_database_jboss_connection_checker: true +keycloak_database_idle_timeouts_min: 1 +keycloak_admin_user: kadmin +# keycloak_admin_password: 'define it into a vault file' + +keycloak_before_nginx: false +keycloak_before_apache_httpd: false +keycloak_behind_reverse_proxy: true +keycloak_reverse_proxy_type: '{% if keycloak_local_certs %}reencrypt{% else %}edge{% endif %}' +keycloak_reverse_proxy_infinispan_attach_route: 'true' + +keycloak_cluster: false +keycloak_cache_type: ispn +keycloak_cache_stack: tcp +keycloak_cache_container_name: keycloak ``` Dependencies diff --git a/defaults/main.yml b/defaults/main.yml index c68112c..59f37cf 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,39 +1,55 @@ --- -keycloak_major_version: '10' +keycloak_major_version: '19' keycloak_minor_version: '0' keycloak_point_version: '2' -keycloak_wildfly_mode: 'standalone' +keycloak_openjdk_runtime_version: 11 +keycloak_openjdk_version: + - '{{ keycloak_openjdk_runtime_version }}' +keycloak_openjdk_bin: '/usr/lib/jvm/java-{{ keycloak_openjdk_runtime_version}}-openjdk-amd64/bin/java' keycloak_install_dir: '/opt/keycloak' -keycloak_properties_directory: '/opt/keycloak/properties' keycloak_distribution_data_directory: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}' -keycloak_data_directory: '/opt/keycloak_data' +keycloak_conf_directory: '{{ keycloak_runtime_home }}/conf' +keycloak_providers_directory: '{{ keycloak_runtime_home }}/providers' +keycloak_data_directory: '{{ keycloak_runtime_home }}/data' keycloak_log_directory: '/var/log/keycloak' -keycloak_startup_properties: - - name: 'jboss.server.data.dir' - value: '{{ keycloak_data_directory }}' - - name: 'jboss.server.log.dir' - value: '{{ keycloak_log_directory }}' -# domain clustered mode is not supported at this time -keycloak_wildfly_clustered: False -keycloak_wildfly_cluster_node_name: '{{ ansible_hostname }}' -keycloak_wildfly_cluster_private_bind_address: '{{ ansible_default_ipv4.address }}' -keycloak_wildfly_mping_multicast_address: '230.0.0.4' -keycloak_wildfly_jgroups_udp_multicast_address: '230.0.0.4' -keycloak_wildfly_modcluster_multicast_address: '224.0.1.105' +keycloak_optimize_build_at_startup: true +keycloak_upgrade_db_at_startup: false +keycloak_disabled_features: [] +keycloak_preview_features: [] +keycloak_remote_providers: [] + # - name: 'foo' + # state: 'present' + # maven_repo_url: '' + # maven_id: '' + # maven_group_id: '' + # maven_extension: '' + # maven_version: '' + +keycloak_external_avatar_dir_enabled: false +keycloak_external_avatar_dir: '{{ keycloak_data_directory }}/avatar' + +keycloak_https_enabled: true +keycloak_https_protocols: 'TLSv1.3' +keycloak_letsencrypt_certs: '{{ keycloak_https_enabled }}' +keycloak_http_enabled: "{% if keycloak_https_enabled %}'false'{% else %}'true'{% endif %}" keycloak_listen: '127.0.0.1' -keycloak_java_min_heap: '2048m' -keycloak_java_max_heap: '{{ keycloak_java_min_heap }}' -keycloak_node_identifier: 1 +keycloak_http_port: 8080 +keycloak_https_port: 8443 +keycloak_set_hostname: false +keycloak_hostname: '{{ ansible_fqdn }}' + +keycloak_log_handlers: console +keycloak_log_console_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_log_console_output: default +keycloak_log_file: '{{ keycloak_log_directory }}/keycloak.log' +keycloak_log_file_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n' +keycloak_log_level: warning +# We keep those together because some health checks are available only when the metrics are enabled. +keycloak_metrics_and_health_checks_enabled: 'true' keycloak_use_external_db: true # postgresql is the only supported choice for the time being -keycloak_db: 'postgresql' -keycloak_db_module_name: 'org.{{ keycloak_db }}' -keycloak_db_module_path: 'org/{{ keycloak_db }}' -keycloak_db_class_name: '{{ keycloak_db_module_name }}.xa.PGXADataSource' -keycloak_jdbc_driver_version: '42.2.14' -keycloak_jdbc_driver: 'postgresql-{{ keycloak_jdbc_driver_version }}.jar' -keycloak_jdbc_driver_url: 'https://jdbc.postgresql.org/download/{{ keycloak_jdbc_driver }}' +keycloak_db_vendor: 'postgres' keycloak_database_name: keycloak keycloak_database_user: keycloak_u # keycloak_database_password: 'define it into a vault file' @@ -44,6 +60,13 @@ keycloak_database_idle_timeouts_min: 1 keycloak_admin_user: kadmin # keycloak_admin_password: 'define it into a vault file' +keycloak_before_nginx: false +keycloak_before_apache_httpd: false keycloak_behind_reverse_proxy: true +keycloak_reverse_proxy_type: '{% if keycloak_local_certs %}reencrypt{% else %}edge{% endif %}' +keycloak_reverse_proxy_infinispan_attach_route: 'true' -keycloak_jcliff_version: '2.12.7' +keycloak_cluster: false +keycloak_cache_type: ispn +keycloak_cache_stack: tcp +keycloak_cache_container_name: keycloak diff --git a/meta/main.yml b/meta/main.yml index 1fbbcba..f8c4f83 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -16,10 +16,13 @@ galaxy_info: - name: Ubuntu versions: - bionic + - focal + - jammy - name: EL versions: - 7 - 8 + - 9 galaxy_tags: - users @@ -32,10 +35,3 @@ dependencies: version: master name: openjdk state: latest - - src: git+https://gitea-s2i2s.isti.cnr.it/ISTI-ansible-roles/ansible-role-nginx.git - version: master - name: nginx - state: latest - -collections: - - wildfly.jcliff diff --git a/tasks/keycloak-configuration.yml b/tasks/keycloak-configuration.yml index adf5cc1..1faeb97 100644 --- a/tasks/keycloak-configuration.yml +++ b/tasks/keycloak-configuration.yml @@ -1,18 +1,15 @@ --- - name: Manage the keycloak configuration block: - - name: Install the standalone configuration files - template: src={{ item }}.j2 dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/standalone/configuration/{{ item }} owner={{ keycloak_user }} group={{ keycloak_user }} mode='0640' - with_items: - - standalone.xml - - standalone-ha.xml + - name: Install the Keycloak and infinispan configuration files + ansible.builtin.template: + src: '{{ item }}.j2' + dest: '{{ keycloak_conf_directory }}/{{ item }}' + owner: root + group: root + loop: + - keycloak.conf + - cache-ispn.xml notify: Restart Keycloak - - name: Create the admin user - shell: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}/bin/add-user-keycloak.sh -u {{ keycloak_admin_user }} -p {{ keycloak_admin_password }} && chown {{ keycloak_user }} {{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/configuration/keycloak-add-user.json && chmod 600 {{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/configuration/keycloak-add-user.json' - args: - creates: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/configuration/keycloak-add-user.json' - notify: Restart Keycloak - tags: [ 'keycloak', 'keycloak_user', 'keycloak_conf' ] - tags: [ 'keycloak', 'keycloak_db', 'keycloak_conf' ] diff --git a/tasks/keycloak-install.yml b/tasks/keycloak-install.yml index 02aa5d1..179827f 100644 --- a/tasks/keycloak-install.yml +++ b/tasks/keycloak-install.yml @@ -2,51 +2,44 @@ - name: Install the keycloak distribution block: - name: Create the keycloak user - user: name={{ keycloak_user }} home={{ keycloak_install_dir }} createhome=no shell=/usr/sbin/nologin system=yes + ansible.builtin.user: + name: '{{ keycloak_user }}' + home: '{{ keycloak_install_dir }}' + createhome: false + shell: /usr/sbin/nologin + system: true - name: Create the keycloak installation directory, if it does not already exist. - file: dest={{ keycloak_install_dir }} owner=root group=root state=directory recurse=yes + ansible.builtin.file: + dest: '{{ keycloak_install_dir }}' + owner: root + group: root + state: directory + recurse: true - - name: Create the {{ keycloak_properties_directory }} - file: dest={{ keycloak_properties_directory }} owner=root group=root state=directory - tags: [ keycloak, keycloak_data_dir ] - - - name: Create the {{ keycloak_data_directory }} - file: dest={{ keycloak_data_directory }}/{{ item }} state=directory owner={{ keycloak_user }} group={{ keycloak_user }} mode='0755' - loop: '{{ keycloak_data_subdirs }}' - when: keycloak_data_directory != keycloak_distribution_data_directory - tags: [ keycloak, keycloak_data_dir ] + - name: Create the keycloak log directory + file: dest={{ keycloak_log_directory }} state=directory owner={{ keycloak_user }} group={{ keycloak_user }} mode='0755' - name: Download the keycloak distribution unarchive: remote_src=yes src={{ keycloak_download_url }} dest={{ keycloak_install_dir }} owner=root group=root args: creates: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}' - - name: Create the keycloak log directory - file: dest={{ keycloak_log_directory }} state=directory owner={{ keycloak_user }} group={{ keycloak_user }} mode='0755' + - name: Set the permissions of the {{ keycloak_data_directory }} directory + ansible.builtin.file: + dest: '{{ keycloak_data_directory }}' + state: directory + owner: '{{ keycloak_user }}' + group: '{{ keycloak_user }}' + mode: 0750 + tags: [ keycloak, keycloak_data_dir ] - - name: Create some log files with the correct permissions - file: dest={{ keycloak_log_directory }}/{{ item }} owner={{ keycloak_user }} group={{ keycloak_user }} mode='0644' state=touch - with_items: - - 'server.log' - - 'audit.log' - - - name: Fix the permissions of the directories into keycloak must be able to write - file: dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/{{ item }} state=directory owner={{ keycloak_user }} group={{ keycloak_user }} mode='0750' recurse=yes - with_items: '{{ keycloak_owned_directories }}' - - - name: Fix the permissions of the keycloak data directories if they are inside the distribution {{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/data - file: dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/data/{{ item }} state=directory owner={{ keycloak_user }} group={{ keycloak_user }} mode='0750' recurse=yes - with_items: '{{ keycloak_data_subdirs }}' - when: keycloak_data_directory == keycloak_distribution_data_directory - - - name: Remove the log directory inside the keycloak distribution - file: dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/log state=absent - - - name: Remove the log directory inside the keycloak distribution - file: dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/log state=absent - - - name: Link to the external log directory - file: src={{ keycloak_log_directory }} dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/{{ keycloak_wildfly_mode }}/log state=link + - name: Avatar directory + ansible.builtin.file: + dest: '{{ keycloak_external_avatar_dir }}' + state: directory + owner: '{{ keycloak_user }}' + group: '{{ keycloak_user }}' + mode: 0750 tags: keycloak diff --git a/tasks/keycloak-jdbc.yml b/tasks/keycloak-jdbc.yml deleted file mode 100644 index 65004d1..0000000 --- a/tasks/keycloak-jdbc.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- -- name: Manage the keycloak external DB driver - block: - - name: Create the path to the DB driver - file: dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/modules/system/layers/base/{{ keycloak_db_module_path }}/main state=directory - - - name: Get the JDBC driver {{ keycloack_jdbc_driver }} - get_url: url={{ keycloak_jdbc_driver_url }} dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/modules/system/layers/base/{{ keycloak_db_module_path }}/main/{{ keycloak_jdbc_driver }} owner=root group=root mode=0444 - notify: Restart Keycloak - - - name: Install the JDBC module configuration - template: src=jdbc-module.xml.j2 dest={{ keycloak_install_dir }}/{{ keycloak_distribution }}/modules/system/layers/base/{{ keycloak_db_module_path }}/main/module.xml owner=root group=root mode=0444 - notify: Restart Keycloak - - when: keycloak_use_external_db - tags: [ 'keycloak', 'keycloak_db', 'keycloak_conf' ] diff --git a/tasks/keycloak-letsencrypt.yml b/tasks/keycloak-letsencrypt.yml new file mode 100644 index 0000000..802d754 --- /dev/null +++ b/tasks/keycloak-letsencrypt.yml @@ -0,0 +1,42 @@ +--- +- name: TLS certificates management with Letsencrypt + block: + - name: Create the acme hooks directory if it does not yet exist + file: + dest: '{{ letsencrypt_acme_services_scripts_dir }}' + state: directory + owner: root + group: root + + - name: Copy the key file where keycloak expects it + copy: + src: '{{ letsencrypt_acme_sh_certificates_install_path }}/privkey' + dest: '{{ keycloak_conf_directory }}/server.key.pem' + owner: root + group: '{{ keycloak_username }}' + mode: 0640 + remote_src: true + notify: Restart keycloak + + - name: Copy the certificate file where keycloak expects it + copy: + src: '{{ letsencrypt_acme_sh_certificates_install_path }}/fullchain' + dest: '{{ keycloak_conf_directory }}/server.crt.pem' + owner: root + group: '{{ keycloak_username }}' + mode: 0640 + remote_src: true + notify: Restart keycloak + + - name: Install a script that updates the certificates upon renewal + template: + src: keycloak-letsencrypt-hook.j2 + dest: '{{ letsencrypt_acme_services_scripts_dir }}/keycloak' + owner: root + group: root + mode: 4555 + + when: + - keycloak_letsencrypt_certs + - letsencrypt_acme_install + tags: ['keycloak', 'keycloak_baremetal', 'keycloak_letsencrypt'] diff --git a/tasks/keycloak-providers.yml b/tasks/keycloak-providers.yml new file mode 100644 index 0000000..18381f2 --- /dev/null +++ b/tasks/keycloak-providers.yml @@ -0,0 +1,19 @@ +--- +- name: Get the keycloak providers + maven_artifact: + artifact_id: "{{ item.maven_id }}" + version: "{{ item.version | default('latest') }}" + group_id: "{{ item.group_id }}" + extension: "{{ item.extension | default('jar') }}" + repository_url: "{{ item.maven_repo_url }}" + dest: "{{ keycloak_providers_directory }}/{{ item.name }}.{{ item.extension | default('jar') }}" + verify_checksum: always + mode: 0644 + loop: '{{ keycloak_remote_providers }}' + when: item.extension is not defined or item.extension != "ear" + notify: Restart keycloak + + tags: + - keycloak + - keycloak_providers + - keycloak_providers_jar diff --git a/tasks/main.yml b/tasks/main.yml index ecdfd90..6c25e6e 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,69 +1,30 @@ --- -- name: Manage the JCliff installation on Ubuntu/Debian - block: - - name: Download the jcliff distribution - unarchive: - remote_src: yes - src: 'https://github.com/bserdar/jcliff/releases/download/v{{ keycloak_jcliff_version }}/jcliff-{{ keycloak_jcliff_version }}-dist.tar.gz' - dest: '/opt' - owner: root - group: root - - - name: Fix the jcliff executable permissions - file: - dest: '/opt/jcliff-{{ keycloak_jcliff_version }}/jcliff' - mode: '0755' - - - name: Link to the executable - file: - src: '/opt/jcliff-{{ keycloak_jcliff_version }}/jcliff' - dest: /usr/bin/jcliff - state: link - - - name: Link to the shared resources - file: - src: '/opt/jcliff-{{ keycloak_jcliff_version }}' - dest: /usr/share/jcliff - state: link - - - name: Set the JBOSS_HOME as {{ jboss_home }} in the global environment profile - template: - src: jboss-env.sh.j2 - dest: /etc/profile.d/jboss-env.sh - owner: root - group: root - mode: '0444' - - when: ansible_distribution_file_variety == "Debian" - tags: [ keycloak, jcliff ] - - import_tasks: keycloak-install.yml -- import_tasks: keycloak-jdbc.yml +- import_tasks: keycloak-letsencrypt.yml +- import_tasks: keycloak-providers.yml - import_tasks: keycloak-configuration.yml - name: Manage the keycloak service block: - - name: Install the keycloak properties file - template: - src: wildfly.properties.j2 - dest: '{{ keycloak_properties_directory }}/wildfly.properties' + - name: Install the keycloak systemd unit + ansible.builtin.template: + src: keycloak.service.j2 + dest: /etc/systemd/system/keycloak.service owner: root group: root - mode: '0444' - notify: Restart Keycloak - - - name: Install the keycloak systemd unit - template: src=keycloak.service.j2 dest=/etc/systemd/system/keycloak.service owner=root group=root mode=0644 + mode: 0644 notify: Restart Keycloak register: keycloak_unit - name: Reload systemd - systemd: + ansible.builtin.systemd: daemon_reload: yes when: keycloak_unit is changed -# - name: ensure that the keycloak service is running and enabled -# service: name=keycloak state=started enabled=yes - - tags: [ 'keycloak', 'keycloak_service', 'keycloak_conf' ] + - name: ensure that the keycloak service is running and enabled + ansible.builtin.service: + name: keycloak + state: started + enabled: true + tags: ['keycloak', 'keycloak_service', 'keycloak_conf'] diff --git a/templates/cache-ispn.xml.j2 b/templates/cache-ispn.xml.j2 new file mode 100644 index 0000000..a3d9ddb --- /dev/null +++ b/templates/cache-ispn.xml.j2 @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2019 Red Hat, Inc. and/or its affiliates + ~ and other contributors as indicated by the @author tags. + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<infinispan + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:infinispan:config:11.0 http://www.infinispan.org/schemas/infinispan-config-11.0.xsd" + xmlns="urn:infinispan:config:11.0"> + + <cache-container name="{{ keycloak_cache_container_name }}"> + <transport lock-timeout="60000"/> + <local-cache name="realms"> + <encoding> + <key media-type="application/x-java-object"/> + <value media-type="application/x-java-object"/> + </encoding> + <memory max-count="10000"/> + </local-cache> + <local-cache name="users"> + <encoding> + <key media-type="application/x-java-object"/> + <value media-type="application/x-java-object"/> + </encoding> + <memory max-count="10000"/> + </local-cache> + <distributed-cache name="sessions" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <distributed-cache name="authenticationSessions" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <distributed-cache name="offlineSessions" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <distributed-cache name="clientSessions" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <distributed-cache name="offlineClientSessions" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <distributed-cache name="loginFailures" owners="2"> + <expiration lifespan="-1"/> + </distributed-cache> + <local-cache name="authorization"> + <encoding> + <key media-type="application/x-java-object"/> + <value media-type="application/x-java-object"/> + </encoding> + <memory max-count="10000"/> + </local-cache> + <replicated-cache name="work"> + <expiration lifespan="-1"/> + </replicated-cache> + <local-cache name="keys"> + <encoding> + <key media-type="application/x-java-object"/> + <value media-type="application/x-java-object"/> + </encoding> + <expiration max-idle="3600000"/> + <memory max-count="1000"/> + </local-cache> + <distributed-cache name="actionTokens" owners="2"> + <encoding> + <key media-type="application/x-java-object"/> + <value media-type="application/x-java-object"/> + </encoding> + <expiration max-idle="-1" lifespan="-1" interval="300000"/> + <memory max-count="-1"/> + </distributed-cache> + </cache-container> +</infinispan> \ No newline at end of file diff --git a/templates/jboss-env.sh.j2 b/templates/jboss-env.sh.j2 deleted file mode 100644 index e1a81e0..0000000 --- a/templates/jboss-env.sh.j2 +++ /dev/null @@ -1 +0,0 @@ -export JBOSS_HOME={{ jboss_home }} diff --git a/templates/jdbc-module.xml.j2 b/templates/jdbc-module.xml.j2 deleted file mode 100644 index cf5d2d0..0000000 --- a/templates/jdbc-module.xml.j2 +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" ?> -<module xmlns="urn:jboss:module:1.3" name="{{ keycloak_db_module_name }}"> - - <resources> - <resource-root path="{{ keycloak_jdbc_driver }}"/> - </resources> - - <dependencies> - <module name="javax.api"/> - <module name="javax.transaction.api"/> - </dependencies> -</module> \ No newline at end of file diff --git a/templates/keycloak-letsencrypt-hook.j2 b/templates/keycloak-letsencrypt-hook.j2 new file mode 100644 index 0000000..f02b63a --- /dev/null +++ b/templates/keycloak-letsencrypt-hook.j2 @@ -0,0 +1,40 @@ +#!/bin/bash + +LE_CERTS_DIR="{{ letsencrypt_acme_sh_certificates_install_path }}" +LE_LOG_DIR=/var/log/letsencrypt +LE_LOGFILE="$LE_LOG_DIR/keycloak.log" +KEYCLOAK_CERTS_DIR="{{ keycloak_conf_directory }}" +KEYCLOAK_KEYFILE="{{ keycloak_conf_directory }}/server.key.pem" +keycloak_CERTFILE="{{ keycloak_conf_directory }}/server.crt.pem" +DATE=$( date ) +RETVAL= + +[ ! -d $LE_LOG_DIR ] && mkdir $LE_LOG_DIR +echo "$DATE" >> "$LE_LOGFILE" + +logger "acme-keycloak-hook: Check if the certificate has been renewed" +cmp ${LE_CERTS_DIR}/privkey ${KEYCLOAK_KEYFILE} +RETVAL=$? +if [ $RETVAL -eq 0 ] ; then + logger "acme-keycloak-hook: No new cerficate." + echo "acme-keycloak-hook: No new cerficate." >> $LE_LOGFILE + exit 0 +else + logger "acme-keycloak-hook: Copying the key file" + echo "Copy the certificate files" >> $LE_LOGFILE + /bin/cp -f ${LE_CERTS_DIR}/privkey ${KEYCLOAK_KEYFILE} + /bin/cp -f ${LE_CERTS_DIR}/fullchain ${KEYCLOAK_CERTFILE} +fi + +chmod 440 ${KEYCLOAK_KEYFILE} ${KEYCLOAK_CERTFILE} +chown root ${KEYCLOAK_KEYFILE} ${KEYCLOAK_CERTFILE} +chgrp keycloak ${KEYCLOAK_KEYFILE} ${KEYCLOAK_CERTFILE} + +logger "acme-keycloak-hook: Restart the keycloak service after a certificate renewal" +systemctl restart keycloak >> $LE_LOGFILE 2>&1 +echo "acme-keycloak-hook: Restart the keycloak service" >> $LE_LOGFILE + +logger "acme-keycloak-hook: Done" +echo "acme-keycloak-hook: Done." >> $LE_LOGFILE + +exit 0 diff --git a/templates/keycloak.conf.j2 b/templates/keycloak.conf.j2 new file mode 100644 index 0000000..b66bd1f --- /dev/null +++ b/templates/keycloak.conf.j2 @@ -0,0 +1,59 @@ + +http-relative-path=/auth +http-enabled={{ keycloak_http_enabled }} +http-host={{ keycloak_listen }} +http-port={{ keycloak_http_port }} +#log-level=DEBUG + +# Database +# The database vendor. +db={{ keycloak_db_vendor }} +# The username of the database user. +db-username={{ keycloak_database_user }} +# The password of the database user. +db-password={{ keycloak_database_password }} +# The full database JDBC URL. If not provided, a default URL is set based on the selected database vendor. +db-url=jdbc:postgresql://{{ keycloak_database_host }}/{{ keycloak_database_name }} + +# Observability +# If the server should expose metrics and healthcheck endpoints. +health-enabled={{ keycloak_metrics_and_health_checks_enabled }} +metrics-enabled={{ keycloak_metrics_and_health_checks_enabled }} + +{% if keycloak_https_enabled %} +# HTTPS +# The file path to a server certificate or certificate chain in PEM format. +https-certificate-file={{ keycloak_conf_directory }}/server.crt.pem +# The file path to a private key in PEM format. +https-certificate-key-file={{ keycloak_conf_directory }}/server.key.pem +https-protocols={{ keycloak_https_protocols }} +https-port={{ keycloak_https_port }} +{% endif %} + +{% if keycloak_behind_reverse_proxy %} +# The proxy address forwarding mode if the server is behind a reverse proxy. +proxy={{ keycloak_reverse_proxy_type }} +{% endif %} + +{% if keycloak_set_hostname %} +# Hostname for the Keycloak server. +hostname={{ keycloak_hostname }} +{% endif %} + +{% if keycloak_external_avatar_dir_enabled %} +spi-avatar-storage-avatar-storage-file-avatar-folder={{ keycloak_external_avatar_dir}} +{% endif %} + +{% if keycloak_cluster %} +# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy +spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_reverse_proxy_infinispan_attach_route }} +cache={{ keycloak_cache_type }} +cache-stack={{ keycloak_cache_stack }} +{% endif %} +# Logging +log={{ keycloak_log_handlers }} +log-console-format={{ keycloak_log_console_format }} +log-console-output={{ keycloak_log_console_output }} +log-file={{ keycloak_log_file }} +log-file-format={{ keycloak_log_file_format }} +log-level={{ keycloak_log_level }} diff --git a/templates/keycloak.service.j2 b/templates/keycloak.service.j2 index f0fe928..e591267 100644 --- a/templates/keycloak.service.j2 +++ b/templates/keycloak.service.j2 @@ -1,18 +1,26 @@ [Unit] Description=Keycloak Application Server -After=network.target +After=syslog.target network.target +{% if keycloak_before_nginx %} +Before=nginx.service +{% endif %} +{% if keycloak_before_apache_httpd %} +{% if ansible_distribution_file_variety == "RedHat" %} +Before=httpd.service +{% endif %} +{% if ansible_distribution_file_variety == "Debian" %} +Before=apache2.service +{% endif %} +{% endif %} [Service] -Type=idle -Environment=JBOSS_HOME={{ keycloak_runtime_home }} -Environment=JBOSS_LOG_DIR={{ keycloak_log_directory }} -Environment="JAVA_OPTS=-Xms{{ keycloak_java_min_heap }} -Xmx{{ keycloak_java_max_heap }}" +Environment=JAVA={{ keycloak_openjdk_bin }} +Environment=JAVA_HOME=/usr/lib/jvm/java-{{ keycloak_openjdk_runtime_version}}-openjdk-amd64 User={{ keycloak_user }} Group={{ keycloak_user }} -ExecStart={{ keycloak_runtime_home }}/bin/standalone.sh -P {{ keycloak_properties_directory }}/wildfly.properties -b {{ keycloak_listen }} {% if keycloak_wildfly_clustered %}--server-config=standalone-ha.xml -Djboss.node.name={{ keycloak_wildfly_cluster_node_name }}{% endif %} - -TimeoutStartSec=600 -TimeoutStopSec=600 +SuccessExitStatus=0 143 +UMask=0027 +ExecStart={{ keycloak_runtime_home }}/bin/kc.sh start{% if not keycloak_optimize_build_at_startup %} --optimized{% endif %}{% if keycloak_disabled_features != "" %} --features-disabled={% for dis in keycloak_disabled_features %}{{ dis }}{% if not loop.last %},{% endif %}{% endfor %}{% endif %}{% if keycloak_preview_features != "" %} --features=={% for feat in --features= %}{{ feat }}{% if not loop.last %},{% endif %}{% endfor %}{% endif %}{% if keycloak_upgrade_db_at_startup %} --spi-connections-jpa-default-migration-strategy=update{% endif %} [Install] -WantedBy=multi-user.target +WantedBy=multi-user.target \ No newline at end of file diff --git a/templates/standalone.xml.j2 b/templates/standalone.xml.j2 deleted file mode 100644 index 1f6b2c7..0000000 --- a/templates/standalone.xml.j2 +++ /dev/null @@ -1,638 +0,0 @@ -<?xml version='1.0' encoding='UTF-8'?> - -<server xmlns="urn:jboss:domain:10.0"> - <extensions> - <extension module="org.jboss.as.clustering.infinispan"/> - <extension module="org.jboss.as.connector"/> - <extension module="org.jboss.as.deployment-scanner"/> - <extension module="org.jboss.as.ee"/> - <extension module="org.jboss.as.ejb3"/> - <extension module="org.jboss.as.jaxrs"/> - <extension module="org.jboss.as.jmx"/> - <extension module="org.jboss.as.jpa"/> - <extension module="org.jboss.as.logging"/> - <extension module="org.jboss.as.mail"/> - <extension module="org.jboss.as.naming"/> - <extension module="org.jboss.as.remoting"/> - <extension module="org.jboss.as.security"/> - <extension module="org.jboss.as.transactions"/> - <extension module="org.jboss.as.weld"/> - <extension module="org.keycloak.keycloak-server-subsystem"/> - <extension module="org.wildfly.extension.bean-validation"/> - <extension module="org.wildfly.extension.core-management"/> - <extension module="org.wildfly.extension.elytron"/> - <extension module="org.wildfly.extension.io"/> - <extension module="org.wildfly.extension.microprofile.config-smallrye"/> - <extension module="org.wildfly.extension.microprofile.health-smallrye"/> - <extension module="org.wildfly.extension.microprofile.metrics-smallrye"/> - <extension module="org.wildfly.extension.request-controller"/> - <extension module="org.wildfly.extension.security.manager"/> - <extension module="org.wildfly.extension.undertow"/> - </extensions> - <management> - <security-realms> - <security-realm name="ManagementRealm"> - <authentication> - <local default-user="$local" skip-group-loading="true"/> - <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/> - </authentication> - <authorization map-groups-to-roles="false"> - <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/> - </authorization> - </security-realm> - <security-realm name="ApplicationRealm"> - <server-identities> - <ssl> - <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/> - </ssl> - </server-identities> - <authentication> - <local default-user="$local" allowed-users="*" skip-group-loading="true"/> - <properties path="application-users.properties" relative-to="jboss.server.config.dir"/> - </authentication> - <authorization> - <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> - </authorization> - </security-realm> - </security-realms> - <audit-log> - <formatters> - <json-formatter name="json-formatter"/> - </formatters> - <handlers> - <file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/> - </handlers> - <logger log-boot="true" log-read-only="false" enabled="false"> - <handlers> - <handler name="file"/> - </handlers> - </logger> - </audit-log> - <management-interfaces> - <http-interface security-realm="ManagementRealm"> - <http-upgrade enabled="true"/> - <socket-binding http="management-http"/> - </http-interface> - </management-interfaces> - <access-control provider="simple"> - <role-mapping> - <role name="SuperUser"> - <include> - <user name="$local"/> - </include> - </role> - </role-mapping> - </access-control> - </management> - <profile> - <subsystem xmlns="urn:jboss:domain:logging:8.0"> - <console-handler name="CONSOLE"> - <level name="INFO"/> - <formatter> - <named-formatter name="COLOR-PATTERN"/> - </formatter> - </console-handler> - <periodic-rotating-file-handler name="FILE" autoflush="true"> - <formatter> - <named-formatter name="PATTERN"/> - </formatter> - <file relative-to="jboss.server.log.dir" path="server.log"/> - <suffix value=".yyyy-MM-dd"/> - <append value="true"/> - </periodic-rotating-file-handler> - <logger category="com.arjuna"> - <level name="WARN"/> - </logger> - <logger category="io.jaegertracing.Configuration"> - <level name="WARN"/> - </logger> - <logger category="org.jboss.as.config"> - <level name="DEBUG"/> - </logger> - <logger category="sun.rmi"> - <level name="WARN"/> - </logger> - <root-logger> - <level name="INFO"/> - <handlers> - <handler name="CONSOLE"/> - <handler name="FILE"/> - </handlers> - </root-logger> - <formatter name="PATTERN"> - <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/> - </formatter> - <formatter name="COLOR-PATTERN"> - <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/> - </formatter> - </subsystem> - <subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/> - <subsystem xmlns="urn:jboss:domain:core-management:1.0"/> - <subsystem xmlns="urn:jboss:domain:datasources:5.0"> - <datasources> - {% if keycloak_use_external_db %} - <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}"> - <connection-url>jdbc:{{ keycloak_db }}://{{ keycloak_database_host }}/{{ keycloak_database_name }}</connection-url> - <driver>{{ keycloak_db }}</driver> - <pool> - <max-pool-size>{{ keycloak_database_max_pool_size }}</max-pool-size> - </pool> - <timeout> - <idle-timeout-minutes>{{ keycloak_database_idle_timeouts_min }}</idle-timeout-minutes> - </timeout> - <validation> - {% if keycloak_database_jboss_connection_checker %} - <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker"></valid-connection-checker> - <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter"></exception-sorter> - {% else %} - <check-valid-connection-sql>select 1</check-valid-connection-sql> - <validate-on-match>false</validate-on-match> - <background-validation>true</background-validation> - <background-validation-millis>10000</background-validation-millis> - {% endif %} - </validation> - <security> - <user-name>{{ keycloak_database_user }}</user-name> - <password>{{ keycloak_database_password }}</password> - </security> - </datasource> - {% else %} - <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}"> - <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url> - <driver>h2</driver> - <security> - <user-name>sa</user-name> - <password>sa</password> - </security> - </datasource> - <datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}"> - <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url> - <driver>h2</driver> - <security> - <user-name>sa</user-name> - <password>sa</password> - </security> - </datasource> - {% endif %} - <drivers> - {% if keycloak_use_external_db %} - <driver name="{{ keycloak_db }}" module="{{ keycloak_db_module_name }}"> - <xa-datasource-class>{{ keycloak_db_class_name }}</xa-datasource-class> - </driver> - {% else %} - <driver name="h2" module="com.h2database.h2"> - <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> - </driver> - {% endif %} - </drivers> - </datasources> - </subsystem> - <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0"> - <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:ee:5.0"> - <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement> - <concurrent> - <context-services> - <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/> - </context-services> - <managed-thread-factories> - <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/> - </managed-thread-factories> - <managed-executor-services> - <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/> - </managed-executor-services> - <managed-scheduled-executor-services> - <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/> - </managed-scheduled-executor-services> - </concurrent> - {% if keycloak_use_external_db %} - <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/KeycloakDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/> - {% else %} - <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/> - {% endif %} - </subsystem> - <subsystem xmlns="urn:jboss:domain:ejb3:6.0"> - <session-bean> - <stateless> - <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/> - </stateless> - <stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/> - <singleton default-access-timeout="5000"/> - </session-bean> - <pools> - <bean-instance-pools> - <strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> - <strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> - </bean-instance-pools> - </pools> - <caches> - <cache name="simple"/> - <cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/> - </caches> - <passivation-stores> - <passivation-store name="infinispan" cache-container="ejb" max-size="10000"/> - </passivation-stores> - <async thread-pool-name="default"/> - <timer-service thread-pool-name="default" default-data-store="default-file-store"> - <data-stores> - <file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/> - </data-stores> - </timer-service> - <remote connector-ref="http-remoting-connector" thread-pool-name="default"> - <channel-creation-options> - <option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/> - </channel-creation-options> - </remote> - <thread-pools> - <thread-pool name="default"> - <max-threads count="10"/> - <keepalive-time time="60" unit="seconds"/> - </thread-pool> - </thread-pools> - <default-security-domain value="other"/> - <default-missing-method-permissions-deny-access value="true"/> - <statistics enabled="${wildfly.ejb3.statistics-enabled:${wildfly.statistics-enabled:false}}"/> - <log-system-exceptions value="true"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:io:3.0"> - <worker name="default"/> - <buffer-pool name="default"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:infinispan:9.0"> - <cache-container name="keycloak"> - <local-cache name="realms"> - <object-memory size="10000"/> - </local-cache> - <local-cache name="users"> - <object-memory size="10000"/> - </local-cache> - <local-cache name="sessions"/> - <local-cache name="authenticationSessions"/> - <local-cache name="offlineSessions"/> - <local-cache name="clientSessions"/> - <local-cache name="offlineClientSessions"/> - <local-cache name="loginFailures"/> - <local-cache name="work"/> - <local-cache name="authorization"> - <object-memory size="10000"/> - </local-cache> - <local-cache name="keys"> - <object-memory size="1000"/> - <expiration max-idle="3600000"/> - </local-cache> - <local-cache name="actionTokens"> - <object-memory size="-1"/> - <expiration max-idle="-1" interval="300000"/> - </local-cache> - </cache-container> - <cache-container name="server" default-cache="default" module="org.wildfly.clustering.server"> - <local-cache name="default"> - <transaction mode="BATCH"/> - </local-cache> - </cache-container> - <cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan"> - <local-cache name="passivation"> - <locking isolation="REPEATABLE_READ"/> - <transaction mode="BATCH"/> - <file-store passivation="true" purge="false"/> - </local-cache> - <local-cache name="sso"> - <locking isolation="REPEATABLE_READ"/> - <transaction mode="BATCH"/> - </local-cache> - <local-cache name="routing"/> - </cache-container> - <cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan"> - <local-cache name="passivation"> - <locking isolation="REPEATABLE_READ"/> - <transaction mode="BATCH"/> - <file-store passivation="true" purge="false"/> - </local-cache> - </cache-container> - <cache-container name="hibernate" module="org.infinispan.hibernate-cache"> - <local-cache name="entity"> - <object-memory size="10000"/> - <expiration max-idle="100000"/> - </local-cache> - <local-cache name="local-query"> - <object-memory size="10000"/> - <expiration max-idle="100000"/> - </local-cache> - <local-cache name="timestamps"/> - </cache-container> - </subsystem> - <subsystem xmlns="urn:jboss:domain:jaxrs:2.0"/> - <subsystem xmlns="urn:jboss:domain:jca:5.0"> - <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/> - <bean-validation enabled="true"/> - <default-workmanager> - <short-running-threads> - <core-threads count="50"/> - <queue-length count="50"/> - <max-threads count="50"/> - <keepalive-time time="10" unit="seconds"/> - </short-running-threads> - <long-running-threads> - <core-threads count="50"/> - <queue-length count="50"/> - <max-threads count="50"/> - <keepalive-time time="10" unit="seconds"/> - </long-running-threads> - </default-workmanager> - <cached-connection-manager/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:jmx:1.3"> - <expose-resolved-model/> - <expose-expression-model/> - <remoting-connector/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:jpa:1.1"> - <jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:mail:3.0"> - <mail-session name="default" jndi-name="java:jboss/mail/Default"> - <smtp-server outbound-socket-binding-ref="mail-smtp"/> - </mail-session> - </subsystem> - <subsystem xmlns="urn:jboss:domain:naming:2.0"> - <remote-naming/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:remoting:4.0"> - <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:request-controller:1.0"/> - <subsystem xmlns="urn:jboss:domain:security-manager:1.0"> - <deployment-permissions> - <maximum-set> - <permission class="java.security.AllPermission"/> - </maximum-set> - </deployment-permissions> - </subsystem> - <subsystem xmlns="urn:wildfly:elytron:9.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto"> - <providers> - <aggregate-providers name="combined-providers"> - <providers name="elytron"/> - <providers name="openssl"/> - </aggregate-providers> - <provider-loader name="elytron" module="org.wildfly.security.elytron"/> - <provider-loader name="openssl" module="org.wildfly.openssl"/> - </providers> - <audit-logging> - <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/> - </audit-logging> - <security-domains> - <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper"> - <realm name="ApplicationRealm" role-decoder="groups-to-roles"/> - <realm name="local"/> - </security-domain> - <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper"> - <realm name="ManagementRealm" role-decoder="groups-to-roles"/> - <realm name="local" role-mapper="super-user-mapper"/> - </security-domain> - </security-domains> - <security-realms> - <identity-realm name="local" identity="$local"/> - <properties-realm name="ApplicationRealm"> - <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/> - <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> - </properties-realm> - <properties-realm name="ManagementRealm"> - <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/> - <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/> - </properties-realm> - </security-realms> - <mappers> - <simple-permission-mapper name="default-permission-mapper" mapping-mode="first"> - <permission-mapping> - <principal name="anonymous"/> - <permission-set name="default-permissions"/> - </permission-mapping> - <permission-mapping match-all="true"> - <permission-set name="login-permission"/> - <permission-set name="default-permissions"/> - </permission-mapping> - </simple-permission-mapper> - <constant-realm-mapper name="local" realm-name="local"/> - <simple-role-decoder name="groups-to-roles" attribute="groups"/> - <constant-role-mapper name="super-user-mapper"> - <role name="SuperUser"/> - </constant-role-mapper> - </mappers> - <permission-sets> - <permission-set name="login-permission"> - <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/> - </permission-set> - <permission-set name="default-permissions"> - <permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/> - <permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/> - <permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/> - </permission-set> - </permission-sets> - <http> - <http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global"> - <mechanism-configuration> - <mechanism mechanism-name="DIGEST"> - <mechanism-realm realm-name="ManagementRealm"/> - </mechanism> - </mechanism-configuration> - </http-authentication-factory> - <provider-http-server-mechanism-factory name="global"/> - </http> - <sasl> - <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain"> - <mechanism-configuration> - <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/> - <mechanism mechanism-name="DIGEST-MD5"> - <mechanism-realm realm-name="ApplicationRealm"/> - </mechanism> - </mechanism-configuration> - </sasl-authentication-factory> - <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain"> - <mechanism-configuration> - <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/> - <mechanism mechanism-name="DIGEST-MD5"> - <mechanism-realm realm-name="ManagementRealm"/> - </mechanism> - </mechanism-configuration> - </sasl-authentication-factory> - <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron"> - <properties> - <property name="wildfly.sasl.local-user.default-user" value="$local"/> - </properties> - </configurable-sasl-server-factory> - <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global"> - <filters> - <filter provider-name="WildFlyElytron"/> - </filters> - </mechanism-provider-filtering-sasl-server-factory> - <provider-sasl-server-factory name="global"/> - </sasl> - </subsystem> - <subsystem xmlns="urn:jboss:domain:security:2.0"> - <security-domains> - <security-domain name="other" cache-type="default"> - <authentication> - <login-module code="Remoting" flag="optional"> - <module-option name="password-stacking" value="useFirstPass"/> - </login-module> - <login-module code="RealmDirect" flag="required"> - <module-option name="password-stacking" value="useFirstPass"/> - </login-module> - </authentication> - </security-domain> - <security-domain name="jboss-web-policy" cache-type="default"> - <authorization> - <policy-module code="Delegating" flag="required"/> - </authorization> - </security-domain> - <security-domain name="jaspitest" cache-type="default"> - <authentication-jaspi> - <login-module-stack name="dummy"> - <login-module code="Dummy" flag="optional"/> - </login-module-stack> - <auth-module code="Dummy"/> - </authentication-jaspi> - </security-domain> - <security-domain name="jboss-ejb-policy" cache-type="default"> - <authorization> - <policy-module code="Delegating" flag="required"/> - </authorization> - </security-domain> - </security-domains> - </subsystem> - <subsystem xmlns="urn:jboss:domain:transactions:5.0"> - <core-environment node-identifier="${jboss.tx.node.id:1}"> - <process-id> - <uuid/> - </process-id> - </core-environment> - <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/> - <coordinator-environment statistics-enabled="${wildfly.transactions.statistics-enabled:${wildfly.statistics-enabled:false}}"/> - <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/> - </subsystem> - <subsystem xmlns="urn:jboss:domain:weld:4.0"/> - <subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/> - <subsystem xmlns="urn:wildfly:microprofile-health-smallrye:2.0" security-enabled="false" empty-liveness-checks-status="${env.MP_HEALTH_EMPTY_LIVENESS_CHECKS_STATUS:UP}" empty-readiness-checks-status="${env.MP_HEALTH_EMPTY_READINESS_CHECKS_STATUS:UP}"/> - <subsystem xmlns="urn:wildfly:microprofile-metrics-smallrye:2.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:wildfly}"/> - <subsystem xmlns="urn:jboss:domain:undertow:10.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}"> - <buffer-cache name="default"/> - <server name="default-server"> - <http-listener name="default" socket-binding="http" enable-http2="true" {% if keycloak_behind_reverse_proxy %} redirect-socket="proxy-https" proxy-address-forwarding="true"{% endif %}/> - <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/> - <host name="default-host" alias="localhost"> - <location name="/" handler="welcome-content"/> - <http-invoker security-realm="ApplicationRealm"/> - </host> - </server> - <servlet-container name="default"> - <jsp-config/> - <websockets/> - </servlet-container> - <handlers> - <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/> - </handlers> - </subsystem> - <subsystem xmlns="urn:jboss:domain:keycloak-server:1.1"> - <web-context>auth</web-context> - <providers> - <provider>classpath:${jboss.home.dir}/providers/*</provider> - </providers> - <master-realm-name>master</master-realm-name> - <scheduled-task-interval>900</scheduled-task-interval> - <theme> - <staticMaxAge>2592000</staticMaxAge> - <cacheThemes>true</cacheThemes> - <cacheTemplates>true</cacheTemplates> - <dir>${jboss.home.dir}/themes</dir> - </theme> - <spi name="eventsStore"> - <provider name="jpa" enabled="true"> - <properties> - <property name="exclude-events" value="["REFRESH_TOKEN"]"/> - </properties> - </provider> - </spi> - <spi name="userCache"> - <provider name="default" enabled="true"/> - </spi> - <spi name="userSessionPersister"> - <default-provider>jpa</default-provider> - </spi> - <spi name="timer"> - <default-provider>basic</default-provider> - </spi> - <spi name="connectionsHttpClient"> - <provider name="default" enabled="true"/> - </spi> - <spi name="connectionsJpa"> - <provider name="default" enabled="true"> - <properties> - <property name="dataSource" value="java:jboss/datasources/KeycloakDS"/> - <property name="initializeEmpty" value="true"/> - <property name="migrationStrategy" value="update"/> - <property name="migrationExport" value="${jboss.home.dir}/keycloak-database-update.sql"/> - </properties> - </provider> - </spi> - <spi name="realmCache"> - <provider name="default" enabled="true"/> - </spi> - <spi name="connectionsInfinispan"> - <default-provider>default</default-provider> - <provider name="default" enabled="true"> - <properties> - <property name="cacheContainer" value="java:jboss/infinispan/container/keycloak"/> - </properties> - </provider> - </spi> - <spi name="jta-lookup"> - <default-provider>${keycloak.jta.lookup.provider:jboss}</default-provider> - <provider name="jboss" enabled="true"/> - </spi> - <spi name="publicKeyStorage"> - <provider name="infinispan" enabled="true"> - <properties> - <property name="minTimeBetweenRequests" value="10"/> - </properties> - </provider> - </spi> - <spi name="x509cert-lookup"> - <default-provider>${keycloak.x509cert.lookup.provider:default}</default-provider> - <provider name="default" enabled="true"/> - </spi> - <spi name="hostname"> - <default-provider>default</default-provider> - <provider name="default" enabled="true"> - <properties> - <property name="frontendUrl" value="${keycloak.frontendUrl:}"/> - <property name="forceBackendUrlToFrontendUrl" value="false"/> - </properties> - </provider> - </spi> - </subsystem> - </profile> - <interfaces> - <interface name="management"> - <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> - </interface> - <interface name="public"> - <inet-address value="${jboss.bind.address:127.0.0.1}"/> - </interface> - </interfaces> - <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> - <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/> - <socket-binding name="http" port="${jboss.http.port:8080}"/> - <socket-binding name="https" port="${jboss.https.port:8443}"/> - {% if keycloak_behind_reverse_proxy %} - <socket-binding name="proxy-https" port="443"/> - {% endif %} - <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> - <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/> - <socket-binding name="txn-recovery-environment" port="4712"/> - <socket-binding name="txn-status-manager" port="4713"/> - <outbound-socket-binding name="mail-smtp"> - <remote-destination host="localhost" port="25"/> - </outbound-socket-binding> - </socket-binding-group> -</server> diff --git a/templates/wildfly.properties.j2 b/templates/wildfly.properties.j2 deleted file mode 100644 index 602ac7f..0000000 --- a/templates/wildfly.properties.j2 +++ /dev/null @@ -1,3 +0,0 @@ -{% for prop in keycloak_startup_properties %} -{{ prop.name }}={{ prop.value }} -{% endfor %} diff --git a/vars/main.yml b/vars/main.yml index 5b583ab..3be2693 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,4 +1,5 @@ --- +openjdk_version: '{{ keycloak_openjdk_version }}' openjdk_pkgs: - jre - jdk @@ -8,16 +9,9 @@ keycloak_user: 'keycloak' keycloak_version: '{{ keycloak_major_version }}.{{ keycloak_minor_version }}.{{ keycloak_point_version }}' keycloak_distribution: 'keycloak-{{ keycloak_version }}' keycloak_distribution_archive: '{{ keycloak_distribution }}.tar.gz' -keycloak_download_url: 'https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_distribution_archive }}' +keycloak_download_url: 'https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_distribution_archive }}' keycloak_runtime_home: '{{ keycloak_install_dir }}/{{ keycloak_distribution }}' jboss_home: '{{ keycloak_runtime_home }}' keycloak_owned_directories: - - tmp - - configuration - - deployments -keycloak_data_subdirs: - - avatar - - content - - kernel - - timer-service-data - - tx-object-store + - '{{ keycloak_data_directory }}' + - '{{ keycloak_external_avatar_dir }}'