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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 @@ - - - - - - - - - - - - \ 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 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {% if keycloak_use_external_db %} - - jdbc:{{ keycloak_db }}://{{ keycloak_database_host }}/{{ keycloak_database_name }} - {{ keycloak_db }} - - {{ keycloak_database_max_pool_size }} - - - {{ keycloak_database_idle_timeouts_min }} - - - {% if keycloak_database_jboss_connection_checker %} - - - {% else %} - select 1 - false - true - 10000 - {% endif %} - - - {{ keycloak_database_user }} - {{ keycloak_database_password }} - - - {% else %} - - jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE - h2 - - sa - sa - - - - jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE - h2 - - sa - sa - - - {% endif %} - - {% if keycloak_use_external_db %} - - {{ keycloak_db_class_name }} - - {% else %} - - org.h2.jdbcx.JdbcDataSource - - {% endif %} - - - - - - - - false - - - - - - - - - - - - - - - {% if keycloak_use_external_db %} - - {% else %} - - {% endif %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - auth - - classpath:${jboss.home.dir}/providers/* - - master - 900 - - 2592000 - true - true - ${jboss.home.dir}/themes - - - - - - - - - - - - - jpa - - - basic - - - - - - - - - - - - - - - - - - - default - - - - - - - - ${keycloak.jta.lookup.provider:jboss} - - - - - - - - - - - ${keycloak.x509cert.lookup.provider:default} - - - - default - - - - - - - - - - - - - - - - - - - - - - {% if keycloak_behind_reverse_proxy %} - - {% endif %} - - - - - - - - - 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 }}'