--- - name: Validate parameters ansible.builtin.assert: that: - keycloak_jboss_home is defined - keycloak_service_user is defined - keycloak_dest is defined - keycloak_archive is defined - keycloak_download_url is defined - keycloak_version is defined quiet: true - name: Check for an existing deployment become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" register: existing_deploy - name: Stop and restart if existing deployment exists and install forced when: existing_deploy.stat.exists and keycloak_force_install | bool block: - name: "Stop the old {{ keycloak.service_name }} service" become: true failed_when: false ansible.builtin.systemd: name: keycloak state: stopped - name: "Remove the old {{ keycloak.service_name }} deployment" become: true ansible.builtin.file: path: "{{ keycloak_jboss_home }}" state: absent - name: Check for an existing deployment after possible forced removal become: true ansible.builtin.stat: path: "{{ keycloak_jboss_home }}" - name: "Create service user/group for {{ keycloak.service_name }}" become: true ansible.builtin.user: name: "{{ keycloak_service_user }}" home: /opt/keycloak system: yes create_home: no - name: "Create install location for {{ keycloak.service_name }}" become: true ansible.builtin.file: dest: "{{ keycloak_dest }}" state: directory owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0750 - name: Create pidfile folder become: true ansible.builtin.file: dest: "{{ keycloak_service_pidfile | dirname }}" state: directory owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}" group: "{{ keycloak_service_group if keycloak_service_runas else omit }}" mode: 0750 ## check remote archive - name: Set download archive path ansible.builtin.set_fact: archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}" - name: Check download archive path become: true ansible.builtin.stat: path: "{{ archive }}" register: archive_path ## download to controller - name: Check local download archive path ansible.builtin.stat: path: "{{ lookup('env', 'PWD') }}" register: local_path delegate_to: localhost - name: Download keycloak archive ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost run_once: true when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - not sso_enable is defined or not sso_enable - not keycloak_offline_install - name: Perform download from RHN using JBoss Network API delegate_to: localhost run_once: true when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - sso_enable is defined and sso_enable - not keycloak_offline_install block: - name: Retrieve product download using JBoss Network API middleware_automation.common.product_search: client_id: "{{ rhn_username }}" client_secret: "{{ rhn_password }}" product_type: DISTRIBUTION product_version: "{{ sso_version.split('.')[:2] | join('.') }}" product_category: "{{ sso_product_category }}" register: rhn_products no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost run_once: true - name: Determine install zipfile from search results ansible.builtin.set_fact: rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}" delegate_to: localhost run_once: true - name: Download Red Hat Single Sign-On middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user client_id: "{{ rhn_username }}" client_secret: "{{ rhn_password }}" product_id: "{{ (rhn_filtered_products | first).id }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" no_log: "{{ omit_rhn_output | default(true) }}" delegate_to: localhost run_once: true - name: Download rhsso archive from alternate location ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user url: "{{ keycloak_rhsso_download_url }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" mode: 0644 delegate_to: localhost run_once: true when: - archive_path is defined - archive_path.stat is defined - not archive_path.stat.exists - sso_enable is defined and sso_enable - not keycloak_offline_install - keycloak_rhsso_download_url is defined - name: Check downloaded archive ansible.builtin.stat: path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" register: local_archive_path delegate_to: localhost ## copy and unpack - name: Copy archive to target nodes ansible.builtin.copy: src: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ archive }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 register: new_version_downloaded when: - not archive_path.stat.exists - local_archive_path.stat is defined - local_archive_path.stat.exists become: true - name: "Check target directory: {{ keycloak.home }}" ansible.builtin.stat: path: "{{ keycloak.home }}" register: path_to_workdir become: true - name: "Extract {{ keycloak_service_desc }} archive on target" ansible.builtin.unarchive: remote_src: true src: "{{ archive }}" dest: "{{ keycloak_dest }}" creates: "{{ keycloak.home }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" become: true when: - new_version_downloaded.changed or not path_to_workdir.stat.exists notify: - restart keycloak - name: Inform decompression was not executed ansible.builtin.debug: msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression" when: - not new_version_downloaded.changed and path_to_workdir.stat.exists - name: "Reown installation directory to {{ keycloak_service_user }}" ansible.builtin.file: path: "{{ keycloak.home }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" recurse: true become: true changed_when: false - name: Ensure permissions are correct on existing deploy ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}" when: keycloak_service_runas become: true changed_when: false # driver and configuration - name: "Install {{ keycloak_jdbc_engine }} driver" ansible.builtin.include_tasks: jdbc_driver.yml when: keycloak_jdbc[keycloak_jdbc_engine].enabled - name: "Deploy custom {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak_config_override_template }}" become: true ansible.builtin.template: src: "templates/{{ keycloak_config_override_template }}" dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak when: keycloak_config_override_template | length > 0 - name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" become: true ansible.builtin.template: src: templates/standalone.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak when: - not keycloak_ha_enabled - keycloak_config_override_template | length == 0 - name: Create tcpping cluster node list ansible.builtin.set_fact: keycloak_cluster_nodes: > {{ keycloak_cluster_nodes | default([]) + [ { "name": item, "address": 'jgroups-' + item, "inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_jgroups_port | string) + ']', "value": hostvars[item].ansible_default_ipv4.address | default(item) } ] }} loop: "{{ ansible_play_batch }}" when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING' - name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}" become: true ansible.builtin.template: src: templates/standalone-ha.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak when: - keycloak_ha_enabled - not keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 - name: "Deploy HA {{ keycloak.service_name }} config with infinispan remote cache store to {{ keycloak_config_path_to_standalone_xml }}" become: true ansible.builtin.template: src: templates/standalone-infinispan.xml.j2 dest: "{{ keycloak_config_path_to_standalone_xml }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak when: - keycloak_ha_enabled - keycloak_remote_cache_enabled - keycloak_config_override_template | length == 0 - name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}" become: true ansible.builtin.template: src: keycloak-profile.properties.j2 dest: "{{ keycloak_config_path_to_properties }}" owner: "{{ keycloak_service_user }}" group: "{{ keycloak_service_group }}" mode: 0640 notify: - restart keycloak when: keycloak_features | length > 0