diff --git a/galaxy.yml b/galaxy.yml index 65fe587..ba88e5a 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -15,6 +15,7 @@ tags: - sso dependencies: - "middleware_automation.redhat_csp_download": ">=1.2.1" + - "middleware_automation.jcliff": ">=0.0.19" repository: https://github.com/ansible-middleware/keycloak documentation: https://github.com/ansible-middleware/keycloak homepage: https://github.com/ansible-middleware/keycloak diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..9baaad6 --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,2 @@ +--- +requires_ansible: ">=2.9.10" \ No newline at end of file diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml new file mode 100644 index 0000000..8d43718 --- /dev/null +++ b/molecule/default/converge.yml @@ -0,0 +1,8 @@ +--- +- name: Converge + hosts: all + vars: + tasks: + - name: Include keycloak role + include_role: + name: ../../roles/keycloak \ No newline at end of file diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml new file mode 100644 index 0000000..1b3efda --- /dev/null +++ b/molecule/default/molecule.yml @@ -0,0 +1,51 @@ +--- +dependency: + name: galaxy +driver: + name: docker +platforms: + - name: instance + image: registry.access.redhat.com/ubi8/ubi-init:latest + pre_build_image: true + privileged: true + command: "/usr/sbin/init" + port_bindings: + - "8080/tcp" + - "8443/tcp" + - "8009/tcp" + published_ports: + - 0.0.0.0:8443:8443/TCP +provisioner: + name: ansible + config_options: + defaults: + interpreter_python: auto_silent + ssh_connection: + pipelining: false + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + inventory: + host_vars: + localhost: + ansible_python_interpreter: "{{ ansible_playbook_python }}" + env: + ANSIBLE_FORCE_COLOR: "true" +verifier: + name: ansible +scenario: + test_sequence: + - dependency + - lint + - cleanup + - destroy + - syntax + - create + - prepare + - converge +# - idempotence + - side_effect + - verify + - cleanup + - destroy diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml new file mode 100644 index 0000000..a0fd601 --- /dev/null +++ b/molecule/default/prepare.yml @@ -0,0 +1,8 @@ +--- +- name: Prepare + hosts: all + tasks: + - name: Install sudo + yum: + name: sudo + state: present \ No newline at end of file diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml new file mode 100644 index 0000000..e28ed78 --- /dev/null +++ b/molecule/default/verify.yml @@ -0,0 +1,10 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Populate service facts + ansible.builtin.service_facts: + - name: Check if infinispan service started + assert: + that: + - ansible_facts.services["keycloak.service"]["state"] == "running" diff --git a/playbooks/keycloak.yml b/playbooks/keycloak.yml new file mode 100644 index 0000000..4c4ee4b --- /dev/null +++ b/playbooks/keycloak.yml @@ -0,0 +1,11 @@ +--- +- name: Playbook for Keycloak Hosts + hosts: keycloak + collections: + - middleware_automation.redhat_csp_download + roles: + - redhat_csp_download + tasks: + - name: Keycloak Role + include_role: + name: keycloak \ No newline at end of file diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..1cca528 --- /dev/null +++ b/requirements.yml @@ -0,0 +1,7 @@ +--- +collections: + - name: middleware_automation.redhat_csp_download + version: ">=1.2.1" + - name: middleware_automation.jcliff + version: ">=0.0.19" + - name: community.general diff --git a/roles/keycloak/defaults/main.yml b/roles/keycloak/defaults/main.yml new file mode 100644 index 0000000..af9ccdc --- /dev/null +++ b/roles/keycloak/defaults/main.yml @@ -0,0 +1,71 @@ +--- +### Configuration specific to keycloak +keycloak_version: 9.0.2 +keycloak_archive: keycloak-{{ keycloak_version }}.zip +keycloak_download_url: https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }} +keycloak_local_download_dest: '{{ "~/keycloak_download" | expanduser }}' +keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" + +### Configuration specific to Red Hat Single Sing-On +keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined else False }}" +keycloak_rhsso_client_adapter_rhn_id: '101951' +keycloak_rhsso_saml_adapter_rhn_id: '101901' +keycloak_rhsso_version: 7.5 +keycloak_rhsso_archive: rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip +keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version }}" + +### Install location and service settings +keycloak_dest: /opt/keycloak +keycloak_jboss_home: "{{ keycloak_rhsso_installdir if rhsso_rhn_id is defined else keycloak_installdir }}" +keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" +keycloak_service_user: keycloak +keycloak_service_group: keycloak +keycloak_service_pidfile: "{{ keycloak_dest }}/keycloak.pid" +keycloak_service_logfile: "{{ keycloak_dest }}/keycloak.log" + +### Keycloak configuration settings +keycloak_bind_address: 0.0.0.0 +keycloak_host: localhost +keycloak_http_port: 8080 +keycloak_https_port: 8443 +keycloak_management_http_port: 9990 +keycloak_management_https_port: 9993 +keycloak_java_opts: "-Xms1024m -Xmx20480m -XX:MaxPermSize=768m" +keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" +keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}" +# enable auto configuration for database backend, clustering and remote caches on infinispan +keycloak_ha_enabled: False + +# keycloak administration console user +keycloak_admin_user: admin +keycloak_admin_password: "password" + +keycloak_auth_realm: master +keycloak_auth_client: admin-cli + +keycloak_force_install: False + +keycloak_modcluster: + enabled: "{{ keycloak_ha_enabled }}" + reverse_proxy_url: jbcs-0 + +keycloak_remotecache: + enabled: "{{ keycloak_ha_enabled }}" + username: supervisor + password: itsme + realm: default + server_name: jdg-1 + trust_store_path: /path/to/jks/keystore + trust_store_password: changeme + +keycloak_jdbc: + postgres: + enabled: "{{ keycloak_ha_enabled }}" + driver_module_name: "org.postgresql" + driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/postgresql/main" + driver_version: 9.4.1212 + driver_jar_filename: "postgresql-9.4.1212.jar" + driver_jar_url: "https://repo.maven.apache.org/maven2/org/postgresql/postgresql/9.4.1212/postgresql-9.4.1212.jar" + connection_url: "jdbc:postgresql://pgsql-0:5432/keycloak" + db_user: "keycloak-user" + db_password: "keycloak-pass" diff --git a/roles/keycloak/handlers/main.yml b/roles/keycloak/handlers/main.yml new file mode 100644 index 0000000..6faa06c --- /dev/null +++ b/roles/keycloak/handlers/main.yml @@ -0,0 +1,3 @@ +--- +- name: restart keycloak + include_tasks: restart_keycloak.yml diff --git a/roles/keycloak/meta/main.yml b/roles/keycloak/meta/main.yml new file mode 100644 index 0000000..2cc2def --- /dev/null +++ b/roles/keycloak/meta/main.yml @@ -0,0 +1,56 @@ +galaxy_info: + author: your name + description: your role description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.9 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + +collections: + - middleware_automation.redhat_csp_download + - middleware_automation.jcliff diff --git a/roles/keycloak/tasks/download_from_rhn.yml b/roles/keycloak/tasks/download_from_rhn.yml new file mode 100644 index 0000000..edfcf01 --- /dev/null +++ b/roles/keycloak/tasks/download_from_rhn.yml @@ -0,0 +1,72 @@ +--- +- assert: + that: + - zipfile_dest is defined + - rhn_id_file is defined + - rhn_username is defined + - rhn_password is defined + quiet: true + +- set_fact: + rhn_base_url: "{{ override_rhn_base_url | default('https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=') }}" + rhn_download_url: "{{ rhn_base_url }}{{ rhn_id_file }}" + +- name: "Check zipfile dest directory {{ zipfile_dest }}" + stat: + path: "{{ zipfile_dest }}" + register: archive_path + +- name: "Install zipfile from RHN: {{ rhn_download_url }}" + redhat_csp_download: + url: "{{ rhn_download_url }}" + dest: "{{ zipfile_dest }}" + username: "{{ rhn_username }}" + password: "{{ rhn_password }}" + no_log: "{{ omit_rhn_output | default(true) }}" + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + +- name: "Check zipfile dest directory {{ zipfile_dest }}" + stat: + path: "{{ zipfile_dest }}" + register: path_to_downloaded_artefact + +- block: + - file: + path: "{{ work_dir }}" + state: directory + + - stat: + path: "{{ target_dir }}" + register: target_dir_state + + - assert: + that: + - target_dir_state is defined + - target_dir_state.stat is defined + fail_msg: "Directory layout for {{ target_dir }} is invalid." + quiet: true + + - name: "Decompress {{ zipfile_dest }} into {{ work_dir }} (results in {{ target_dir }}." + unarchive: + src: "{{ zipfile_dest }}" + dest: "{{ work_dir }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_user }}" + remote_src: yes + creates: "{{ target_dir }}" + when: + - not target_dir_state.stat.exists + + - debug: + msg: "{{ target_dir }} already exists, skipping decompressing {{ zipfile_dest }}" + when: + - target_dir_state.stat.exists + when: + - path_to_downloaded_artefact is defined + - path_to_downloaded_artefact.stat is defined + - path_to_downloaded_artefact.stat.exists + - target_dir is defined + - work_dir is defined diff --git a/roles/keycloak/tasks/fastpackages/check.yml b/roles/keycloak/tasks/fastpackages/check.yml new file mode 100644 index 0000000..a31d28b --- /dev/null +++ b/roles/keycloak/tasks/fastpackages/check.yml @@ -0,0 +1,14 @@ +--- +- block: + - name: "Check if package {{ package_name }} is already installed" + command: rpm -q {{ package_name }} + args: + warn: no + register: rpm_info + changed_when: rpm_info.failed + + rescue: + - name: "If package {{ package_name }} is missing, add it to the yum install list." + set_fact: + packages_to_install: "{{ packages_to_install + [ package_name ] }}" + when: rpm_info.failed \ No newline at end of file diff --git a/roles/keycloak/tasks/fastpackages/install.yml b/roles/keycloak/tasks/fastpackages/install.yml new file mode 100644 index 0000000..0f71965 --- /dev/null +++ b/roles/keycloak/tasks/fastpackages/install.yml @@ -0,0 +1,17 @@ +--- +- set_fact: + update_cache: true + packages_to_install: [] + +- name: "Check packages to be installed" + include_tasks: check.yml + loop: "{{ packages_list | flatten }}" + loop_control: + loop_var: package_name + +- name: "Install packages: {{ packages_to_install }}" + become: yes + yum: + name: "{{ packages_to_install }}" + state: present + when: packages_to_install | length > 0 \ No newline at end of file diff --git a/roles/keycloak/tasks/firewalld.yml b/roles/keycloak/tasks/firewalld.yml new file mode 100644 index 0000000..346d58d --- /dev/null +++ b/roles/keycloak/tasks/firewalld.yml @@ -0,0 +1,25 @@ +--- +- name: Ensures required package firewalld are installed + ansible.builtin.include_tasks: fastpackages/install.yml + vars: + packages_list: + - firewalld + +- name: Enable and start the firewalld service + become: yes + systemd: + name: firewalld + enabled: yes + state: started + +- name: Configure firewall for jdg ports + become: yes + ansible.posix.firewalld: + port: "{{ item }}" + permanent: true + state: enabled + immediate: yes + loop: + - "{{ keycloak_http_port }}/tcp" + - "{{ keycloak_https_port }}/tcp" + - "8009/tcp" diff --git a/roles/keycloak/tasks/install.yml b/roles/keycloak/tasks/install.yml new file mode 100644 index 0000000..120ad46 --- /dev/null +++ b/roles/keycloak/tasks/install.yml @@ -0,0 +1,141 @@ +--- +- 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 + +- set_fact: + keycloak_service_group: "{{ keycloak_service_user }}" + when: + - not keycloak_service_group is defined + +- name: check for an existing deployment + become: yes + stat: + path: "{{ keycloak_jboss_home }}" + register: existing_deploy + +- block: + - name: stop the old keycloak service + become: yes + ignore_errors: yes + systemd: + name: keycloak + state: stopped + - name: remove the old Keycloak deployment + become: yes + file: + path: "{{ keycloak_jboss_home }}" + state: absent + when: existing_deploy.stat.exists and keycloak_force_install|bool + +- name: check for an existing deployment after possible forced removal + become: yes + stat: + path: "{{ keycloak_jboss_home }}" + +- name: create Keycloak service user/group + become: yes + user: + name: "{{ keycloak_service_user }}" + home: /opt/keycloak + system: yes + create_home: no + +- name: create Keycloak install location + become: yes + file: + dest: "{{ keycloak_dest }}" + state: directory + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + +- block: + - set_fact: + archive: "{{ keycloak_dest }}/{{ keycloak_archive }}" + - name: "Check archive directory {{ archive }}" + stat: + path: "{{ archive }}" + register: archive_path + + - name: download Keycloak archive to target + get_url: + url: "{{ keycloak_download_url }}" + dest: "{{ keycloak_dest }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + when: + - archive_path is defined + - archive_path.stat is defined + - not archive_path.stat.exists + + - name: extract Keycloak archive on target + unarchive: + remote_src: yes + src: "{{ archive }}" + dest: "{{ keycloak_dest }}" + creates: "{{ keycloak_jboss_home }}" + owner: "{{ keycloak_service_user }}" + group: "{{ keycloak_service_group }}" + notify: + - restart keycloak + become: yes + when: not keycloak_rhsso_enable + +- block: + - assert: + that: + - rhsso_rhn_id is defined + quiet: true + fail_msg: "Can't install RHSSO without RHN ID." + + - name: create download directory + file: + path: /opt/apps + state: directory + + - include_tasks: download_from_rhn.yml + vars: + rhn_id_file: "{{ rhsso_rhn_id }}" + zipfile_dest: "{{ keycloak_dest }}/{{ keycloak_rhsso_archive }}" + work_dir: "{{ keycloak_dest }}" + target_dir: "{{ keycloak_jboss_home }}" + become: yes + when: keycloak_rhsso_enable + +- name: "Install Postresql driver" + include_role: + name: wildfly_driver + tasks_from: jdbc_driver.yml + vars: + wildfly_user: "{{ keycloak_service_user }}" + jdbc_driver_module_dir: "{{ keycloak_jdbc.postgres.driver_module_dir }}" + jdbc_driver_version: "{{ keycloak_jdbc.postgres.driver_version }}" + jdbc_driver_jar_filename: "{{ keycloak_jdbc.postgres.driver_jar_filename }}" + jdbc_driver_jar_url: "{{ keycloak_jdbc.postgres.driver_jar_url }}" + jdbc_driver_jar_installation_path: "{{ keycloak_jdbc.postgres.driver_module_dir }}/{{ keycloak_jdbc.postgres.driver_jar_filename }}" + jdbc_driver_module_name: "{{ keycloak_jdbc.postgres.driver_module_name }}" + when: keycloak_jdbc.postgres.enabled + +- name: "Deploy Keycloak's standalone.xml" + become: yes + template: + src: "{{ 'templates/standalone-rhsso.xml.j2' if keycloak_rhsso_enable else 'templates/standalone.xml.j2' }}" + dest: "{{ keycloak_jboss_home }}/standalone/configuration/standalone.xml" + notify: + - restart keycloak + when: not keycloak_remotecache.enabled + +- name: "Deploy Keycloak's standalone.xml with remote cache store" + become: yes + template: + src: "{{ 'templates/standalone-rhsso-jdg.xml.j2' if keycloak_rhsso_enable else 'templates/standalone-infinispan.xml.j2' }}" + dest: "{{ keycloak_jboss_home }}/standalone/configuration/standalone.xml" + notify: + - restart keycloak + when: keycloak_remotecache.enabled diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml new file mode 100644 index 0000000..97407c9 --- /dev/null +++ b/roles/keycloak/tasks/main.yml @@ -0,0 +1,24 @@ +--- +# tasks file for keycloak + +- name: Prerequisites + include_tasks: prereqs.yml + tags: + - prereqs + +- include_tasks: tasks/install.yml + +- name: create Keycloak admin user + command: + args: + argv: + - "{{ keycloak_jboss_home }}/bin/add-user-keycloak.sh" + - -rmaster + - -u{{ keycloak_admin_user }} + - -p{{ keycloak_admin_password }} + creates: "{{ keycloak_config_dir }}/keycloak-add-user.json" + become: yes + +- include_tasks: tasks/systemd.yml + + diff --git a/roles/keycloak/tasks/manage_client_roles.yml b/roles/keycloak/tasks/manage_client_roles.yml new file mode 100644 index 0000000..d7fca8d --- /dev/null +++ b/roles/keycloak/tasks/manage_client_roles.yml @@ -0,0 +1,12 @@ +- name: Create client roles + community.general.keycloak_role: + name: "{{ item }}" + realm: "{{ client.realm }}" + client_id: "{{ client.name }}" + auth_client_id: "{{ keycloak_auth_client }}" + auth_keycloak_url: "{{ keycloak_url }}/auth" + auth_realm: "{{ keycloak_auth_realm }}" + auth_username: "{{ keycloak_admin_user }}" + auth_password: "{{ keycloak_admin_password }}" + state: present + loop: "{{ client.roles | flatten }}" diff --git a/roles/keycloak/tasks/manage_realm.yml b/roles/keycloak/tasks/manage_realm.yml new file mode 100644 index 0000000..76b260f --- /dev/null +++ b/roles/keycloak/tasks/manage_realm.yml @@ -0,0 +1,73 @@ +--- +- name: Generate keycloak auth token + uri: + url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 5 + delay: 2 + +- name: "Determine if realm exists" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}" + method: GET + status_code: + - 200 + - 404 + headers: + Accept: "application/json" + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_realm_exists + +- name: Create Realm + uri: + url: "{{ keycloak_url }}/auth/admin/realms" + method: POST + body: "{{ lookup('template','realm.json.j2') }}" + validate_certs: no + body_format: json + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + status_code: 201 + when: keycloak_realm_exists.status == 404 + +- name: Create Client + community.general.keycloak_client: + auth_client_id: "{{ keycloak_auth_client }}" + auth_keycloak_url: "{{ keycloak_url }}/auth" + auth_realm: "{{ keycloak_auth_realm }}" + auth_username: "{{ keycloak_admin_user }}" + auth_password: "{{ keycloak_admin_password }}" + client_id: "{{ item.name }}" + realm: "{{ item.realm }}" + default_roles: "{{ item.roles | default(omit) }}" + root_url: "{{ item.root_url | default('') }}" + redirect_uris: "{{ demo_app_redirect_uris | default([]) }}" + public_client: "{{ item.public_client | default(False) }}" + web_origins: "{{ item.web_origins | default('+') }}" + state: present + register: create_client_result + loop: "{{ keycloak_clients | flatten }}" + +- name: Create client roles + include_tasks: manage_client_roles.yml + when: keycloak_rhsso_enable + loop: "{{ keycloak_clients | flatten }}" + loop_control: + loop_var: client + +- name: Manage Users + include_tasks: manage_user.yml + loop: "{{ keycloak_users }}" + loop_control: + loop_var: user + +- name: Manage User Roles + include_tasks: manage_user_roles.yml + loop: "{{ keycloak_users | flatten }}" + loop_control: + loop_var: user + when: "'client_roles' in user" \ No newline at end of file diff --git a/roles/keycloak/tasks/manage_user.yml b/roles/keycloak/tasks/manage_user.yml new file mode 100644 index 0000000..019d65b --- /dev/null +++ b/roles/keycloak/tasks/manage_user.yml @@ -0,0 +1,51 @@ +--- +- name: "Check if User Already Exists" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + validate_certs: no + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_user_serach_result + +- name: "Create User" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users" + method: POST + body: + enabled: true + attributes: "{{ user.attributes | default(omit) }}" + username: "{{ user.username }}" + email: "{{ user.email | default(omit) }}" + firstName: "{{ user.firstName | default(omit) }}" + lastName: "{{ user.lastName | default(omit) }}" + validate_certs: no + body_format: json + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + status_code: 201 + when: keycloak_user_serach_result.json | length == 0 + +- name: "Get User" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + validate_certs: no + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_user + +- name: "Update User Password" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users/{{ (keycloak_user.json | first).id }}/reset-password" + method: PUT + body: + type: password + temporary: false + value: "{{ user.password }}" + validate_certs: no + body_format: json + status_code: + - 200 + - 204 + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_user diff --git a/roles/keycloak/tasks/manage_user_client_roles.yml b/roles/keycloak/tasks/manage_user_client_roles.yml new file mode 100644 index 0000000..562ff09 --- /dev/null +++ b/roles/keycloak/tasks/manage_user_client_roles.yml @@ -0,0 +1,40 @@ +--- +- name: "Get Realm for role" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: client_role_realm + +- name: Check if Mapping is available + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available" + method: GET + status_code: + - 200 + headers: + Accept: "application/json" + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: client_role_user_available + +- name: "Create Role Mapping" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ client_role.realm }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}" + method: POST + body: + - id: "{{ item.id }}" + clientRole: "{{ item.clientRole }}" + containerId: "{{ item.containerId }}" + name: "{{ item.name }}" + composite: "{{ item.composite }}" + validate_certs: False + body_format: json + headers: + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + status_code: 204 + loop: "{{ client_role_user_available.json | flatten }}" + when: item.name == client_role.role diff --git a/roles/keycloak/tasks/manage_user_roles.yml b/roles/keycloak/tasks/manage_user_roles.yml new file mode 100644 index 0000000..82ee948 --- /dev/null +++ b/roles/keycloak/tasks/manage_user_roles.yml @@ -0,0 +1,26 @@ +--- + +- name: "Get User {{ user.username }}" + uri: + url: "{{ keycloak_url }}/auth/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}" + headers: + validate_certs: no + Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}" + register: keycloak_user + +- name: Refresh keycloak auth token + uri: + url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password" + validate_certs: no + register: keycloak_auth_response + until: keycloak_auth_response.status == 200 + retries: 5 + delay: 2 + +- name: "Manage Client Role Mapping for {{ user.username }}" + include_tasks: manage_user_client_roles.yml + loop: "{{ user.client_roles | flatten }}" + loop_control: + loop_var: client_role diff --git a/roles/keycloak/tasks/prereqs.yml b/roles/keycloak/tasks/prereqs.yml new file mode 100644 index 0000000..b6abb88 --- /dev/null +++ b/roles/keycloak/tasks/prereqs.yml @@ -0,0 +1,12 @@ +--- +- set_fact: + required_packages: + - "{{ jvm_package | default('java-1.8.0-openjdk-devel') }}" + - unzip + - procps-ng + - initscripts + +- name: "Ensures required packages are installed" + ansible.builtin.include_tasks: fastpackages/install.yml + vars: + packages_list: "{{ required_packages }}" \ No newline at end of file diff --git a/roles/keycloak/tasks/restart_keycloak.yml b/roles/keycloak/tasks/restart_keycloak.yml new file mode 100644 index 0000000..774d14d --- /dev/null +++ b/roles/keycloak/tasks/restart_keycloak.yml @@ -0,0 +1,7 @@ +--- +- name: "Restart and enable keycloack service" + systemd: + name: keycloak + enabled: yes + state: restarted + become: yes diff --git a/roles/keycloak/tasks/stop_keycloak.yml b/roles/keycloak/tasks/stop_keycloak.yml new file mode 100644 index 0000000..d6203b2 --- /dev/null +++ b/roles/keycloak/tasks/stop_keycloak.yml @@ -0,0 +1,7 @@ +--- +- name: "Stop SSO service" + systemd: + name: keycloak + enabled: yes + state: stopped + become: yes diff --git a/roles/keycloak/tasks/systemd.yml b/roles/keycloak/tasks/systemd.yml new file mode 100644 index 0000000..67fd2e1 --- /dev/null +++ b/roles/keycloak/tasks/systemd.yml @@ -0,0 +1,65 @@ +- name: configure keycloak service script wrapper + become: yes + template: + src: keycloak-service.sh.j2 + dest: "{{ keycloak_dest }}/keycloak-service.sh" + owner: root + group: root + mode: 0755 + notify: + - restart keycloak + +- name: configure sysconfig file for keycloak service + become: yes + template: + src: keycloak-sysconfig.j2 + dest: /etc/sysconfig/keycloak + owner: root + group: root + mode: 0644 + notify: + - restart keycloak + +- name: configure systemd unit file for keycloak service + template: + src: keycloak.service.j2 + dest: /etc/systemd/system/keycloak.service + owner: root + group: root + mode: 0644 + become: yes + register: systemdunit + notify: + - restart keycloak + +- name: reload systemd + become: yes + systemd: + daemon_reload: yes + when: systemdunit.changed + +- name: start keycloak + systemd: + name: keycloak + enabled: yes + state: started + become: yes + +- command: "systemctl status keycloak" + register: keycloak_service_status + changed_when: False + +- assert: + that: + - keycloak_service_status is defined + - keycloak_service_status.stdout is defined + +- meta: flush_handlers + +- name: Wait until Keycloak becomes active + uri: + url: "{{ keycloak_management_url }}/health" + register: keycloak_status + until: keycloak_status.status == 200 + retries: 20 + delay: 10 diff --git a/roles/keycloak/templates/keycloak-service.sh.j2 b/roles/keycloak/templates/keycloak-service.sh.j2 new file mode 100755 index 0000000..ebbecf0 --- /dev/null +++ b/roles/keycloak/templates/keycloak-service.sh.j2 @@ -0,0 +1,125 @@ +#!/bin/bash +set -eo pipefail + +checkEnvVar() { + local envVar=${1} + local msg=${2} + local exitCode=${3} + + if [ -z "${envVar}" ]; then + echo "${msg}" + exit "${exitCode}" + fi +} +# SystemD will do for the unit, decomment +# for testing outside systemd +. /etc/sysconfig/keycloak + +readonly KEYCLOAK_HOME={{ keycloak_jboss_home }} +readonly KEYCLOAK_BIND_ADDRESS=${KEYCLOAK_BIND_ADDRESS} +readonly KEYCLOAK_HTTP_PORT=${KEYCLOAK_HTTP_PORT} +readonly KEYCLOAK_HTTPS_PORT=${KEYCLOAK_HTTPS_PORT} +readonly KEYCLOAK_MANAGEMENT_HTTP_PORT=${KEYCLOAK_MANAGEMENT_HTTP_PORT} +readonly KEYCLOAK_MANAGEMENT_HTTPS_PORT=${KEYCLOAK_MANAGEMENT_HTTPS_PORT} +readonly KEYCLOAK_LOGFILE={{ keycloak_service_logfile }} +readonly KEYCLOAK_PIDFILE={{ keycloak_service_pidfile }} + +set -u +if [ ! -d "${KEYCLOAK_HOME}" ]; then + echo "KEYCLOAK_HOME (${KEYCLOAK_HOME}) is not a director or does not exists." + exit 1 +fi + +checkEnvVar "${KEYCLOAK_PIDFILE}" 'KEYCLOAK_PIDFILE not provided' 2 + +getKeycloakPID() { + + local pid + if [ -e "${KEYCLOAK_PIDFILE}" ]; then + cat "${KEYCLOAK_PIDFILE}" + fi +} + +statusKeycloak() { + + if [ "$(isKeyCloakRunning)" -eq 1 ]; then + echo "Keycloak is running (PID:$(getKeycloakPID ))" + else + echo "Keycloak is NOT running." + fi +} + +isKeyCloakRunning() { + set +e + local statusKeycloak=0 + local pid=$(getKeycloakPID ) + if [ -n "${pid}" ]; then + kill -0 "${pid}" 2> /dev/null + if [ "${?}" -eq 0 ]; then + statusKeycloak=1 + fi + fi + set -e + echo "${statusKeycloak}" +} + +startKeycloak() { + checkEnvVar "${KEYCLOAK_BIND_ADDRESS}" 'KEYCLOAK_BIND_ADDRESS not provided' 2 + checkEnvVar "${KEYCLOAK_HTTP_PORT}" 'KEYCLOAK_HTTP_PORT not provided' 4 + checkEnvVar "${KEYCLOAK_HTTPS_PORT}" 'KEYCLOAK_HTTPS_PORT not provided' 5 + checkEnvVar "${KEYCLOAK_MANAGEMENT_HTTP_PORT}" 'KEYCLOAK_MANAGEMENT_HTTP_PORT not provided' 6 + checkEnvVar "${KEYCLOAK_MANAGEMENT_HTTPS_PORT}" 'KEYCLOAK_MANAGEMENT_HTTPS_PORT not provided' 7 + checkEnvVar "${KEYCLOAK_LOGFILE}" 'KEYCLOAK_LOGFILE not provided' 8 + + if [ "$(isKeyCloakRunning)" -eq 1 ]; then + statusKeycloak + else + ${KEYCLOAK_HOME}/bin/standalone.sh \ + -Djboss.bind.address=${KEYCLOAK_BIND_ADDRESS} \ + -Djboss.http.port=${KEYCLOAK_HTTP_PORT} \ + -Djboss.https.port=${KEYCLOAK_HTTPS_PORT} \ + -Djboss.management.http.port=${KEYCLOAK_MANAGEMENT_HTTP_PORT} \ + -Djboss.management.https.port=${KEYCLOAK_MANAGEMENT_HTTPS_PORT} \ + -Djboss.node.name={{ inventory_hostname }} 2>&1 >> "${KEYCLOAK_LOGFILE}" & + echo "${!}" > "${KEYCLOAK_PIDFILE}" + fi +} + +stopKeycloak() { + local pid=$(getKeycloakPID) + if [ -n "${pid}" ]; then + set +e + kill ${pid} 2> /dev/null + kill -0 "${pid}" 2> /dev/null +# if [ "${?}" -eq 0 ]; then +# sleep 5 +# kill -9 "${pid}" > /dev/null +# fi + set -e + deletePidFile + fi +} + +deletePidFile() { + rm -f "${KEYCLOAK_PIDFILE}" +} + +case "$1" in + start) + startKeycloak + ;; + stop) + stopKeycloak + ;; + restart) + stopKeycloak + startKeycloak + ;; + status) + statusKeycloak + ;; + *) + echo "usage: $0 start|stop|restart" >&2 + exit 1 + ;; +esac diff --git a/roles/keycloak/templates/keycloak-sysconfig.j2 b/roles/keycloak/templates/keycloak-sysconfig.j2 new file mode 100644 index 0000000..d0682ac --- /dev/null +++ b/roles/keycloak/templates/keycloak-sysconfig.j2 @@ -0,0 +1,7 @@ +JAVA_OPTS='{{ keycloak_java_opts }}' +JBOSS_HOME={{ keycloak_jboss_home }} +KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }} +KEYCLOAK_HTTP_PORT={{ keycloak_http_port }} +KEYCLOAK_HTTPS_PORT={{ keycloak_https_port }} +KEYCLOAK_MANAGEMENT_HTTP_PORT={{ keycloak_management_http_port }} +KEYCLOAK_MANAGEMENT_HTTPS_PORT={{ keycloak_management_https_port }} diff --git a/roles/keycloak/templates/keycloak.service.j2 b/roles/keycloak/templates/keycloak.service.j2 new file mode 100644 index 0000000..a3aa846 --- /dev/null +++ b/roles/keycloak/templates/keycloak.service.j2 @@ -0,0 +1,19 @@ +[Unit] +Description=Keycloak Server +After=network.target + +[Service] +Type=forking +EnvironmentFile=-/etc/sysconfig/keycloak + +User={{ keycloak_service_user }} +Group={{ keycloak_service_group }} +PIDFile={{ keycloak_service_pidfile }} +ExecStart={{ keycloak_dest }}/keycloak-service.sh start +ExecStop={{ keycloak_dest }}/keycloak-service.sh stop +TimeoutStartSec=60 +TimeoutStopSec=60 +LimitNOFILE=102642 + +[Install] +WantedBy=multi-user.target diff --git a/roles/keycloak/templates/realm.json.j2 b/roles/keycloak/templates/realm.json.j2 new file mode 100644 index 0000000..88ee819 --- /dev/null +++ b/roles/keycloak/templates/realm.json.j2 @@ -0,0 +1,7 @@ +{ + "id": "{{ keycloak_realm }}", + "realm": "{{ keycloak_realm }}", + "enabled": true, + "eventsEnabled": true, + "eventsExpiration": 7200 +} \ No newline at end of file diff --git a/roles/keycloak/templates/standalone-infinispan.xml.j2 b/roles/keycloak/templates/standalone-infinispan.xml.j2 new file mode 100644 index 0000000..d63072a --- /dev/null +++ b/roles/keycloak/templates/standalone-infinispan.xml.j2 @@ -0,0 +1,719 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + +{% if keycloak_jdbc.postgres.enabled %} + {{ keycloak_jdbc.postgres.connection_url }} + {{ keycloak_jdbc.postgres.driver_module_name }} + + 20 + + + {{ keycloak_jdbc.postgres.db_user }} + {{ keycloak_jdbc.postgres.db_password }} + +{% else %} + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + +{% endif %} + + +{% if keycloak_jdbc.postgres.enabled %} + + org.postgresql.Driver + org.postgresql.xa.PGXADataSource + +{% endif %} + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% for cachename in [ "sessions", "offlineSessions", "clientSessions", "offlineClientSessions", "loginFailures", "actionTokens" ] %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism | default('SCRAM-SHA-512') }} + false + {{ keycloak_remotecache.trust_store_path | default('/etc/truststore/truststore.jks') }} + JKS + {{ keycloak_remotecache.trust_store_password | default("changeme") }} + + + {% endfor %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism | default('SCRAM-SHA-512') }} + false + {{ keycloak_remotecache.trust_store_path | default('/etc/truststore/truststore.jks') }} + JKS + {{ keycloak_remotecache.trust_store_password | default("changeme") }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + +{% endif %} + + + + + diff --git a/roles/keycloak/templates/standalone-rhsso-jdg.xml.j2 b/roles/keycloak/templates/standalone-rhsso-jdg.xml.j2 new file mode 100644 index 0000000..c308dde --- /dev/null +++ b/roles/keycloak/templates/standalone-rhsso-jdg.xml.j2 @@ -0,0 +1,719 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE + h2 + + sa + sa + + + +{% if keycloak_jdbc.postgres.enabled %} + {{ keycloak_jdbc.postgres.connection_url }} + {{ keycloak_jdbc.postgres.driver_module_name }} + + 20 + + + {{ keycloak_jdbc.postgres.db_user }} + {{ keycloak_jdbc.postgres.db_password }} + +{% else %} + jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE + h2 + + sa + sa + +{% endif %} + + +{% if keycloak_jdbc.postgres.enabled %} + + org.postgresql.Driver + org.postgresql.xa.PGXADataSource + +{% endif %} + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% for cachename in [ "sessions", "offlineSessions", "clientSessions", "offlineClientSessions", "loginFailures", "actionTokens" ] %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism | default('SCRAM-SHA-512') }} + false + {{ keycloak_remotecache.trust_store_path | default('/etc/truststore/truststore.jks') }} + JKS + {{ keycloak_remotecache.trust_store_password | default("changeme") }} + + + {% endfor %} + + + true + org.keycloak.cluster.infinispan.KeycloakHotRodMarshallerFactory + false + {{ keycloak_remotecache.username }} + {{ keycloak_remotecache.password }} + {{ keycloak_remotecache.realm | default('default') }} + {{ keycloak_remotecache.server_name }} + {{ keycloak_remotecache.sasl_mechanism | default('SCRAM-SHA-512') }} + false + {{ keycloak_remotecache.trust_store_path | default('/etc/truststore/truststore.jks') }} + JKS + {{ keycloak_remotecache.trust_store_password | default("changeme") }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + +{% endif %} + + + + + diff --git a/roles/keycloak/templates/standalone-rhsso.xml.j2 b/roles/keycloak/templates/standalone-rhsso.xml.j2 new file mode 100644 index 0000000..777aa85 --- /dev/null +++ b/roles/keycloak/templates/standalone-rhsso.xml.j2 @@ -0,0 +1,632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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_modcluster.enabled %} + + + + + + + +{% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + +{% endif %} + + diff --git a/roles/keycloak/templates/standalone.xml.j2 b/roles/keycloak/templates/standalone.xml.j2 new file mode 100644 index 0000000..9e620b2 --- /dev/null +++ b/roles/keycloak/templates/standalone.xml.j2 @@ -0,0 +1,614 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + org.h2.jdbcx.JdbcDataSource + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{% if keycloak_modcluster.enabled %} + + + + + + + +{% 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_modcluster.enabled %} + + + +{% endif %} + + diff --git a/roles/keycloak/vars/main.yml b/roles/keycloak/vars/main.yml new file mode 100644 index 0000000..203b6d7 --- /dev/null +++ b/roles/keycloak/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for keycloak \ No newline at end of file