Compare commits

..

2 Commits

Author SHA1 Message Date
Romain Pelisse
57b3cb380b Rework Molecule prepare phase to install sudo only if root on target 2024-03-04 21:30:23 +01:00
Romain Pelisse
d8286dfca7 Rework Molecule prepare phase to install sudo only if root on target 2024-03-04 21:13:06 +01:00
83 changed files with 494 additions and 1316 deletions

View File

@@ -15,4 +15,4 @@ jobs:
with: with:
fqcn: 'middleware_automation/keycloak' fqcn: 'middleware_automation/keycloak'
molecule_tests: >- molecule_tests: >-
[ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "debian" ] [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ]

View File

@@ -15,4 +15,3 @@ jobs:
with: with:
fqcn: 'middleware_automation/keycloak' fqcn: 'middleware_automation/keycloak'
collection_fqcn: 'middleware_automation.keycloak' collection_fqcn: 'middleware_automation.keycloak'
historical_docs: 'false'

View File

@@ -2,27 +2,20 @@
name: Release collection name: Release collection
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
release_summary:
description: 'Optional release summary for changelogs'
required: false
jobs: jobs:
release: release:
uses: ansible-middleware/github-actions/.github/workflows/release.yml@main uses: ansible-middleware/github-actions/.github/workflows/release.yml@main
with: with:
collection_fqcn: 'middleware_automation.keycloak' collection_fqcn: 'middleware_automation.keycloak'
downstream_name: 'rhbk'
release_summary: "${{ github.event.inputs.release_summary }}"
secrets: secrets:
galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }}
jira_webhook: ${{ secrets.JIRA_WEBHOOK_CREATE_VERSION }}
dispatch: dispatch:
needs: release needs: release
strategy: strategy:
matrix: matrix:
repo: ['ansible-middleware/ansible-middleware-ee'] repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo', 'ansible-middleware/ansible-middleware-ee']
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Repository Dispatch - name: Repository Dispatch

View File

@@ -6,51 +6,6 @@ middleware\_automation.keycloak Release Notes
This changelog describes changes after version 0.2.6. This changelog describes changes after version 0.2.6.
v2.2.0
======
Major Changes
-------------
- Support java keystore for configuration of sensitive options `#189 <https://github.com/ansible-middleware/keycloak/pull/189>`_
Minor Changes
-------------
- Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 <https://github.com/ansible-middleware/keycloak/pull/199>`_
- Customize jdbc driver downloads, optional authentication `#202 <https://github.com/ansible-middleware/keycloak/pull/202>`_
- Keystore-based vault SPI configuration `#196 <https://github.com/ansible-middleware/keycloak/pull/196>`_
- New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 <https://github.com/ansible-middleware/keycloak/pull/195>`_
- Providers config and custom providers `#201 <https://github.com/ansible-middleware/keycloak/pull/201>`_
- Remove administrator credentials from files once keycloak is bootstrapped `#197 <https://github.com/ansible-middleware/keycloak/pull/197>`_
- Update keycloak to 24.0 `#194 <https://github.com/ansible-middleware/keycloak/pull/194>`_
v2.1.2
======
Release Summary
---------------
Internal release, documentation or test changes only.
v2.1.1
======
Minor Changes
-------------
- Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 <https://github.com/ansible-middleware/keycloak/pull/187>`_
- Debian/Ubuntu compatibility `#178 <https://github.com/ansible-middleware/keycloak/pull/178>`_
- Use ``keycloak_realm`` as default for sub-entities `#180 <https://github.com/ansible-middleware/keycloak/pull/180>`_
Bugfixes
--------
- Fix permissions on controller-side downloaded artifacts `#184 <https://github.com/ansible-middleware/keycloak/pull/184>`_
- JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 <https://github.com/ansible-middleware/keycloak/pull/186>`_
- Unrelax configuration file permissions `#191 <https://github.com/ansible-middleware/keycloak/pull/191>`_
- Utilize comment filter for ``ansible_managed`` annotations `#176 <https://github.com/ansible-middleware/keycloak/pull/176>`_
v2.1.0 v2.1.0
====== ======
@@ -299,11 +254,6 @@ Minor Changes
v1.0.4 v1.0.4
====== ======
Release Summary
---------------
Internal release, documentation or test changes only.
v1.0.3 v1.0.3
====== ======

View File

@@ -1,9 +1,8 @@
python3-dev [compile platform:dpkg]
python3-devel [compile platform:rpm] python3-devel [compile platform:rpm]
python39-devel [compile platform:centos-8 platform:rhel-8] python39-devel [compile platform:centos-8 platform:rhel-8]
git-lfs [platform:rpm platform:dpkg] git-lfs [platform:rpm]
python3-netaddr [platform:rpm platform:dpkg] python3-netaddr [platform:rpm]
python3-lxml [platform:rpm platform:dpkg] python3-lxml [platform:rpm]
python3-jmespath [platform:rpm platform:dpkg] python3-jmespath [platform:rpm]
python3-requests [platform:rpm platform:dpkg] python3-requests [platform:rpm]

View File

@@ -59,10 +59,6 @@ releases:
- 31.yaml - 31.yaml
release_date: '2022-05-09' release_date: '2022-05-09'
1.0.4: 1.0.4:
changes:
release_summary: 'Internal release, documentation or test changes only.
'
release_date: '2022-05-11' release_date: '2022-05-11'
1.0.5: 1.0.5:
changes: changes:
@@ -423,83 +419,3 @@ releases:
- 167.yaml - 167.yaml
- 171.yaml - 171.yaml
release_date: '2024-02-28' release_date: '2024-02-28'
2.1.1:
changes:
bugfixes:
- 'Fix permissions on controller-side downloaded artifacts `#184 <https://github.com/ansible-middleware/keycloak/pull/184>`_
'
- 'JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186
<https://github.com/ansible-middleware/keycloak/pull/186>`_
'
- 'Unrelax configuration file permissions `#191 <https://github.com/ansible-middleware/keycloak/pull/191>`_
'
- 'Utilize comment filter for ``ansible_managed`` annotations `#176 <https://github.com/ansible-middleware/keycloak/pull/176>`_
'
minor_changes:
- 'Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 <https://github.com/ansible-middleware/keycloak/pull/187>`_
'
- 'Debian/Ubuntu compatibility `#178 <https://github.com/ansible-middleware/keycloak/pull/178>`_
'
- 'Use ``keycloak_realm`` as default for sub-entities `#180 <https://github.com/ansible-middleware/keycloak/pull/180>`_
'
fragments:
- 176.yaml
- 178.yaml
- 180.yaml
- 184.yaml
- 186.yaml
- 187.yaml
- 191.yaml
release_date: '2024-04-17'
2.1.2:
changes:
release_summary: 'Internal release, documentation or test changes only.
'
release_date: '2024-04-17'
2.2.0:
changes:
major_changes:
- 'Support java keystore for configuration of sensitive options `#189 <https://github.com/ansible-middleware/keycloak/pull/189>`_
'
minor_changes:
- 'Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 <https://github.com/ansible-middleware/keycloak/pull/199>`_
'
- 'Customize jdbc driver downloads, optional authentication `#202 <https://github.com/ansible-middleware/keycloak/pull/202>`_
'
- 'Keystore-based vault SPI configuration `#196 <https://github.com/ansible-middleware/keycloak/pull/196>`_
'
- 'New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 <https://github.com/ansible-middleware/keycloak/pull/195>`_
'
- 'Providers config and custom providers `#201 <https://github.com/ansible-middleware/keycloak/pull/201>`_
'
- 'Remove administrator credentials from files once keycloak is bootstrapped
`#197 <https://github.com/ansible-middleware/keycloak/pull/197>`_
'
- 'Update keycloak to 24.0 `#194 <https://github.com/ansible-middleware/keycloak/pull/194>`_
'
fragments:
- 189.yaml
- 194.yaml
- 195.yaml
- 196.yaml
- 197.yaml
- 199.yaml
- 201.yaml
- 202.yaml
release_date: '2024-05-01'

View File

@@ -24,15 +24,14 @@
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu"> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Middleware Automation</span></p> <p class="caption" role="heading"><span class="caption-text">Middleware Automation</span></p>
<ul> <ul>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/infinispan/main/">Infinispan / Red Hat Data Grid</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/infinispan/">Infinispan / Red Hat Data Grid</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/keycloak/main/">Keycloak / Red Hat Single Sign-On</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/keycloak/">Keycloak / Red Hat Single Sign-On</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/wildfly/main/">Wildfly / Red Hat JBoss EAP</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/wildfly/">Wildfly / Red Hat JBoss EAP</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/jws/main/">Tomcat / Red Hat JWS</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/jws/">Tomcat / Red Hat JWS</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq/main/">ActiveMQ / Red Hat AMQ Broker</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq/">ActiveMQ / Red Hat AMQ Broker</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq_streams/main/">Kafka / Red Hat AMQ Streams</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/amq_streams/">Kafka / Red Hat AMQ Streams</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/common/main/">Ansible Middleware utilities</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/redhat-csp-download/">Red Hat CSP Download</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/redhat-csp-download/main/">Red Hat CSP Download</a></li> <li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/ansible_collections_jcliff/">JCliff</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/ansible_collections_jcliff/main/">JCliff</a></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -29,12 +29,11 @@ Welcome to Keycloak Collection documentation
:maxdepth: 2 :maxdepth: 2
:caption: Middleware collections :caption: Middleware collections
Infinispan / Red Hat Data Grid <https://ansible-middleware.github.io/infinispan/main/> Infinispan / Red Hat Data Grid <https://ansible-middleware.github.io/infinispan/>
Keycloak / Red Hat Single Sign-On <https://ansible-middleware.github.io/keycloak/main/> Keycloak / Red Hat Single Sign-On <https://ansible-middleware.github.io/keycloak/>
Wildfly / Red Hat JBoss EAP <https://ansible-middleware.github.io/wildfly/main/> Wildfly / Red Hat JBoss EAP <https://ansible-middleware.github.io/wildfly/>
Tomcat / Red Hat JWS <https://ansible-middleware.github.io/jws/main/> Tomcat / Red Hat JWS <https://ansible-middleware.github.io/jws/>
ActiveMQ / Red Hat AMQ Broker <https://ansible-middleware.github.io/amq/main/> ActiveMQ / Red Hat AMQ Broker <https://ansible-middleware.github.io/amq/>
Kafka / Red Hat AMQ Streams <https://ansible-middleware.github.io/amq_streams/main/> Kafka / Red Hat AMQ Streams <https://ansible-middleware.github.io/amq_streams/>
Ansible Middleware utilities <https://ansible-middleware.github.io/common/main/> Red Hat CSP Download <https://ansible-middleware.github.io/redhat-csp-download/>
Red Hat CSP Download <https://ansible-middleware.github.io/redhat-csp-download/main/> JCliff <https://ansible-middleware.github.io/ansible_collections_jcliff/>
JCliff <https://ansible-middleware.github.io/ansible_collections_jcliff/main/>

View File

@@ -1,7 +1,7 @@
--- ---
namespace: middleware_automation namespace: middleware_automation
name: keycloak name: keycloak
version: "2.2.0" version: "2.1.1"
readme: README.md readme: README.md
authors: authors:
- Romain Pelisse <rpelisse@redhat.com> - Romain Pelisse <rpelisse@redhat.com>
@@ -35,6 +35,7 @@ issues: https://github.com/ansible-middleware/keycloak/issues
build_ignore: build_ignore:
- .gitignore - .gitignore
- .github - .github
- .ansible-lint
- .yamllint - .yamllint
- '*.tar.gz' - '*.tar.gz'
- '*.zip' - '*.zip'

View File

@@ -1,41 +0,0 @@
---
- name: Converge
hosts: all
vars:
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_realm: TestRealm
keycloak_quarkus_log: file
keycloak_quarkus_frontend_url: 'http://localhost:8080/'
keycloak_quarkus_start_dev: True
keycloak_quarkus_proxy_mode: none
keycloak_client_default_roles:
- TestRoleAdmin
- TestRoleUser
keycloak_client_users:
- username: TestUser
password: password
client_roles:
- client: TestClient
role: TestRoleUser
- username: TestAdmin
password: password
client_roles:
- client: TestClient
role: TestRoleUser
- client: TestClient
role: TestRoleAdmin
keycloak_clients:
- name: TestClient
roles: "{{ keycloak_client_default_roles }}"
public_client: "{{ keycloak_client_public }}"
web_origins: "{{ keycloak_client_web_origins }}"
users: "{{ keycloak_client_users }}"
client_id: TestClient
attributes:
post.logout.redirect.uris: '/public/logout'
roles:
- role: keycloak_quarkus
- role: keycloak_realm
keycloak_realm: TestRealm
keycloak_admin_password: "remembertochangeme"
keycloak_context: ''

View File

@@ -1,48 +0,0 @@
---
driver:
name: docker
platforms:
- name: instance
image: ghcr.io/hspaans/molecule-containers:debian-11
pre_build_image: true
privileged: true
port_bindings:
- "8080/tcp"
- "8443/tcp"
- "8009/tcp"
cgroupns_mode: host
command: "/lib/systemd/systemd"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
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: /usr/bin/python3
env:
ANSIBLE_FORCE_COLOR: "true"
ANSIBLE_REMOTE_TMP: /tmp/.ansible/tmp
verifier:
name: ansible
scenario:
test_sequence:
- cleanup
- destroy
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy

View File

@@ -1,11 +0,0 @@
---
- name: Prepare
hosts: all
gather_facts: yes
tasks:
- name: Install sudo
ansible.builtin.apt:
name:
- sudo
- openjdk-17-jdk-headless
state: present

View File

@@ -1 +0,0 @@
../../roles

View File

@@ -1,40 +0,0 @@
---
- name: Verify
hosts: all
vars:
keycloak_admin_password: "remembertochangeme"
keycloak_uri: "http://localhost:{{ 8080 + ( keycloak_jboss_port_offset | default(0) ) }}"
keycloak_management_port: "http://localhost:{{ 9990 + ( keycloak_jboss_port_offset | default(0) ) }}"
keycloak_jboss_port_offset: 10
tasks:
- name: Populate service facts
ansible.builtin.service_facts:
- name: Check if keycloak service started
ansible.builtin.assert:
that:
- ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled"
- name: Verify openid config
block:
- name: Fetch openID config # noqa blocked_modules command-instead-of-module
ansible.builtin.shell: |
set -o pipefail
curl http://localhost:8080/realms/master/.well-known/openid-configuration -k | jq .
args:
executable: /bin/bash
delegate_to: localhost
register: openid_config
changed_when: False
- name: Verify endpoint URLs
ansible.builtin.assert:
that:
- (openid_config.stdout | from_json)["backchannel_authentication_endpoint"] == 'http://localhost:8080/realms/master/protocol/openid-connect/ext/ciba/auth'
- (openid_config.stdout | from_json)['issuer'] == 'http://localhost:8080/realms/master'
- (openid_config.stdout | from_json)['authorization_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/auth'
- (openid_config.stdout | from_json)['token_endpoint'] == 'http://localhost:8080/realms/master/protocol/openid-connect/token'
delegate_to: localhost
when:
- hera_home is defined
- hera_home | length == 0

View File

@@ -1,7 +1,7 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_jvm_package: java-11-openjdk-headless keycloak_jvm_package: java-11-openjdk-headless
keycloak_modcluster_enabled: True keycloak_modcluster_enabled: True
@@ -52,7 +52,7 @@
pre_tasks: pre_tasks:
- name: "Retrieve assets server from env" - name: "Retrieve assets server from env"
ansible.builtin.set_fact: ansible.builtin.set_fact:
assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}"
- name: "Set offline when assets server from env is defined" - name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact: ansible.builtin.set_fact:

View File

@@ -18,12 +18,5 @@
name: name:
- java-1.8.0-openjdk - java-1.8.0-openjdk
state: present state: present
when: ansible_facts['os_family'] == "RedHat"
- name: Install JDK8
become: yes
ansible.builtin.apt:
name:
- openjdk-8-jdk
state: present
when: ansible_facts['os_family'] == "Debian"

View File

@@ -1,7 +1,7 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_config_override_template: custom.xml.j2 keycloak_config_override_template: custom.xml.j2
keycloak_http_port: 8081 keycloak_http_port: 8081
@@ -9,3 +9,47 @@
keycloak_service_runas: True keycloak_service_runas: True
roles: roles:
- role: keycloak - role: keycloak
tasks:
- name: Keycloak Realm Role
ansible.builtin.include_role:
name: keycloak_realm
vars:
keycloak_client_default_roles:
- TestRoleAdmin
- TestRoleUser
keycloak_client_users:
- username: TestUser
password: password
client_roles:
- client: TestClient
role: TestRoleUser
realm: "{{ keycloak_realm }}"
- username: TestAdmin
password: password
client_roles:
- client: TestClient
role: TestRoleUser
realm: "{{ keycloak_realm }}"
- client: TestClient
role: TestRoleAdmin
realm: "{{ keycloak_realm }}"
keycloak_realm: TestRealm
keycloak_clients:
- name: TestClient
roles: "{{ keycloak_client_default_roles }}"
realm: "{{ keycloak_realm }}"
public_client: "{{ keycloak_client_public }}"
web_origins: "{{ keycloak_client_web_origins }}"
users: "{{ keycloak_client_users }}"
client_id: TestClient
pre_tasks:
- name: "Retrieve assets server from env"
ansible.builtin.set_fact:
assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}"
- name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact:
sso_offline_install: True
when:
- assets_server is defined
- assets_server | length > 0

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- this is a custom file --> <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>
@@ -44,7 +44,7 @@
</audit-log> </audit-log>
<management-interfaces> <management-interfaces>
<http-interface http-authentication-factory="management-http-authentication"> <http-interface http-authentication-factory="management-http-authentication">
<http-upgrade enabled="true" sasl-authentication-factory="management-sasl-authentication"/> <http-upgrade enabled="true"/>
<socket-binding http="management-http"/> <socket-binding http="management-http"/>
</http-interface> </http-interface>
</management-interfaces> </management-interfaces>
@@ -481,8 +481,8 @@
<default-provider>default</default-provider> <default-provider>default</default-provider>
<provider name="default" enabled="true"> <provider name="default" enabled="true">
<properties> <properties>
<property name="frontendUrl" value="${keycloak.frontendUrl:}"/> <property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
<property name="forceBackendUrlToFrontendUrl" value="false"/> <property name="forceBackendUrlToFrontendUrl" value="true"/>
</properties> </properties>
</provider> </provider>
</spi> </spi>
@@ -520,8 +520,7 @@
<subsystem xmlns="urn:jboss:domain:undertow:12.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}}"> <subsystem xmlns="urn:jboss:domain:undertow:12.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"/> <buffer-cache name="default"/>
<server name="default-server"> <server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <http-listener name="default" socket-binding="http"/>
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
<host name="default-host" alias="localhost"> <host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/> <location name="/" handler="welcome-content"/>
<http-invoker http-authentication-factory="application-http-authentication"/> <http-invoker http-authentication-factory="application-http-authentication"/>
@@ -534,25 +533,20 @@
<handlers> <handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/> <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers> </handlers>
<application-security-domains>
<application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
</subsystem> </subsystem>
<subsystem xmlns="urn:jboss:domain:weld:4.0"/> <subsystem xmlns="urn:jboss:domain:weld:4.0"/>
</profile> </profile>
<interfaces> <interfaces>
<interface name="management"> <interface name="management">
<inet-address value="127.0.0.1"/> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface> </interface>
<interface name="public"> <interface name="public">
<inet-address value="127.0.0.1"/> <inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface> </interface>
</interfaces> </interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="http" port="8081"/> <socket-binding name="http" port="8081"/>
<socket-binding name="https" port="8443"/>
<socket-binding name="management-http" interface="management" port="19990"/> <socket-binding name="management-http" interface="management" port="19990"/>
<socket-binding name="management-https" interface="management" port="19991"/>
<socket-binding name="txn-recovery-environment" port="4712"/> <socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/> <socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp"> <outbound-socket-binding name="mail-smtp">

View File

@@ -1,10 +1,6 @@
--- ---
- name: Verify - name: Verify
hosts: all hosts: all
vars:
keycloak_uri: "http://localhost:8081"
keycloak_management_port: "http://localhost:19990"
keycloak_admin_password: "remembertochangeme"
tasks: tasks:
- name: Populate service facts - name: Populate service facts
ansible.builtin.service_facts: ansible.builtin.service_facts:
@@ -13,20 +9,3 @@
that: that:
- ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled" - ansible_facts.services["keycloak.service"]["status"] == "enabled"
- name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module
ansible.builtin.shell: |
set -o pipefail
ps -ef | grep '/etc/alternatives/jre_1.8.0/' | grep -v grep
args:
executable: /bin/bash
changed_when: no
- name: Verify token api call
ansible.builtin.uri:
url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no
register: keycloak_auth_response
until: keycloak_auth_response.status == 200
retries: 2
delay: 2

View File

@@ -3,44 +3,39 @@
ansible.builtin.debug: ansible.builtin.debug:
msg: "Ansible version is {{ ansible_version.full }}" msg: "Ansible version is {{ ansible_version.full }}"
- name: "Set package name for sudo"
ansible.builtin.set_fact:
sudo_pkg_name: sudo
- name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)." - name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)."
ansible.builtin.yum: ansible.builtin.yum:
name: "{{ sudo_pkg_name }}" name: "{{ sudo_pkg_name }}"
state: present
when: when:
- ansible_user_id == 'root' - ansible_user_id == 'root'
- name: Gather the package facts - name: Gather the package facts
ansible.builtin.package_facts: ansible.builtin.package_facts:
manager: auto manager: auto
- name: "Check if sudo is installed." - name: "Check if {{ sudo_pkg_name }} is installed."
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- sudo_pkg_name in ansible_facts.packages - sudo_pkg_name in ansible_facts.packages
fail_msg: "sudo is not installed on target system"
- name: "Install iproute" - name: Install sudo
become: true become: yes
ansible.builtin.yum: ansible.builtin.yum:
name: name:
- sudo
- iproute - iproute
state: present state: present
- name: "Retrieve assets server from env" - name: "Retrieve assets server from env"
ansible.builtin.set_fact: ansible.builtin.set_fact:
assets_server: "{{ lookup('env', 'MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}" assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}"
- name: "Download artefacts only if assets_server is set" - name: "Download artefacts only if assets_server is set"
when: when:
- assets_server is defined - assets_server is defined
- assets_server | length > 0 - assets_server | length > 0
- assets is defined
- assets | length > 0
block: block:
- name: "Set offline when assets server from env is defined" - name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact: ansible.builtin.set_fact:
@@ -51,7 +46,6 @@
url: "{{ asset }}" url: "{{ asset }}"
dest: "{{ lookup('env', 'PWD') }}" dest: "{{ lookup('env', 'PWD') }}"
validate_certs: no validate_certs: no
mode: '0644'
delegate_to: localhost delegate_to: localhost
loop: "{{ assets }}" loop: "{{ assets }}"
loop_control: loop_control:

View File

@@ -1,39 +1,14 @@
--- ---
- name: Prepare - name: Prepare
hosts: all hosts: all
become: yes
tasks: tasks:
- name: Install sudo - name: Install sudo
ansible.builtin.apt:
name:
- sudo
- openjdk-17-jdk-headless
state: present
when:
- ansible_facts.os_family == 'Debian'
- name: "Ensure common prepare phase are set."
ansible.builtin.include_tasks: ../prepare.yml
- name: Install JDK17
become: yes
ansible.builtin.yum: ansible.builtin.yum:
name: name:
- sudo
- java-17-openjdk-headless - java-17-openjdk-headless
state: present state: present
when:
- ansible_facts.os_family == 'RedHat'
- name: Link default logs directory
become: yes
ansible.builtin.file:
state: link
src: "{{ item }}"
dest: /opt/openjdk
force: true
with_fileglob:
- /usr/lib/jvm/java-17-openjdk*
when:
- ansible_facts.os_family == "Debian"
- name: Link default logs directory - name: Link default logs directory
ansible.builtin.file: ansible.builtin.file:
@@ -41,8 +16,6 @@
src: /usr/lib/jvm/jre-17-openjdk src: /usr/lib/jvm/jre-17-openjdk
dest: /opt/openjdk dest: /opt/openjdk
force: true force: true
when:
- ansible_facts.os_family == "RedHat"
- name: "Display hera_home if defined." - name: "Display hera_home if defined."
ansible.builtin.set_fact: ansible.builtin.set_fact:

View File

@@ -1,34 +1,16 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm keycloak_realm: TestRealm
keycloak_quarkus_host: instance keycloak_quarkus_host: instance
keycloak_quarkus_log: file keycloak_quarkus_log: file
keycloak_quarkus_log_level: debug keycloak_quarkus_https_key_file_enabled: True
keycloak_quarkus_https_key_file_enabled: true
keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem"
keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem"
keycloak_quarkus_log_target: /tmp/keycloak keycloak_quarkus_log_target: /tmp/keycloak
keycloak_quarkus_ks_vault_enabled: true
keycloak_quarkus_ks_vault_file: "/opt/keycloak/certs/keystore.p12"
keycloak_quarkus_ks_vault_pass: keystorepassword
keycloak_quarkus_systemd_wait_for_port: true
keycloak_quarkus_systemd_wait_for_timeout: 20
keycloak_quarkus_systemd_wait_for_delay: 2
keycloak_quarkus_systemd_wait_for_log: true
keycloak_quarkus_providers:
- id: http-client
spi: connections
default: true
restart: true
properties:
- key: default-connection-pool-size
value: 10
- id: spid-saml
url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar
roles: roles:
- role: keycloak_quarkus - role: keycloak_quarkus
- role: keycloak_realm - role: keycloak_realm

View File

@@ -2,42 +2,29 @@
- name: Prepare - name: Prepare
hosts: all hosts: all
tasks: tasks:
- name: Install sudo
become: yes
ansible.builtin.yum:
name: sudo
state: present
- name: "Display hera_home if defined." - name: "Display hera_home if defined."
ansible.builtin.set_fact: ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}" hera_home: "{{ lookup('env', 'HERA_HOME') }}"
- name: "Ensure common prepare phase are set."
ansible.builtin.include_tasks: ../prepare.yml
- name: Create certificate request - name: Create certificate request
ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance' ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance'
delegate_to: localhost delegate_to: localhost
changed_when: False changed_when: False
- name: Create conf directory # risky-file-permissions in test user account does not exist yet - name: Create conf directory # risky-file-permissions in test user account does not exist yet
become: true
ansible.builtin.file: ansible.builtin.file:
state: directory state: directory
path: "/opt/keycloak/certs/" path: "/opt/keycloak/certs/"
mode: 0755 mode: 0755
- name: Make sure a jre is available (for keytool to prepare keystore) - name: Copy certificates
delegate_to: localhost become: yes
ansible.builtin.package:
name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}"
state: present
become: true
failed_when: false
- name: Create vault keystore
ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword
delegate_to: localhost
register: keytool_cmd
changed_when: False
failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0
- name: Copy certificates and vault
become: true
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ item }}" src: "{{ item }}"
dest: "/opt/keycloak/certs/{{ item }}" dest: "/opt/keycloak/certs/{{ item }}"
@@ -45,4 +32,3 @@
loop: loop:
- cert.pem - cert.pem
- key.pem - key.pem
- keystore.p12

View File

@@ -10,7 +10,6 @@
that: that:
- ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled" - ansible_facts.services["keycloak.service"]["status"] == "enabled"
fail_msg: "Service not running"
- name: Set internal envvar - name: Set internal envvar
ansible.builtin.set_fact: ansible.builtin.set_fact:
@@ -41,7 +40,7 @@
- name: Check log folder - name: Check log folder
ansible.builtin.stat: ansible.builtin.stat:
path: /tmp/keycloak path: "/tmp/keycloak"
register: keycloak_log_folder register: keycloak_log_folder
- name: Check that keycloak log folder exists and is a link - name: Check that keycloak log folder exists and is a link
@@ -50,12 +49,10 @@
- keycloak_log_folder.stat.exists - keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir - not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk - keycloak_log_folder.stat.islnk
fail_msg: "Service log symlink not correctly created"
- name: Check log file - name: Check log file
become: true
ansible.builtin.stat: ansible.builtin.stat:
path: /tmp/keycloak/keycloak.log path: "/tmp/keycloak/keycloak.log"
register: keycloak_log_file register: keycloak_log_file
- name: Check if keycloak file exists - name: Check if keycloak file exists
@@ -65,9 +62,8 @@
- not keycloak_log_file.stat.isdir - not keycloak_log_file.stat.isdir
- name: Check default log folder - name: Check default log folder
become: yes
ansible.builtin.stat: ansible.builtin.stat:
path: /var/log/keycloak path: "/var/log/keycloak"
register: keycloak_default_log_folder register: keycloak_default_log_folder
failed_when: false failed_when: false
@@ -75,12 +71,3 @@
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- not keycloak_default_log_folder.stat.exists - not keycloak_default_log_folder.stat.exists
- name: Verify vault SPI in logfile
become: true
ansible.builtin.shell: |
set -o pipefail
zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip
changed_when: false
failed_when: slurped_log.rc != 0
register: slurped_log

View File

@@ -5,7 +5,7 @@ collections:
- name: community.general - name: community.general
- name: ansible.posix - name: ansible.posix
- name: community.docker - name: community.docker
version: ">=3.8.0" version: ">=1.9.1"
roles: roles:
- name: elan.simple_nginx_reverse_proxy - name: elan.simple_nginx_reverse_proxy

View File

@@ -637,7 +637,7 @@ EXAMPLES = '''
- test01 - test01
- test02 - test02
authentication_flow_binding_overrides: authentication_flow_binding_overrides:
browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb browser: 4c90336b-bf1d-4b87-916d-3677ba4e5fbb
protocol_mappers: protocol_mappers:
- config: - config:
access.token.claim: true access.token.claim: true

View File

@@ -142,14 +142,14 @@ EXAMPLES = '''
auth_password: PASSWORD auth_password: PASSWORD
name: my-new-role name: my-new-role
attributes: attributes:
attrib1: value1 attrib1: value1
attrib2: value2 attrib2: value2
attrib3: attrib3:
- with - with
- numerous - numerous
- individual - individual
- list - list
- items - items
delegate_to: localhost delegate_to: localhost
''' '''

View File

@@ -475,99 +475,99 @@ author:
''' '''
EXAMPLES = ''' EXAMPLES = '''
- name: Create LDAP user federation - name: Create LDAP user federation
middleware_automation.keycloak.keycloak_user_federation: middleware_automation.keycloak.keycloak_user_federation:
auth_keycloak_url: https://keycloak.example.com/auth auth_keycloak_url: https://keycloak.example.com/auth
auth_realm: master auth_realm: master
auth_username: admin auth_username: admin
auth_password: password auth_password: password
realm: my-realm realm: my-realm
name: my-ldap name: my-ldap
state: present state: present
provider_id: ldap provider_id: ldap
provider_type: org.keycloak.storage.UserStorageProvider provider_type: org.keycloak.storage.UserStorageProvider
config: config:
priority: 0 priority: 0
enabled: true enabled: true
cachePolicy: DEFAULT cachePolicy: DEFAULT
batchSizeForSync: 1000 batchSizeForSync: 1000
editMode: READ_ONLY editMode: READ_ONLY
importEnabled: true importEnabled: true
syncRegistrations: false syncRegistrations: false
vendor: other vendor: other
usernameLDAPAttribute: uid usernameLDAPAttribute: uid
rdnLDAPAttribute: uid rdnLDAPAttribute: uid
uuidLDAPAttribute: entryUUID uuidLDAPAttribute: entryUUID
userObjectClasses: inetOrgPerson, organizationalPerson userObjectClasses: inetOrgPerson, organizationalPerson
connectionUrl: ldaps://ldap.example.com:636 connectionUrl: ldaps://ldap.example.com:636
usersDn: ou=Users,dc=example,dc=com usersDn: ou=Users,dc=example,dc=com
authType: simple authType: simple
bindDn: cn=directory reader bindDn: cn=directory reader
bindCredential: password bindCredential: password
searchScope: 1 searchScope: 1
validatePasswordPolicy: false validatePasswordPolicy: false
trustEmail: false trustEmail: false
useTruststoreSpi: ldapsOnly useTruststoreSpi: ldapsOnly
connectionPooling: true connectionPooling: true
pagination: true pagination: true
allowKerberosAuthentication: false allowKerberosAuthentication: false
debug: false debug: false
useKerberosForPasswordAuthentication: false useKerberosForPasswordAuthentication: false
mappers: mappers:
- name: "full name" - name: "full name"
providerId: "full-name-ldap-mapper" providerId: "full-name-ldap-mapper"
providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper" providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
config: config:
ldap.full.name.attribute: cn ldap.full.name.attribute: cn
read.only: true read.only: true
write.only: false write.only: false
- name: Create Kerberos user federation - name: Create Kerberos user federation
middleware_automation.keycloak.keycloak_user_federation: middleware_automation.keycloak.keycloak_user_federation:
auth_keycloak_url: https://keycloak.example.com/auth auth_keycloak_url: https://keycloak.example.com/auth
auth_realm: master auth_realm: master
auth_username: admin auth_username: admin
auth_password: password auth_password: password
realm: my-realm realm: my-realm
name: my-kerberos name: my-kerberos
state: present state: present
provider_id: kerberos provider_id: kerberos
provider_type: org.keycloak.storage.UserStorageProvider provider_type: org.keycloak.storage.UserStorageProvider
config: config:
priority: 0 priority: 0
enabled: true enabled: true
cachePolicy: DEFAULT cachePolicy: DEFAULT
kerberosRealm: EXAMPLE.COM kerberosRealm: EXAMPLE.COM
serverPrincipal: HTTP/host.example.com@EXAMPLE.COM serverPrincipal: HTTP/host.example.com@EXAMPLE.COM
keyTab: keytab keyTab: keytab
allowPasswordAuthentication: false allowPasswordAuthentication: false
updateProfileFirstLogin: false updateProfileFirstLogin: false
- name: Create sssd user federation - name: Create sssd user federation
middleware_automation.keycloak.keycloak_user_federation: middleware_automation.keycloak.keycloak_user_federation:
auth_keycloak_url: https://keycloak.example.com/auth auth_keycloak_url: https://keycloak.example.com/auth
auth_realm: master auth_realm: master
auth_username: admin auth_username: admin
auth_password: password auth_password: password
realm: my-realm realm: my-realm
name: my-sssd name: my-sssd
state: present state: present
provider_id: sssd provider_id: sssd
provider_type: org.keycloak.storage.UserStorageProvider provider_type: org.keycloak.storage.UserStorageProvider
config: config:
priority: 0 priority: 0
enabled: true enabled: true
cachePolicy: DEFAULT cachePolicy: DEFAULT
- name: Delete user federation - name: Delete user federation
middleware_automation.keycloak.keycloak_user_federation: middleware_automation.keycloak.keycloak_user_federation:
auth_keycloak_url: https://keycloak.example.com/auth auth_keycloak_url: https://keycloak.example.com/auth
auth_realm: master auth_realm: master
auth_username: admin auth_username: admin
auth_password: password auth_password: password
realm: my-realm realm: my-realm
name: my-federation name: my-federation
state: absent state: absent
''' '''
RETURN = ''' RETURN = '''

View File

@@ -10,7 +10,6 @@ Requirements
This role requires the `python3-netaddr` library installed on the controller node. This role requires the `python3-netaddr` library installed on the controller node.
* to install via yum/dnf: `dnf install python3-netaddr` * to install via yum/dnf: `dnf install python3-netaddr`
* to install via apt: `apt install python3-netaddr`
* or via pip: `pip install netaddr==0.8.0` * or via pip: `pip install netaddr==0.8.0`
* or via the collection: `pip install -r requirements.txt` * or via the collection: `pip install -r requirements.txt`

View File

@@ -8,6 +8,7 @@ keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}"
keycloak_offline_install: false keycloak_offline_install: false
### Install location and service settings ### Install location and service settings
keycloak_jvm_package: java-1.8.0-openjdk-headless
keycloak_java_home: keycloak_java_home:
keycloak_dest: /opt/keycloak keycloak_dest: /opt/keycloak
keycloak_jboss_home: "{{ keycloak_installdir }}" keycloak_jboss_home: "{{ keycloak_installdir }}"
@@ -32,7 +33,6 @@ keycloak_service_startlimitburst: "5"
keycloak_service_restartsec: "10s" keycloak_service_restartsec: "10s"
keycloak_configure_firewalld: false keycloak_configure_firewalld: false
keycloak_configure_iptables: false
### administrator console password ### administrator console password
keycloak_admin_password: '' keycloak_admin_password: ''

View File

@@ -2,38 +2,42 @@ argument_specs:
main: main:
options: options:
keycloak_version: keycloak_version:
# line 3 of keycloak/defaults/main.yml
default: "18.0.2" default: "18.0.2"
description: "keycloak.org package version" description: "keycloak.org package version"
type: "str" type: "str"
keycloak_archive: keycloak_archive:
# line 4 of keycloak/defaults/main.yml
default: "keycloak-legacy-{{ keycloak_version }}.zip" default: "keycloak-legacy-{{ keycloak_version }}.zip"
description: "keycloak install archive filename" description: "keycloak install archive filename"
type: "str" type: "str"
keycloak_configure_iptables:
default: false
description: "Ensure iptables is running and configure keycloak ports"
type: "bool"
keycloak_configure_firewalld: keycloak_configure_firewalld:
# line 33 of keycloak/defaults/main.yml
default: false default: false
description: "Ensure firewalld is running and configure keycloak ports" description: "Ensure firewalld is running and configure keycloak ports"
type: "bool" type: "bool"
keycloak_download_url: keycloak_download_url:
# line 5 of keycloak/defaults/main.yml
default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}" default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}"
description: "Download URL for keycloak" description: "Download URL for keycloak"
type: "str" type: "str"
keycloak_download_url_9x: keycloak_download_url_9x:
# line 6 of keycloak/defaults/main.yml
default: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}" default: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}"
description: "Download URL for keycloak (deprecated)" description: "Download URL for keycloak (deprecated)"
type: "str" type: "str"
keycloak_installdir: keycloak_installdir:
# line 7 of keycloak/defaults/main.yml
default: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}" default: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}"
description: "Installation path" description: "Installation path"
type: "str" type: "str"
keycloak_offline_install: keycloak_offline_install:
# line 20 of keycloak/defaults/main.yml
default: false default: false
description: "Perform an offline install" description: "Perform an offline install"
type: "bool" type: "bool"
keycloak_jvm_package: keycloak_jvm_package:
# line 23 of keycloak/defaults/main.yml
default: "java-1.8.0-openjdk-headless" default: "java-1.8.0-openjdk-headless"
description: "RHEL java package runtime rpm" description: "RHEL java package runtime rpm"
type: "str" type: "str"
@@ -41,10 +45,12 @@ argument_specs:
description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path"
type: "str" type: "str"
keycloak_dest: keycloak_dest:
# line 24 of keycloak/defaults/main.yml
default: "/opt/keycloak" default: "/opt/keycloak"
description: "Root installation directory" description: "Root installation directory"
type: "str" type: "str"
keycloak_jboss_home: keycloak_jboss_home:
# line 25 of keycloak/defaults/main.yml
default: "{{ keycloak_installdir }}" default: "{{ keycloak_installdir }}"
description: "Installation work directory" description: "Installation work directory"
type: "str" type: "str"
@@ -53,42 +59,52 @@ argument_specs:
description: "Port offset for the JBoss socket binding" description: "Port offset for the JBoss socket binding"
type: "int" type: "int"
keycloak_config_dir: keycloak_config_dir:
# line 26 of keycloak/defaults/main.yml
default: "{{ keycloak_jboss_home }}/standalone/configuration" default: "{{ keycloak_jboss_home }}/standalone/configuration"
description: "Path for configuration" description: "Path for configuration"
type: "str" type: "str"
keycloak_config_standalone_xml: keycloak_config_standalone_xml:
# line 27 of keycloak/defaults/main.yml
default: "keycloak.xml" default: "keycloak.xml"
description: "Service configuration filename" description: "Service configuration filename"
type: "str" type: "str"
keycloak_config_path_to_standalone_xml: keycloak_config_path_to_standalone_xml:
# line 28 of keycloak/defaults/main.yml
default: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" default: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}"
description: "Custom path for configuration" description: "Custom path for configuration"
type: "str" type: "str"
keycloak_config_override_template: keycloak_config_override_template:
# line 30 of keycloak/defaults/main.yml
default: "" default: ""
description: "Path to custom template for standalone.xml configuration" description: "Path to custom template for standalone.xml configuration"
type: "str" type: "str"
keycloak_service_runas: keycloak_service_runas:
# line 20 of keycloak/defaults/main.yml
default: false default: false
description: "Enable execution of service as `keycloak_service_user`" description: "Enable execution of service as `keycloak_service_user`"
type: "bool" type: "bool"
keycloak_service_user: keycloak_service_user:
# line 29 of keycloak/defaults/main.yml
default: "keycloak" default: "keycloak"
description: "posix account username" description: "posix account username"
type: "str" type: "str"
keycloak_service_group: keycloak_service_group:
# line 30 of keycloak/defaults/main.yml
default: "keycloak" default: "keycloak"
description: "posix account group" description: "posix account group"
type: "str" type: "str"
keycloak_service_pidfile: keycloak_service_pidfile:
# line 31 of keycloak/defaults/main.yml
default: "/run/keycloak/keycloak.pid" default: "/run/keycloak/keycloak.pid"
description: "PID file path for service" description: "PID file path for service"
type: "str" type: "str"
keycloak_features: keycloak_features:
# line 17 of keycloak/defaults/main.yml
default: "[]" default: "[]"
description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`" description: "List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]`"
type: "list" type: "list"
keycloak_bind_address: keycloak_bind_address:
# line 34 of keycloak/defaults/main.yml
default: "0.0.0.0" default: "0.0.0.0"
description: "Address for binding service ports" description: "Address for binding service ports"
type: "str" type: "str"
@@ -97,42 +113,52 @@ argument_specs:
description: "Address for binding the management ports" description: "Address for binding the management ports"
type: "str" type: "str"
keycloak_host: keycloak_host:
# line 35 of keycloak/defaults/main.yml
default: "localhost" default: "localhost"
description: "Hostname for service" description: "Hostname for service"
type: "str" type: "str"
keycloak_http_port: keycloak_http_port:
# line 36 of keycloak/defaults/main.yml
default: 8080 default: 8080
description: "Listening HTTP port" description: "Listening HTTP port"
type: "int" type: "int"
keycloak_https_port: keycloak_https_port:
# line 37 of keycloak/defaults/main.yml
default: 8443 default: 8443
description: "Listening HTTPS port" description: "Listening HTTPS port"
type: "int" type: "int"
keycloak_ajp_port: keycloak_ajp_port:
# line 38 of keycloak/defaults/main.yml
default: 8009 default: 8009
description: "Listening AJP port" description: "Listening AJP port"
type: "int" type: "int"
keycloak_jgroups_port: keycloak_jgroups_port:
# line 39 of keycloak/defaults/main.yml
default: 7600 default: 7600
description: "jgroups cluster tcp port" description: "jgroups cluster tcp port"
type: "int" type: "int"
keycloak_management_http_port: keycloak_management_http_port:
# line 40 of keycloak/defaults/main.yml
default: 9990 default: 9990
description: "Management port (http)" description: "Management port (http)"
type: "int" type: "int"
keycloak_management_https_port: keycloak_management_https_port:
# line 41 of keycloak/defaults/main.yml
default: 9993 default: 9993
description: "Management port (https)" description: "Management port (https)"
type: "int" type: "int"
keycloak_java_opts: keycloak_java_opts:
# line 42 of keycloak/defaults/main.yml
default: "-Xms1024m -Xmx2048m" default: "-Xms1024m -Xmx2048m"
description: "Additional JVM options" description: "Additional JVM options"
type: "str" type: "str"
keycloak_prefer_ipv4: keycloak_prefer_ipv4:
# line 43 of keycloak/defaults/main.yml
default: true default: true
description: "Prefer IPv4 stack and addresses for port binding" description: "Prefer IPv4 stack and addresses for port binding"
type: "bool" type: "bool"
keycloak_ha_enabled: keycloak_ha_enabled:
# line 46 of keycloak/defaults/main.yml
default: false default: false
description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" description: "Enable auto configuration for database backend, clustering and remote caches on infinispan"
type: "bool" type: "bool"
@@ -141,22 +167,27 @@ argument_specs:
description: "Discovery protocol for HA cluster members" description: "Discovery protocol for HA cluster members"
type: "str" type: "str"
keycloak_db_enabled: keycloak_db_enabled:
# line 48 of keycloak/defaults/main.yml
default: "{{ True if keycloak_ha_enabled else False }}" default: "{{ True if keycloak_ha_enabled else False }}"
description: "Enable auto configuration for database backend" description: "Enable auto configuration for database backend"
type: "bool" type: "bool"
keycloak_admin_user: keycloak_admin_user:
# line 51 of keycloak/defaults/main.yml
default: "admin" default: "admin"
description: "Administration console user account" description: "Administration console user account"
type: "str" type: "str"
keycloak_auth_realm: keycloak_auth_realm:
# line 52 of keycloak/defaults/main.yml
default: "master" default: "master"
description: "Name for rest authentication realm" description: "Name for rest authentication realm"
type: "str" type: "str"
keycloak_auth_client: keycloak_auth_client:
# line 53 of keycloak/defaults/main.yml
default: "admin-cli" default: "admin-cli"
description: "Authentication client for configuration REST calls" description: "Authentication client for configuration REST calls"
type: "str" type: "str"
keycloak_force_install: keycloak_force_install:
# line 55 of keycloak/defaults/main.yml
default: false default: false
description: "Remove pre-existing versions of service" description: "Remove pre-existing versions of service"
type: "bool" type: "bool"
@@ -165,6 +196,7 @@ argument_specs:
description: "Enable configuration for modcluster subsystem" description: "Enable configuration for modcluster subsystem"
type: "bool" type: "bool"
keycloak_modcluster_url: keycloak_modcluster_url:
# line 58 of keycloak/defaults/main.yml
default: "localhost" default: "localhost"
description: "URL for the modcluster reverse proxy" description: "URL for the modcluster reverse proxy"
type: "str" type: "str"
@@ -177,6 +209,7 @@ argument_specs:
description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy" description: "List of modproxy node URLs in the format { host, port } for the modcluster reverse proxy"
type: "list" type: "list"
keycloak_frontend_url: keycloak_frontend_url:
# line 59 of keycloak/defaults/main.yml
default: "http://localhost" default: "http://localhost"
description: "Frontend URL for keycloak endpoints when a reverse proxy is used" description: "Frontend URL for keycloak endpoints when a reverse proxy is used"
type: "str" type: "str"
@@ -185,62 +218,77 @@ argument_specs:
description: "Force backend requests to use the frontend URL" description: "Force backend requests to use the frontend URL"
type: "bool" type: "bool"
keycloak_infinispan_user: keycloak_infinispan_user:
# line 62 of keycloak/defaults/main.yml
default: "supervisor" default: "supervisor"
description: "Username for connecting to infinispan" description: "Username for connecting to infinispan"
type: "str" type: "str"
keycloak_infinispan_pass: keycloak_infinispan_pass:
# line 63 of keycloak/defaults/main.yml
default: "supervisor" default: "supervisor"
description: "Password for connecting to infinispan" description: "Password for connecting to infinispan"
type: "str" type: "str"
keycloak_infinispan_url: keycloak_infinispan_url:
# line 64 of keycloak/defaults/main.yml
default: "localhost" default: "localhost"
description: "URL for the infinispan remote-cache server" description: "URL for the infinispan remote-cache server"
type: "str" type: "str"
keycloak_infinispan_sasl_mechanism: keycloak_infinispan_sasl_mechanism:
# line 65 of keycloak/defaults/main.yml
default: "SCRAM-SHA-512" default: "SCRAM-SHA-512"
description: "Authentication type to infinispan server" description: "Authentication type to infinispan server"
type: "str" type: "str"
keycloak_infinispan_use_ssl: keycloak_infinispan_use_ssl:
# line 66 of keycloak/defaults/main.yml
default: false default: false
description: "Enable hotrod client TLS communication" description: "Enable hotrod client TLS communication"
type: "bool" type: "bool"
keycloak_infinispan_trust_store_path: keycloak_infinispan_trust_store_path:
# line 68 of keycloak/defaults/main.yml
default: "/etc/pki/java/cacerts" default: "/etc/pki/java/cacerts"
description: "TODO document argument" description: "TODO document argument"
type: "str" type: "str"
keycloak_infinispan_trust_store_password: keycloak_infinispan_trust_store_password:
# line 69 of keycloak/defaults/main.yml
default: "changeit" default: "changeit"
description: "Path to truststore containing infinispan server certificate" description: "Path to truststore containing infinispan server certificate"
type: "str" type: "str"
keycloak_jdbc_engine: keycloak_jdbc_engine:
# line 72 of keycloak/defaults/main.yml
default: "postgres" default: "postgres"
description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]" description: "Backend database flavour when db is enabled: [ postgres, mariadb, sqlserver ]"
type: "str" type: "str"
keycloak_db_user: keycloak_db_user:
# line 74 of keycloak/defaults/main.yml
default: "keycloak-user" default: "keycloak-user"
description: "Username for connecting to database" description: "Username for connecting to database"
type: "str" type: "str"
keycloak_db_pass: keycloak_db_pass:
# line 75 of keycloak/defaults/main.yml
default: "keycloak-pass" default: "keycloak-pass"
description: "Password for connecting to database" description: "Password for connecting to database"
type: "str" type: "str"
keycloak_jdbc_url: keycloak_jdbc_url:
# line 76 of keycloak/defaults/main.yml
default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}" default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}"
description: "URL for connecting to backend database" description: "URL for connecting to backend database"
type: "str" type: "str"
keycloak_jdbc_driver_version: keycloak_jdbc_driver_version:
# line 77 of keycloak/defaults/main.yml
default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}" default: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}"
description: "Version for the JDBC driver to download" description: "Version for the JDBC driver to download"
type: "str" type: "str"
keycloak_admin_password: keycloak_admin_password:
# line 4 of keycloak/vars/main.yml
required: true required: true
description: "Password for the administration console user account" description: "Password for the administration console user account"
type: "str" type: "str"
keycloak_url: keycloak_url:
# line 12 of keycloak/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}" default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}"
description: "URL for configuration rest calls" description: "URL for configuration rest calls"
type: "str" type: "str"
keycloak_management_url: keycloak_management_url:
# line 13 of keycloak/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}" default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}"
description: "URL for management console rest calls" description: "URL for management console rest calls"
type: "str" type: "str"

View File

@@ -1,6 +0,0 @@
---
- name: Include firewall config tasks
ansible.builtin.include_tasks: iptables.yml
when: keycloak_configure_iptables
tags:
- firewall

View File

@@ -4,27 +4,14 @@
register: rpm_info register: rpm_info
changed_when: false changed_when: false
failed_when: false failed_when: false
when: ansible_facts.os_family == "RedHat"
- name: "Add missing packages to the yum install list" - name: "Add missing packages to the yum install list"
ansible.builtin.set_fact: ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}" packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
when: ansible_facts.os_family == "RedHat"
- name: "Install packages: {{ packages_to_install }}" - name: "Install packages: {{ packages_to_install }}"
become: true become: true
ansible.builtin.yum: ansible.builtin.yum:
name: "{{ packages_to_install }}" name: "{{ packages_to_install }}"
state: present state: present
when: when: packages_to_install | default([]) | length > 0
- packages_to_install | default([]) | length > 0
- ansible_facts.os_family == "RedHat"
- name: "Install packages: {{ packages_list }}"
become: true
ansible.builtin.package:
name: "{{ packages_list }}"
state: present
when:
- packages_list | default([]) | length > 0
- ansible_facts.os_family == "Debian"

View File

@@ -1,23 +0,0 @@
---
- name: Ensure required package iptables are installed
ansible.builtin.include_tasks: fastpackages.yml
vars:
packages_list:
- iptables
- name: "Configure firewall ports for {{ keycloak.service_name }}"
become: true
ansible.builtin.iptables:
destination_port: "{{ item }}"
action: "insert"
rule_num: 6 # magic number I forget why
chain: "INPUT"
policy: "ACCEPT"
protocol: tcp
loop:
- "{{ keycloak_http_port }}"
- "{{ keycloak_https_port }}"
- "{{ keycloak_management_http_port }}"
- "{{ keycloak_management_https_port }}"
- "{{ keycloak_jgroups_port }}"
- "{{ keycloak_ajp_port }}"

View File

@@ -5,10 +5,11 @@
tags: tags:
- prereqs - prereqs
- name: Distro specific tasks - name: Include firewall config tasks
ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" ansible.builtin.include_tasks: firewalld.yml
when: keycloak_configure_firewalld
tags: tags:
- unbound - firewall
- name: Include install tasks - name: Include install tasks
ansible.builtin.include_tasks: install.yml ansible.builtin.include_tasks: install.yml
@@ -25,7 +26,6 @@
when: when:
- sso_apply_patches is defined and sso_apply_patches - sso_apply_patches is defined and sso_apply_patches
- sso_enable is defined and sso_enable - sso_enable is defined and sso_enable
- ansible_facts.os_family == "RedHat"
tags: tags:
- install - install
- patch - patch

View File

@@ -36,20 +36,12 @@
success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database"
when: keycloak_db_enabled when: keycloak_db_enabled
- name: Validate OS family
ansible.builtin.assert:
that:
- ansible_os_family in ["RedHat", "Debian"]
quiet: true
fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}"
success_msg: "Installing on {{ ansible_os_family }}"
- name: Load OS specific variables
ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml"
tags:
- always
- name: Ensure required packages are installed - name: Ensure required packages are installed
ansible.builtin.include_tasks: fastpackages.yml ansible.builtin.include_tasks: fastpackages.yml
vars: vars:
packages_list: "{{ keycloak_prereq_package_list }}" packages_list:
- "{{ keycloak_jvm_package }}"
- unzip
- procps-ng
- initscripts
- tzdata-java

View File

@@ -1,6 +0,0 @@
---
- name: Include firewall config tasks
ansible.builtin.include_tasks: firewalld.yml
when: keycloak_configure_firewalld
tags:
- firewall

View File

@@ -36,9 +36,7 @@
- name: Determine patch versions list - name: Determine patch versions list
ansible.builtin.set_fact: ansible.builtin.set_fact:
filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | \ filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*', '\\1') | list | unique }}"
select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | \
map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*(-[0-9])?)-.*', '\\1') | list | unique }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0 when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
@@ -72,7 +70,7 @@
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
client_id: "{{ rhn_username }}" client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}" client_secret: "{{ rhn_password }}"
product_id: "{{ (rhn_filtered_products | sort | last).id }}" product_id: "{{ (rhn_filtered_products | first).id }}"
dest: "{{ local_path.stat.path }}/{{ patch_bundle }}" dest: "{{ local_path.stat.path }}/{{ patch_bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}" no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost delegate_to: localhost
@@ -116,7 +114,7 @@
when: when:
- cli_result is defined - cli_result is defined
- cli_result.stdout is defined - cli_result.stdout is defined
- patch_version | regex_replace('-[0-9]$', '') not in cli_result.stdout - patch_version not in cli_result.stdout
block: block:
- name: "Apply patch {{ patch_version }} to server" - name: "Apply patch {{ patch_version }} to server"
ansible.builtin.include_tasks: rhsso_cli.yml ansible.builtin.include_tasks: rhsso_cli.yml

View File

@@ -10,14 +10,20 @@
notify: notify:
- restart keycloak - restart keycloak
- name: Determine JAVA_HOME for selected JVM RPM
ansible.builtin.set_fact:
rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}"
- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - name: "Configure sysconfig file for {{ keycloak.service_name }} service"
become: true become: true
ansible.builtin.template: ansible.builtin.template:
src: keycloak-sysconfig.j2 src: keycloak-sysconfig.j2
dest: "{{ keycloak_sysconf_file }}" dest: /etc/sysconfig/keycloak
owner: root owner: root
group: root group: root
mode: 0644 mode: 0644
vars:
keycloak_rpm_java_home: "{{ rpm_java_home }}"
notify: notify:
- restart keycloak - restart keycloak

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>

View File

@@ -1,5 +1,5 @@
#!/bin/bash -eu #!/bin/bash -eu
{{ ansible_managed | comment }} # {{ ansible_managed }}
set +u -o pipefail set +u -o pipefail

View File

@@ -1,6 +1,6 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
JAVA_OPTS='{{ keycloak_java_opts }}' JAVA_OPTS='{{ keycloak_java_opts }}'
JAVA_HOME={{ keycloak_java_home | default(keycloak_pkg_java_home, true) }} JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}
JBOSS_HOME={{ keycloak.home }} JBOSS_HOME={{ keycloak.home }}
KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }} KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }}
KEYCLOAK_HTTP_PORT={{ keycloak_http_port }} KEYCLOAK_HTTP_PORT={{ keycloak_http_port }}

View File

@@ -1,4 +1,4 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
[Unit] [Unit]
Description={{ keycloak.service_name }} Server Description={{ keycloak.service_name }} Server
After=network.target After=network.target
@@ -11,7 +11,7 @@ StartLimitBurst={{ keycloak_service_startlimitburst }}
User={{ keycloak_service_user }} User={{ keycloak_service_user }}
Group={{ keycloak_service_group }} Group={{ keycloak_service_group }}
{% endif -%} {% endif -%}
EnvironmentFile=-{{ keycloak_sysconf_file }} EnvironmentFile=-/etc/sysconfig/keycloak
PIDFile={{ keycloak_service_pidfile }} PIDFile={{ keycloak_service_pidfile }}
ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS ExecStart={{ keycloak.home }}/bin/standalone.sh $WILDFLY_OPTS
WorkingDirectory={{ keycloak.home }} WorkingDirectory={{ keycloak.home }}

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>
@@ -539,7 +539,7 @@
</mail-session> </mail-session>
</subsystem> </subsystem>
<subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/> <subsystem xmlns="urn:wildfly:metrics:1.0" security-enabled="false" exposed-subsystems="*" prefix="${wildfly.metrics.prefix:jboss}"/>
{% if keycloak_modcluster.enabled %} {% if keycloak_modcluster.enabled %}
<subsystem xmlns="urn:jboss:domain:modcluster:5.0"> <subsystem xmlns="urn:jboss:domain:modcluster:5.0">
<proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}"> <proxy name="default" advertise="false" listener="ajp" proxies="{{ ['proxy_'] | product(keycloak_modcluster.reverse_proxy_urls | map(attribute='host')) | map('join') | list | join(' ') }}">
<dynamic-load-provider> <dynamic-load-provider>
@@ -547,7 +547,7 @@
</dynamic-load-provider> </dynamic-load-provider>
</proxy> </proxy>
</subsystem> </subsystem>
{% endif %} {% endif %}
<subsystem xmlns="urn:jboss:domain:naming:2.0"> <subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/> <remote-naming/>
</subsystem> </subsystem>
@@ -621,6 +621,6 @@
<remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/> <remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/>
</outbound-socket-binding> </outbound-socket-binding>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</socket-binding-group> </socket-binding-group>
</server> </server>

View File

@@ -1,11 +0,0 @@
---
keycloak_varjvm_package: "{{ keycloak_jvm_package | default('openjdk-11-jdk-headless') }}"
keycloak_prereq_package_list:
- "{{ keycloak_varjvm_package }}"
- unzip
- procps
- apt
- tzdata
keycloak_configure_iptables: True
keycloak_sysconf_file: /etc/default/keycloak
keycloak_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_varjvm_package | regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"

View File

@@ -1,10 +0,0 @@
---
keycloak_varjvm_package: "{{ keycloak_jvm_package | default('java-1.8.0-openjdk-headless') }}"
keycloak_prereq_package_list:
- "{{ keycloak_varjvm_package }}"
- unzip
- procps-ng
- initscripts
- tzdata-java
keycloak_sysconf_file: /etc/sysconfig/keycloak
keycloak_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}"

View File

@@ -7,20 +7,20 @@ Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurati
Role Defaults Role Defaults
------------- -------------
#### Installation options * Installation options
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
|`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | |`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` |
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` |
|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` |
#### Service configuration * Service configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` |
|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` |
|`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` |
|`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` |
|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` |
@@ -29,16 +29,16 @@ Role Defaults
|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` |
|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` |
|`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` |
|`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` |
|`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` |
|`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` |
|`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` |
|`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` |
|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` |
|`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` |
|`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak |
|`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` |
|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | |
|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | |
|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` |
@@ -47,35 +47,14 @@ Role Defaults
|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` |
|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` | |`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `{{ keycloak.home }}/conf/server.crt.pem` |
|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | |`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` |
|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || |`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` |
|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| |`keycloak_quarkus_key_store_password`| Password for the key store | `""` |
|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | |`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` |
|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | |`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` |
|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` |
|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` |
|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password != ''`, else `''` |
|`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` |
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
|`keycloak_quarkus_configure_iptables` | Ensure iptables is configured for keycloak ports | `False` |
#### High-availability * Hostname configuration
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` |
|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` |
|`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` |
|`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` |
|`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` |
#### Hostname configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -84,7 +63,7 @@ Role Defaults
|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | |`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` |
#### Database configuration * Database configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -95,7 +74,7 @@ Role Defaults
|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | |`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` |
#### Remote caches configuration * Remote caches configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -108,7 +87,18 @@ Role Defaults
|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | |`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` |
#### Miscellaneous configuration * Install options
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` |
|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` |
|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` |
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
* Miscellaneous configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -135,43 +125,6 @@ Role Defaults
|`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` |
|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | |`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` |
#### Vault SPI
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_ks_vault_enabled`| Whether to enable the vault SPI | `false` |
|`keycloak_quarkus_ks_vault_file`| The keystore path for the vault SPI | `{{ keycloak_quarkus_config_dir }}/keystore.p12` |
|`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` |
#### Configuring providers
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_providers`| List of provider definitions; see below | `[]` |
Provider definition:
```yaml
keycloak_quarkus_providers:
- id: http-client # required
spi: connections # required if url is not specified
default: true # optional, whether to set default for spi, default false
restart: true # optional, whether to restart, default true
url: https://.../.../custom_spi.jar # optional, url for download
properties: # optional, list of key-values
- key: default-connection-pool-size
value: 10
```
the definition above will generate the following build command:
```
bin/kc.sh build --spi-connections-provider=http-client --spi-connections-http-client-default-connection-pool-size=10
```
Role Variables Role Variables
-------------- --------------
@@ -180,16 +133,7 @@ Role Variables
|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` |
|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` |
|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` |
|`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` |
Role custom facts
-----------------
The role uses the following [custom facts](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html#adding-custom-facts) found in `/etc/ansible/facts.d/keycloak.fact` (and thus identified by the `ansible_local.keycloak.` prefix):
| Variable | Description |
|:---------|:------------|
|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_admin_user[_pass]` gets created |
License License
------- -------

View File

@@ -1,6 +1,6 @@
--- ---
### Configuration specific to keycloak ### Configuration specific to keycloak
keycloak_quarkus_version: 24.0.3 keycloak_quarkus_version: 23.0.7
keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip"
keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
@@ -9,6 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q
keycloak_quarkus_offline_install: false keycloak_quarkus_offline_install: false
### Install location and service settings ### Install location and service settings
keycloak_quarkus_jvm_package: java-17-openjdk-headless
keycloak_quarkus_java_home: keycloak_quarkus_java_home:
keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_dest: /opt/keycloak
keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}"
@@ -16,13 +17,12 @@ keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf"
keycloak_quarkus_start_dev: false keycloak_quarkus_start_dev: false
keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_user: keycloak
keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_group: keycloak
keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_service_restart_always: false keycloak_quarkus_service_restart_always: false
keycloak_quarkus_service_restart_on_failure: false keycloak_quarkus_service_restart_on_failure: false
keycloak_quarkus_service_restartsec: "10s" keycloak_quarkus_service_restartsec: "10s"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_configure_iptables: false
### administrator console password ### administrator console password
keycloak_quarkus_admin_user: admin keycloak_quarkus_admin_user: admin
keycloak_quarkus_admin_pass: keycloak_quarkus_admin_pass:
@@ -38,12 +38,7 @@ keycloak_quarkus_http_port: 8080
keycloak_quarkus_https_port: 8443 keycloak_quarkus_https_port: 8443
keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_ajp_port: 8009
keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_jgroups_port: 7800
keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m"
keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8
-Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError
-Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4
-XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512"
keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}"
### TLS/HTTPS configuration ### TLS/HTTPS configuration
keycloak_quarkus_https_key_file_enabled: false keycloak_quarkus_https_key_file_enabled: false
@@ -51,25 +46,18 @@ keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem"
keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem"
#### key store configuration #### key store configuration
keycloak_quarkus_https_key_store_enabled: false keycloak_quarkus_https_key_store_enabled: false
keycloak_quarkus_https_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12"
keycloak_quarkus_https_key_store_password: '' keycloak_quarkus_key_store_password: ''
##### trust store configuration ##### trust store configuration
keycloak_quarkus_https_trust_store_enabled: false keycloak_quarkus_https_trust_store_enabled: false
keycloak_quarkus_https_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12"
keycloak_quarkus_https_trust_store_password: '' keycloak_quarkus_trust_store_password: ''
### configuration key store configuration
keycloak_quarkus_config_key_store_file: "{{ keycloak.home }}/conf/conf_store.p12"
keycloak_quarkus_config_key_store_password: ''
### Enable configuration for database backend, clustering and remote caches on infinispan ### Enable configuration for database backend, clustering and remote caches on infinispan
keycloak_quarkus_ha_enabled: false keycloak_quarkus_ha_enabled: false
keycloak_quarkus_ha_discovery: "TCPPING" keycloak_quarkus_ha_discovery: "TCPPING"
### Enable database configuration, must be enabled when HA is configured ### Enable database configuration, must be enabled when HA is configured
keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}" keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}"
keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}"
keycloak_quarkus_systemd_wait_for_log: false
keycloak_quarkus_systemd_wait_for_timeout: 60
keycloak_quarkus_systemd_wait_for_delay: 10
### keycloak frontend url ### keycloak frontend url
keycloak_quarkus_frontend_url: keycloak_quarkus_frontend_url:
@@ -92,8 +80,7 @@ keycloak_quarkus_proxy_mode: edge
# disable xa transactions # disable xa transactions
keycloak_quarkus_transaction_xa_enabled: true keycloak_quarkus_transaction_xa_enabled: true
# If the route should be attached to cookies to reflect the node that owns a particular session. # If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
# If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true
keycloak_quarkus_metrics_enabled: false keycloak_quarkus_metrics_enabled: false
@@ -127,8 +114,7 @@ keycloak_quarkus_default_jdbc:
mssql: mssql:
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
version: 12.2.0 version: 12.2.0
driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
# cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
### logging configuration ### logging configuration
keycloak_quarkus_log: file keycloak_quarkus_log: file
keycloak_quarkus_log_level: info keycloak_quarkus_log_level: info
@@ -138,11 +124,3 @@ keycloak_quarkus_log_target: /var/log/keycloak
keycloak_quarkus_log_max_file_size: 10M keycloak_quarkus_log_max_file_size: 10M
keycloak_quarkus_log_max_backup_index: 10 keycloak_quarkus_log_max_backup_index: 10
keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip'
# keystore-based vault
keycloak_quarkus_ks_vault_enabled: false
keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
keycloak_quarkus_ks_vault_type: PKCS12
keycloak_quarkus_ks_vault_pass:
keycloak_quarkus_providers: []

View File

@@ -3,15 +3,6 @@
- name: "Rebuild {{ keycloak.service_name }} config" - name: "Rebuild {{ keycloak.service_name }} config"
ansible.builtin.include_tasks: rebuild_config.yml ansible.builtin.include_tasks: rebuild_config.yml
listen: "rebuild keycloak config" listen: "rebuild keycloak config"
- name: "Bootstrapped"
ansible.builtin.include_tasks: bootstrapped.yml
listen: bootstrapped
- name: "Restart {{ keycloak.service_name }}" - name: "Restart {{ keycloak.service_name }}"
ansible.builtin.include_tasks: restart.yml ansible.builtin.include_tasks: restart.yml
listen: "restart keycloak" listen: "restart keycloak"
- name: "Print deprecation warning"
ansible.builtin.fail:
msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade."
ignore_errors: true
failed_when: false
listen: "print deprecation warning"

View File

@@ -2,26 +2,32 @@ argument_specs:
main: main:
options: options:
keycloak_quarkus_version: keycloak_quarkus_version:
default: "24.0.3" # line 3 of defaults/main.yml
default: "17.0.1"
description: "keycloak.org package version" description: "keycloak.org package version"
type: "str" type: "str"
keycloak_quarkus_archive: keycloak_quarkus_archive:
# line 4 of defaults/main.yml
default: "keycloak-{{ keycloak_quarkus_version }}.zip" default: "keycloak-{{ keycloak_quarkus_version }}.zip"
description: "keycloak install archive filename" description: "keycloak install archive filename"
type: "str" type: "str"
keycloak_quarkus_download_url: keycloak_quarkus_download_url:
# line 5 of defaults/main.yml
default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
description: "Download URL for keycloak" description: "Download URL for keycloak"
type: "str" type: "str"
keycloak_quarkus_installdir: keycloak_quarkus_installdir:
# line 6 of defaults/main.yml
default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
description: "Installation path" description: "Installation path"
type: "str" type: "str"
keycloak_quarkus_offline_install: keycloak_quarkus_offline_install:
# line 9 of defaults/main.yml
default: false default: false
description: "Perform an offline install" description: "Perform an offline install"
type: "bool" type: "bool"
keycloak_quarkus_jvm_package: keycloak_quarkus_jvm_package:
# line 12 of defaults/main.yml
default: "java-11-openjdk-headless" default: "java-11-openjdk-headless"
description: "RHEL java package runtime" description: "RHEL java package runtime"
type: "str" type: "str"
@@ -29,30 +35,37 @@ argument_specs:
description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path" description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path"
type: "str" type: "str"
keycloak_quarkus_dest: keycloak_quarkus_dest:
# line 13 of defaults/main.yml
default: "/opt/keycloak" default: "/opt/keycloak"
description: "Installation root path" description: "Installation root path"
type: "str" type: "str"
keycloak_quarkus_home: keycloak_quarkus_home:
# line 14 of defaults/main.yml
default: "{{ keycloak_quarkus_installdir }}" default: "{{ keycloak_quarkus_installdir }}"
description: "Installation work directory" description: "Installation work directory"
type: "str" type: "str"
keycloak_quarkus_config_dir: keycloak_quarkus_config_dir:
# line 15 of defaults/main.yml
default: "{{ keycloak_quarkus_home }}/conf" default: "{{ keycloak_quarkus_home }}/conf"
description: "Path for configuration" description: "Path for configuration"
type: "str" type: "str"
keycloak_quarkus_service_user: keycloak_quarkus_service_user:
# line 16 of defaults/main.yml
default: "keycloak" default: "keycloak"
description: "Posix account username" description: "Posix account username"
type: "str" type: "str"
keycloak_quarkus_service_group: keycloak_quarkus_service_group:
# line 17 of defaults/main.yml
default: "keycloak" default: "keycloak"
description: "Posix account group" description: "Posix account group"
type: "str" type: "str"
keycloak_quarkus_service_pidfile:
# line 18 of defaults/main.yml
default: "/run/keycloak/keycloak.pid"
description: "Pid file path for service"
type: "str"
keycloak_quarkus_configure_firewalld: keycloak_quarkus_configure_firewalld:
default: false # line 19 of defaults/main.yml
description: "Ensure firewalld is running and configure keycloak ports"
type: "bool"
keycloak_quarkus_configure_iptables:
default: false default: false
description: "Ensure firewalld is running and configure keycloak ports" description: "Ensure firewalld is running and configure keycloak ports"
type: "bool" type: "bool"
@@ -77,10 +90,12 @@ argument_specs:
description: "Password of console admin account" description: "Password of console admin account"
type: "str" type: "str"
keycloak_quarkus_master_realm: keycloak_quarkus_master_realm:
# line 24 of defaults/main.yml
default: "master" default: "master"
description: "Name for rest authentication realm" description: "Name for rest authentication realm"
type: "str" type: "str"
keycloak_quarkus_bind_address: keycloak_quarkus_bind_address:
# line 27 of defaults/main.yml
default: "0.0.0.0" default: "0.0.0.0"
description: "Address for binding service ports" description: "Address for binding service ports"
type: "str" type: "str"
@@ -101,6 +116,7 @@ argument_specs:
description: "Enable listener on HTTP port" description: "Enable listener on HTTP port"
type: "bool" type: "bool"
keycloak_quarkus_http_port: keycloak_quarkus_http_port:
# line 29 of defaults/main.yml
default: 8080 default: 8080
description: "HTTP port" description: "HTTP port"
type: "int" type: "int"
@@ -121,69 +137,47 @@ argument_specs:
description: "Enable configuration of HTTPS via a key store" description: "Enable configuration of HTTPS via a key store"
type: "bool" type: "bool"
keycloak_quarkus_key_store_file: keycloak_quarkus_key_store_file:
default: ""
description: "Deprecated, use `keycloak_quarkus_https_key_store_file` instead."
type: "str"
keycloak_quarkus_key_store_password:
default: ""
description: "Deprecated, use `keycloak_quarkus_https_key_store_password` instead."
type: "str"
keycloak_quarkus_https_key_store_file:
default: "{{ keycloak.home }}/conf/key_store.p12" default: "{{ keycloak.home }}/conf/key_store.p12"
description: "The file path to the key store" description: "The file path to the key store"
type: "str" type: "str"
keycloak_quarkus_https_key_store_password: keycloak_quarkus_key_store_password:
default: "" default: ""
description: "Password for the key store" description: "Password for the key store"
type: "str" type: "str"
keycloak_quarkus_https_trust_store_enabled: keycloak_quarkus_https_trust_store_enabled:
default: false default: false
description: "Enable configuration of the https trust store" description: "Enalbe confiugration of a trust store"
type: "bool" type: "bool"
keycloak_quarkus_https_trust_store_file: keycloak_quarkus_trust_store_file:
default: "{{ keycloak.home }}/conf/trust_store.p12" default: "{{ keycloak.home }}/conf/trust_store.p12"
description: "The file path to the trust store" description: "The file path to the trust store"
type: "str" type: "str"
keycloak_quarkus_https_trust_store_password: keycloak_quarkus_trust_store_password:
default: "" default: ""
description: "Password for the trust store" description: "Password for the trust store"
type: "str" type: "str"
keycloak_quarkus_config_key_store_file:
default: "{{ keycloak.home }}/conf/conf_store.p12"
description: "Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty"
type: "str"
keycloak_quarkus_config_key_store_password:
default: ""
description: "Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text"
type: "str"
keycloak_quarkus_https_port: keycloak_quarkus_https_port:
# line 30 of defaults/main.yml
default: 8443 default: 8443
description: "HTTPS port" description: "HTTPS port"
type: "int" type: "int"
keycloak_quarkus_ajp_port: keycloak_quarkus_ajp_port:
# line 31 of defaults/main.yml
default: 8009 default: 8009
description: "AJP port" description: "AJP port"
type: "int" type: "int"
keycloak_quarkus_jgroups_port: keycloak_quarkus_jgroups_port:
# line 32 of defaults/main.yml
default: 7800 default: 7800
description: "jgroups cluster tcp port" description: "jgroups cluster tcp port"
type: "int" type: "int"
keycloak_quarkus_java_heap_opts:
default: "-Xms1024m -Xmx2048m"
description: "Heap memory JVM setting"
type: "str"
keycloak_quarkus_java_jvm_opts:
default: >
-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8
-Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC
-XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512
description: "Other JVM settings"
type: "str"
keycloak_quarkus_java_opts: keycloak_quarkus_java_opts:
default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}" # line 33 of defaults/main.yml
description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them" default: "-Xms1024m -Xmx2048m"
description: "Additional JVM options"
type: "str" type: "str"
keycloak_quarkus_ha_enabled: keycloak_quarkus_ha_enabled:
# line 36 of defaults/main.yml
default: false default: false
description: "Enable auto configuration for database backend, clustering and remote caches on infinispan" description: "Enable auto configuration for database backend, clustering and remote caches on infinispan"
type: "bool" type: "bool"
@@ -192,6 +186,7 @@ argument_specs:
description: "Discovery protocol for HA cluster members" description: "Discovery protocol for HA cluster members"
type: "str" type: "str"
keycloak_quarkus_db_enabled: keycloak_quarkus_db_enabled:
# line 38 of defaults/main.yml
default: "{{ True if keycloak_quarkus_ha_enabled else False }}" default: "{{ True if keycloak_quarkus_ha_enabled else False }}"
description: "Enable auto configuration for database backend" description: "Enable auto configuration for database backend"
type: "str" type: "str"
@@ -209,6 +204,7 @@ argument_specs:
description: "Service URL for the admin console" description: "Service URL for the admin console"
type: "str" type: "str"
keycloak_quarkus_metrics_enabled: keycloak_quarkus_metrics_enabled:
# line 43 of defaults/main.yml
default: false default: false
description: "Whether to enable metrics" description: "Whether to enable metrics"
type: "bool" type: "bool"
@@ -217,50 +213,62 @@ argument_specs:
description: "If the server should expose health check endpoints" description: "If the server should expose health check endpoints"
type: "bool" type: "bool"
keycloak_quarkus_ispn_user: keycloak_quarkus_ispn_user:
# line 46 of defaults/main.yml
default: "supervisor" default: "supervisor"
description: "Username for connecting to infinispan" description: "Username for connecting to infinispan"
type: "str" type: "str"
keycloak_quarkus_ispn_pass: keycloak_quarkus_ispn_pass:
# line 47 of defaults/main.yml
default: "supervisor" default: "supervisor"
description: "Password for connecting to infinispan" description: "Password for connecting to infinispan"
type: "str" type: "str"
keycloak_quarkus_ispn_hosts: keycloak_quarkus_ispn_hosts:
# line 48 of defaults/main.yml
default: "localhost:11222" default: "localhost:11222"
description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222" description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222"
type: "str" type: "str"
keycloak_quarkus_ispn_sasl_mechanism: keycloak_quarkus_ispn_sasl_mechanism:
# line 49 of defaults/main.yml
default: "SCRAM-SHA-512" default: "SCRAM-SHA-512"
description: "Infinispan auth mechanism" description: "Infinispan auth mechanism"
type: "str" type: "str"
keycloak_quarkus_ispn_use_ssl: keycloak_quarkus_ispn_use_ssl:
# line 50 of defaults/main.yml
default: false default: false
description: "Whether infinispan uses TLS connection" description: "Whether infinispan uses TLS connection"
type: "bool" type: "bool"
keycloak_quarkus_ispn_trust_store_path: keycloak_quarkus_ispn_trust_store_path:
# line 52 of defaults/main.yml
default: "/etc/pki/java/cacerts" default: "/etc/pki/java/cacerts"
description: "Path to infinispan server trust certificate" description: "Path to infinispan server trust certificate"
type: "str" type: "str"
keycloak_quarkus_ispn_trust_store_password: keycloak_quarkus_ispn_trust_store_password:
# line 53 of defaults/main.yml
default: "changeit" default: "changeit"
description: "Password for infinispan certificate keystore" description: "Password for infinispan certificate keystore"
type: "str" type: "str"
keycloak_quarkus_jdbc_engine: keycloak_quarkus_jdbc_engine:
# line 56 of defaults/main.yml
default: "postgres" default: "postgres"
description: "Database engine [mariadb,postres,mssql]" description: "Database engine [mariadb,postres,mssql]"
type: "str" type: "str"
keycloak_quarkus_db_user: keycloak_quarkus_db_user:
# line 58 of defaults/main.yml
default: "keycloak-user" default: "keycloak-user"
description: "User for database connection" description: "User for database connection"
type: "str" type: "str"
keycloak_quarkus_db_pass: keycloak_quarkus_db_pass:
# line 59 of defaults/main.yml
default: "keycloak-pass" default: "keycloak-pass"
description: "Password for database connection" description: "Password for database connection"
type: "str" type: "str"
keycloak_quarkus_jdbc_url: keycloak_quarkus_jdbc_url:
# line 60 of defaults/main.yml
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}" default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}"
description: "JDBC URL for connecting to database" description: "JDBC URL for connecting to database"
type: "str" type: "str"
keycloak_quarkus_jdbc_driver_version: keycloak_quarkus_jdbc_driver_version:
# line 61 of defaults/main.yml
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}" default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}"
description: "Version for JDBC driver" description: "Version for JDBC driver"
type: "str" type: "str"
@@ -287,9 +295,7 @@ argument_specs:
keycloak_quarkus_log_max_file_size: keycloak_quarkus_log_max_file_size:
default: 10M default: 10M
type: "str" type: "str"
description: > description: "Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes."
Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular
expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes.
keycloak_quarkus_log_max_backup_index: keycloak_quarkus_log_max_backup_index:
default: 10 default: 10
type: "str" type: "str"
@@ -297,17 +303,11 @@ argument_specs:
keycloak_quarkus_log_file_suffix: keycloak_quarkus_log_file_suffix:
default: '.yyyy-MM-dd.zip' default: '.yyyy-MM-dd.zip'
type: "str" type: "str"
description: > description: "Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with .zip or .gz, the rotation file will also be compressed."
Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix. Note: If the suffix ends
with .zip or .gz, the rotation file will also be compressed.
keycloak_quarkus_proxy_mode: keycloak_quarkus_proxy_mode:
default: 'edge' default: 'edge'
type: "str" type: "str"
description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy" description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy"
keycloak_quarkus_proxy_headers:
default: ""
type: "str"
description: "Parse reverse proxy headers (`forwarded` or `xforwarded`), overrides the deprecated keycloak_quarkus_proxy_mode argument"
keycloak_quarkus_start_dev: keycloak_quarkus_start_dev:
default: false default: false
type: "bool" type: "bool"
@@ -319,76 +319,19 @@ argument_specs:
keycloak_quarkus_hostname_strict: keycloak_quarkus_hostname_strict:
default: true default: true
type: "bool" type: "bool"
description: > description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header."
Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless
proxy verifies the Host header.
keycloak_quarkus_hostname_strict_backchannel: keycloak_quarkus_hostname_strict_backchannel:
default: false default: false
type: "bool" type: "bool"
description: > description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled."
By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all
applications use the public URL this option should be enabled.
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route:
default: true default: true
type: "bool" type: "bool"
description: > description: "If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy"
If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies
and we rely on the session affinity capabilities from reverse proxy
keycloak_quarkus_hostname_strict_https:
type: "bool"
required: false
description: >
By default, Keycloak requires running using TLS/HTTPS. If the service MUST run without TLS/HTTPS, then set
this option to "true"
keycloak_quarkus_ks_vault_enabled:
default: false
type: "bool"
description: "Whether to enable vault SPI"
keycloak_quarkus_ks_vault_file:
default: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
type: "str"
description: "The keystore path for the vault SPI"
keycloak_quarkus_ks_vault_type:
default: "PKCS12"
type: "str"
description: "Type of the keystore used for the vault SPI"
keycloak_quarkus_ks_vault_pass:
required: false
type: "str"
description: "The password for accessing the keystore vault SPI"
keycloak_quarkus_systemd_wait_for_port:
description: 'Whether systemd unit should wait for keycloak port before returning'
default: "{{ keycloak_quarkus_ha_enabled }}"
type: "bool"
keycloak_quarkus_systemd_wait_for_log:
description: 'Whether systemd unit should wait for service to be up in logs'
default: false
type: "bool"
keycloak_quarkus_systemd_wait_for_timeout:
description: "How long to wait for service to be alive (seconds)"
default: 60
type: 'int'
keycloak_quarkus_systemd_wait_for_delay:
description: "Activation delay for service systemd unit (seconds)"
default: 10
type: 'int'
keycloak_quarkus_providers:
description: "List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'default': bool, 'properties': list of key/value }"
default: []
type: "list"
keycloak_quarkus_jdbc_download_url:
description: "Override the default Maven Central download URL for the JDBC driver"
type: "str"
keycloak_quarkus_jdbc_download_user:
description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location"
type: "str"
keycloak_quarkus_jdbc_download_pass:
description: "Set a password with which to authenticate when downloading JDBC drivers from an alternative location (requires keycloak_quarkus_jdbc_download_user)"
type: "str"
downstream: downstream:
options: options:
rhbk_version: rhbk_version:
default: "22.0.10" default: "22.0.6"
description: "Red Hat Build of Keycloak version" description: "Red Hat Build of Keycloak version"
type: "str" type: "str"
rhbk_archive: rhbk_archive:
@@ -410,7 +353,7 @@ argument_specs:
rhbk_enable: rhbk_enable:
default: true default: true
description: "Enable Red Hat Build of Keycloak installation" description: "Enable Red Hat Build of Keycloak installation"
type: "bool" type: "str"
rhbk_offline_install: rhbk_offline_install:
default: false default: false
description: "Perform an offline install" description: "Perform an offline install"

View File

@@ -14,11 +14,6 @@ galaxy_info:
- name: EL - name: EL
versions: versions:
- "8" - "8"
- "9"
- name: Fedora
- name: Debian
- name: Ubuntu
galaxy_tags: galaxy_tags:
- keycloak - keycloak
@@ -30,4 +25,3 @@ galaxy_info:
- identity - identity
- security - security
- rhbk - rhbk
- debian

View File

@@ -1,16 +0,0 @@
---
- name: Write ansible custom facts
become: true
ansible.builtin.template:
src: keycloak.fact.j2
dest: /etc/ansible/facts.d/keycloak.fact
mode: '0644'
vars:
bootstrapped: true
- name: Re-read custom facts
ansible.builtin.setup:
filter: ansible_local
- name: Ensure that `KEYCLOAK_ADMIN[_PASSWORD]` get purged
ansible.builtin.include_tasks: systemd.yml

View File

@@ -1,52 +0,0 @@
---
- name: "Initialize configuration key store variables to be written"
ansible.builtin.set_fact:
store_items:
- key: "kc.db-password"
value: "{{ keycloak_quarkus_db_pass }}"
- name: "Initialize empty configuration key store"
become: true
# keytool doesn't allow creating an empty key store, so this is a hacky way around it
ansible.builtin.shell: |
set -o nounset # abort on unbound variable
set -o pipefail # do not hide errors within pipes
set -o errexit # abort on nonzero exit status
echo dummy | keytool -noprompt -importpass -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12
keytool -delete -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
args:
creates: "{{ keycloak_quarkus_config_key_store_file }}"
- name: "Set configuration key store using keytool"
ansible.builtin.shell: |
set -o nounset # abort on unbound variable
set -o pipefail # do not hide errors within pipes
keytool -list -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
retVal=$?
set -o errexit # abort on nonzero exit status
if [ $retVal -eq 0 ]; then
# value is already in keystore, but keytool has no replace function: delete and re-create instead
# note that we can not read whether the value has changed either[^1], so we need to override it
# [^1]: https://stackoverflow.com/a/37491400
keytool -delete -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
fi
echo {{ item.value | quote }} | keytool -noprompt -importpass -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12
with_items: "{{ store_items }}"
no_log: true
become: true
changed_when: true
notify:
- restart keycloak
- name: "Set owner of configuration key store {{ keycloak_quarkus_config_key_store_file }}"
ansible.builtin.file:
path: "{{ keycloak_quarkus_config_key_store_file }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0400'
become: true

View File

@@ -1,6 +0,0 @@
---
- name: Include firewall config tasks
ansible.builtin.include_tasks: iptables.yml
when: keycloak_quarkus_configure_iptables
tags:
- firewall

View File

@@ -1,36 +0,0 @@
---
- name: Check deprecation keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store
delegate_to: localhost
run_once: true
when:
- keycloak_quarkus_https_key_store_enabled
block:
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_file`, superseded by `keycloak_quarkus_https_key_store_file`
when:
- keycloak_quarkus_key_store_file is defined
- keycloak_quarkus_key_store_file != ''
- keycloak_quarkus_https_key_store_file == keycloak.home + "/conf/key_store.p12" # default value
changed_when: true
ansible.builtin.set_fact:
keycloak_quarkus_https_key_store_file: "{{ keycloak_quarkus_key_store_file }}"
deprecated_variable: "keycloak_quarkus_key_store_file" # read in deprecation handler
notify:
- print deprecation warning
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_password`, superseded by `keycloak_quarkus_https_key_store_password`
when:
- keycloak_quarkus_key_store_password is defined
- keycloak_quarkus_key_store_password != ''
- keycloak_quarkus_https_key_store_password == "" # default value
changed_when: true
ansible.builtin.set_fact:
keycloak_quarkus_https_key_store_password: "{{ keycloak_quarkus_key_store_password }}"
deprecated_variable: "keycloak_quarkus_key_store_password" # read in deprecation handler
notify:
- print deprecation warning
- name: Flush handlers
ansible.builtin.meta: flush_handlers

View File

@@ -4,28 +4,14 @@
register: rpm_info register: rpm_info
changed_when: false changed_when: false
failed_when: false failed_when: false
when: ansible_facts.os_family == "RedHat"
- name: "Add missing packages to the yum install list" - name: "Add missing packages to the yum install list"
ansible.builtin.set_fact: ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | \ packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
when: ansible_facts.os_family == "RedHat"
- name: "Install packages: {{ packages_to_install }}" - name: "Install packages: {{ packages_to_install }}"
become: true become: true
ansible.builtin.dnf: ansible.builtin.yum:
name: "{{ packages_to_install }}" name: "{{ packages_to_install }}"
state: present state: present
when: when: packages_to_install | default([]) | length > 0
- packages_to_install | default([]) | length > 0
- ansible_facts.os_family == "RedHat"
- name: "Install packages: {{ packages_list }}"
become: true
ansible.builtin.package:
name: "{{ packages_list }}"
state: present
when:
- packages_list | default([]) | length > 0
- ansible_facts.os_family == "Debian"

View File

@@ -22,7 +22,7 @@
name: "{{ keycloak.service_user }}" name: "{{ keycloak.service_user }}"
home: /opt/keycloak home: /opt/keycloak
system: true system: true
create_home: false create_home: no
- name: "Create {{ keycloak.service_name }} install location" - name: "Create {{ keycloak.service_name }} install location"
become: true become: true
@@ -31,14 +31,7 @@
state: directory state: directory
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0750' mode: 0750
- name: Create directory for ansible custom facts
become: true
ansible.builtin.file:
state: directory
recurse: true
path: /etc/ansible/facts.d
## check remote archive ## check remote archive
- name: Set download archive path - name: Set download archive path
@@ -57,15 +50,13 @@
path: "{{ lookup('env', 'PWD') }}" path: "{{ lookup('env', 'PWD') }}"
register: local_path register: local_path
delegate_to: localhost delegate_to: localhost
become: false
- name: Download keycloak archive - name: Download keycloak archive
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_quarkus_download_url }}" url: "{{ keycloak_quarkus_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0640' mode: 0640
delegate_to: localhost delegate_to: localhost
become: false
run_once: true run_once: true
when: when:
- archive_path is defined - archive_path is defined
@@ -125,7 +116,7 @@
dest: "{{ archive }}" dest: "{{ archive }}"
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0640' mode: 0640
register: new_version_downloaded register: new_version_downloaded
when: when:
- not archive_path.stat.exists - not archive_path.stat.exists
@@ -139,7 +130,7 @@
register: path_to_workdir register: path_to_workdir
become: true become: true
- name: "Extract Keycloak archive on target" # noqa no-handler need to run this here - name: "Extract Keycloak archive on target"
ansible.builtin.unarchive: ansible.builtin.unarchive:
remote_src: true remote_src: true
src: "{{ archive }}" src: "{{ archive }}"
@@ -164,15 +155,3 @@
when: when:
- rhbk_enable is defined and rhbk_enable - rhbk_enable is defined and rhbk_enable
- keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined
- name: "Download custom providers"
ansible.builtin.get_url:
url: "{{ item.url }}"
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
loop: "{{ keycloak_quarkus_providers }}"
when: item.url is defined and item.url | length > 0
notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}"

View File

@@ -1,20 +0,0 @@
---
- name: Ensure required package iptables are installed
ansible.builtin.include_tasks: fastpackages.yml
vars:
packages_list:
- iptables
- name: "Configure firewall ports for {{ keycloak.service_name }}"
become: true
ansible.builtin.iptables:
destination_port: "{{ item }}"
action: "insert"
rule_num: 6 # magic number I forget why
chain: "INPUT"
policy: "ACCEPT"
protocol: tcp
loop:
- "{{ keycloak_quarkus_http_port }}"
- "{{ keycloak_quarkus_https_port }}"
- "{{ keycloak_quarkus_jgroups_port }}"

View File

@@ -1,20 +1,12 @@
--- ---
- name: "Verify valid parameters for download credentials when specified"
ansible.builtin.fail: - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}"
msg: >-
When JDBC driver download credentials are set, both the username and the password MUST be set
when:
- keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined
- keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined
- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_user | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}"
ansible.builtin.get_url: ansible.builtin.get_url:
url: "{{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url) }}" url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}"
dest: "{{ keycloak.home }}/providers" dest: "{{ keycloak.home }}/providers"
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" mode: 0640
url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}"
mode: '0640'
become: true become: true
notify: notify:
- restart keycloak - restart keycloak

View File

@@ -4,17 +4,12 @@
ansible.builtin.include_tasks: prereqs.yml ansible.builtin.include_tasks: prereqs.yml
tags: tags:
- prereqs - prereqs
- always
- name: Check for deprecations - name: Include firewall config tasks
ansible.builtin.include_tasks: deprecations.yml ansible.builtin.include_tasks: firewalld.yml
when: keycloak_quarkus_configure_firewalld
tags: tags:
- always - firewall
- name: Distro specific tasks
ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml"
tags:
- unbound
- name: Include install tasks - name: Include install tasks
ansible.builtin.include_tasks: install.yml ansible.builtin.include_tasks: install.yml
@@ -26,11 +21,28 @@
tags: tags:
- systemd - systemd
- name: Include configuration key store tasks - name: "Configure config for keycloak service"
when: keycloak.config_key_store_enabled ansible.builtin.template:
ansible.builtin.include_tasks: config_store.yml src: keycloak.conf.j2
tags: dest: "{{ keycloak.home }}/conf/keycloak.conf"
- install owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0644
become: true
notify:
- rebuild keycloak config
- restart keycloak
- name: "Configure quarkus config for keycloak service"
ansible.builtin.template:
src: quarkus.properties.j2
dest: "{{ keycloak.home }}/conf/quarkus.properties"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0644
become: true
notify:
- restart keycloak
- name: Create tcpping cluster node list - name: Create tcpping cluster node list
ansible.builtin.set_fact: ansible.builtin.set_fact:
@@ -46,18 +58,14 @@
loop: "{{ ansible_play_batch }}" loop: "{{ ansible_play_batch }}"
when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING'
- name: "Configure config files for keycloak service" - name: "Configure infinispan config for keycloak service"
ansible.builtin.template: ansible.builtin.template:
src: "{{ item }}.j2" src: cache-ispn.xml.j2
dest: "{{ keycloak.home }}/conf/{{ item }}" dest: "{{ keycloak.home }}/conf/cache-ispn.xml"
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0640' mode: 0644
become: true become: true
loop:
- keycloak.conf
- quarkus.properties
- cache-ispn.xml
notify: notify:
- rebuild keycloak config - rebuild keycloak config
- restart keycloak - restart keycloak
@@ -65,10 +73,10 @@
- name: Ensure logdirectory exists - name: Ensure logdirectory exists
ansible.builtin.file: ansible.builtin.file:
state: directory state: directory
path: "{{ keycloak.log.file | dirname }}" path: "{{ keycloak.log.file | dirname }}"
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0775' mode: 0775
become: true become: true
- name: Flush pending handlers - name: Flush pending handlers
@@ -77,6 +85,11 @@
- name: "Start and wait for keycloak service" - name: "Start and wait for keycloak service"
ansible.builtin.include_tasks: start.yml ansible.builtin.include_tasks: start.yml
- name: Check service status
ansible.builtin.command: "systemctl status keycloak"
register: keycloak_service_status
changed_when: false
- name: Link default logs directory - name: Link default logs directory
ansible.builtin.file: ansible.builtin.file:
state: link state: link
@@ -84,21 +97,3 @@
dest: "{{ keycloak_quarkus_log_target }}" dest: "{{ keycloak_quarkus_log_target }}"
force: true force: true
become: true become: true
- name: Check service status
ansible.builtin.systemd_service:
name: "{{ keycloak.service_name }}"
register: keycloak_service_status
changed_when: false
- name: "Trigger bootstrapped notification: remove `keycloak_quarkus_admin_user[_pass]` env vars"
when:
- not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution
- keycloak_service_status.status.ActiveState == "active" # but it is now
ansible.builtin.assert: { that: true, quiet: true }
changed_when: true
notify:
- bootstrapped
- name: Flush pending handlers
ansible.builtin.meta: flush_handlers

View File

@@ -4,64 +4,31 @@
that: that:
- keycloak_quarkus_admin_pass | length > 12 - keycloak_quarkus_admin_pass | length > 12
quiet: true quiet: true
fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass to a 12+ char long string" fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string"
success_msg: "{{ 'Console administrator password OK' }}" success_msg: "{{ 'Console administrator password OK' }}"
- name: Validate relative path - name: Validate relative path
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- keycloak_quarkus_http_relative_path is regex('^/.*') - keycloak_quarkus_http_relative_path is regex('^/.*')
quiet: true quiet: true
fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /" fail_msg: "the relative path must begin with /"
success_msg: "{{ 'Relative path OK' }}" success_msg: "{{ 'relative path OK' }}"
- name: Validate configuration - name: Validate configuration
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
(not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
(not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
quiet: true quiet: true
fail_msg: "HA setup requires a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled"
success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}"
- name: Validate OS family
ansible.builtin.assert:
that:
- ansible_os_family in ["RedHat", "Debian"]
quiet: true
fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}"
success_msg: "Installing on {{ ansible_os_family }}"
- name: Load OS specific variables
ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml"
tags:
- always
- name: Ensure required packages are installed - name: Ensure required packages are installed
ansible.builtin.include_tasks: fastpackages.yml ansible.builtin.include_tasks: fastpackages.yml
vars: vars:
packages_list: "{{ keycloak_quarkus_prereq_package_list }}" packages_list:
- "{{ keycloak_quarkus_jvm_package }}"
- name: "Validate keytool" - unzip
when: keycloak_quarkus_config_key_store_password | length > 0 - procps-ng
block: - initscripts
- name: "Attempt to run keytool" - tzdata-java
changed_when: false
ansible.builtin.command: keytool -help
register: keytool_check
ignore_errors: true
- name: "Fail when no keytool found"
when: keytool_check.rc != 0
ansible.builtin.fail:
msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store"
- name: "Validate providers"
ansible.builtin.assert:
that:
- item.id is defined and item.id | length > 0
- (item.spi is defined and item.spi | length > 0) or (item.url is defined and item.url | length > 0)
quiet: true
fail_msg: "Providers definition is incorrect; `id` and one of `spi` or `url` are mandatory. `key` and `value` are mandatory for each property"
loop: "{{ keycloak_quarkus_providers }}"

View File

@@ -1,6 +0,0 @@
---
- name: Include firewall config tasks
ansible.builtin.include_tasks: firewalld.yml
when: keycloak_quarkus_configure_firewalld
tags:
- firewall

View File

@@ -1,6 +1,5 @@
--- ---
- name: "Restart and enable {{ keycloak.service_name }} service" - name: "Restart and enable {{ keycloak.service_name }} service"
throttle: 1
ansible.builtin.systemd: ansible.builtin.systemd:
name: keycloak name: keycloak
enabled: true enabled: true

View File

@@ -13,4 +13,4 @@
register: keycloak_status register: keycloak_status
until: keycloak_status.status == 200 until: keycloak_status.status == 200
retries: 25 retries: 25
delay: 10 delay: 10

View File

@@ -1,14 +1,18 @@
--- ---
- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - name: Determine JAVA_HOME for selected JVM RPM
ansible.builtin.set_fact:
rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}"
- name: "Configure sysconfig file for keycloak service"
become: true become: true
ansible.builtin.template: ansible.builtin.template:
src: keycloak-sysconfig.j2 src: keycloak-sysconfig.j2
dest: "{{ keycloak_quarkus_sysconf_file }}" dest: /etc/sysconfig/keycloak
owner: root owner: root
group: root group: root
mode: '0640' mode: 0644
vars: vars:
keycloak_sys_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}" keycloak_rpm_java_home: "{{ rpm_java_home }}"
notify: notify:
- restart keycloak - restart keycloak
@@ -18,7 +22,7 @@
dest: /etc/systemd/system/keycloak.service dest: /etc/systemd/system/keycloak.service
owner: root owner: root
group: root group: root
mode: '0644' mode: 0644
become: true become: true
register: systemdunit register: systemdunit
notify: notify:

View File

@@ -1,4 +1,4 @@
{{ ansible_managed | comment('xml') }} <!-- {{ ansible_managed }} -->
<!-- <!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates ~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags. ~ and other contributors as indicated by the @author tags.

View File

@@ -1,10 +1,6 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
{% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %}
KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }} KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }}
KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}' KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}'
{% else %} PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
{{ keycloak.bootstrap_mnemonic }} JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}
{% endif %} JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }}
PATH={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_sys_pkg_java_home, true) }}
JAVA_OPTS={{ keycloak_quarkus_java_opts }}

View File

@@ -1,28 +1,12 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
{% if keycloak_quarkus_db_enabled %} {% if keycloak_quarkus_db_enabled %}
# Database # Database
db={{ keycloak_quarkus_jdbc_engine }} db={{ keycloak_quarkus_jdbc_engine }}
db-url={{ keycloak_quarkus_jdbc_url }} db-url={{ keycloak_quarkus_jdbc_url }}
db-username={{ keycloak_quarkus_db_user }} db-username={{ keycloak_quarkus_db_user }}
{% if not keycloak.config_key_store_enabled %}
db-password={{ keycloak_quarkus_db_pass }} db-password={{ keycloak_quarkus_db_pass }}
{% endif %} {% endif %}
{% endif %}
{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas true -%}
hostname-strict-https=true
{% endif -%}
{% if keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is sameas false -%}
hostname-strict-https=false
{% endif -%}
{% if keycloak.config_key_store_enabled %}
# Config store
config-keystore={{ keycloak_quarkus_config_key_store_file }}
config-keystore-password={{ keycloak_quarkus_config_key_store_password }}
config-keystore-type=PKCS12
{% endif %}
# Observability # Observability
metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }} metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }}
@@ -40,12 +24,12 @@ https-certificate-file={{ keycloak_quarkus_cert_file}}
https-certificate-key-file={{ keycloak_quarkus_key_file }} https-certificate-key-file={{ keycloak_quarkus_key_file }}
{% endif %} {% endif %}
{% if keycloak_quarkus_https_key_store_enabled %} {% if keycloak_quarkus_https_key_store_enabled %}
https-key-store-file={{ keycloak_quarkus_https_key_store_file }} https-key-store-file={{ keycloak_quarkus_key_store_file }}
https-key-store-password={{ keycloak_quarkus_https_key_store_password }} https-key-store-password={{ keycloak_quarkus_key_store_password }}
{% endif %} {% endif %}
{% if keycloak_quarkus_https_trust_store_enabled %} {% if keycloak_quarkus_https_trust_store_enabled %}
https-trust-store-file={{ keycloak_quarkus_https_trust_store_file }} https-trust-store-file={{ keycloak_quarkus_trust_store_file }}
https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }} https-trust-store-password={{ keycloak_quarkus_trust_store_password }}
{% endif %} {% endif %}
# Client URL configuration # Client URL configuration
@@ -70,14 +54,9 @@ cache-config-file=cache-ispn.xml
{% endif %} {% endif %}
{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %} {% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %}
# Deprecated Proxy configuration # Proxy
proxy={{ keycloak_quarkus_proxy_mode }} proxy={{ keycloak_quarkus_proxy_mode }}
{% endif %} {% endif %}
{% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %}
# Proxy
proxy-headers={{ keycloak_quarkus_proxy_headers }}
{% endif %}
spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }} spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }}
# Transaction # Transaction
@@ -89,22 +68,3 @@ log={{ keycloak_quarkus_log }}
log-level={{ keycloak.log.level }} log-level={{ keycloak.log.level }}
log-file={{ keycloak.log.file }} log-file={{ keycloak.log.file }}
log-file-format={{ keycloak.log.format }} log-file-format={{ keycloak.log.format }}
# Vault
{% if keycloak_quarkus_ks_vault_enabled %}
vault=keystore
vault-file={{ keycloak_quarkus_ks_vault_file }}
vault-type={{ keycloak_quarkus_ks_vault_type }}
vault-pass={{ keycloak_quarkus_ks_vault_pass }}
{% endif %}
# Providers
{% for provider in keycloak_quarkus_providers %}
{% if provider.default is defined and provider.default %}
spi-{{ provider.spi }}-provider={{ provider.id }}
{% endif %}
{% if provider.properties is defined %}{% for property in provider.properties %}
spi-{{ provider.spi }}-{{ provider.id }}-{{ property.key }}={{ property.value }}
{% endfor %}{% endif %}
{% endfor %}

View File

@@ -1,2 +0,0 @@
[general]
bootstrapped={{ bootstrapped | lower }}

View File

@@ -1,10 +1,12 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
[Unit] [Unit]
Description=Keycloak Server Description=Keycloak Server
After=network.target After=network.target
[Service] [Service]
EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }} Type=simple
EnvironmentFile=-/etc/sysconfig/keycloak
PIDFile={{ keycloak_quarkus_service_pidfile }}
{% if keycloak_quarkus_start_dev %} {% if keycloak_quarkus_start_dev %}
ExecStart={{ keycloak.home }}/bin/kc.sh start-dev ExecStart={{ keycloak.home }}/bin/kc.sh start-dev
{% else %} {% else %}
@@ -12,22 +14,15 @@ ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized
{% endif %} {% endif %}
User={{ keycloak.service_user }} User={{ keycloak.service_user }}
Group={{ keycloak.service_group }} Group={{ keycloak.service_group }}
SuccessExitStatus=0 143
{% if keycloak_quarkus_service_restart_always %} {% if keycloak_quarkus_service_restart_always %}
Restart=always Restart=always
{% elif keycloak_quarkus_service_restart_on_failure %} {% elif keycloak_quarkus_service_restart_on_failure %}
Restart=on-failure Restart=on-failure
{% endif %} {% endif %}
RestartSec={{ keycloak_quarkus_service_restartsec }} RestartSec={{ keycloak_quarkus_service_restartsec }}
{% if keycloak_quarkus_http_port | int < 1024 or keycloak_quarkus_https_port | int < 1024 %} {% if keycloak_quarkus_http_port|int < 1024 or keycloak_quarkus_https_port|int < 1024 %}
AmbientCapabilities=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE
{% endif %} {% endif %}
{% if keycloak_quarkus_systemd_wait_for_port %}
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_https_port }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_https_port }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
{% endif %}
{% if keycloak_quarkus_systemd_wait_for_log %}
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'cat {{ keycloak.log.file }} | sed "/Profile.*activated/ q" && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
{% endif %}
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,4 +1,4 @@
{{ ansible_managed | comment }} # {{ ansible_managed }}
{% if keycloak_quarkus_ha_enabled %} {% if keycloak_quarkus_ha_enabled %}
{% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %} {% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %}
quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }} quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }}

View File

@@ -1,11 +0,0 @@
---
keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-17-jdk-headless') }}"
keycloak_quarkus_prereq_package_list:
- "{{ keycloak_quarkus_varjvm_package }}"
- unzip
- procps
- apt
- tzdata
keycloak_quarkus_sysconf_file: /etc/default/keycloak
keycloak_quarkus_pkg_java_home: "/usr/lib/jvm/java-{{ keycloak_quarkus_varjvm_package | \
regex_search('(?!:openjdk-)[0-9.]+') }}-openjdk-{{ 'arm64' if ansible_architecture == 'aarch64' else 'amd64' }}"

View File

@@ -1,18 +1,15 @@
--- ---
keycloak: # noqa var-naming this is an internal dict of interpolated values keycloak:
home: "{{ keycloak_quarkus_home }}" home: "{{ keycloak_quarkus_home }}"
config_dir: "{{ keycloak_quarkus_config_dir }}" config_dir: "{{ keycloak_quarkus_config_dir }}"
bundle: "{{ keycloak_quarkus_archive }}" bundle: "{{ keycloak_quarkus_archive }}"
service_name: "keycloak" service_name: "keycloak"
health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \ health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration"
if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration"
cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh" cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh"
service_user: "{{ keycloak_quarkus_service_user }}" service_user: "{{ keycloak_quarkus_service_user }}"
service_group: "{{ keycloak_quarkus_service_group }}" service_group: "{{ keycloak_quarkus_service_group }}"
offline_install: "{{ keycloak_quarkus_offline_install }}" offline_install: "{{ keycloak_quarkus_offline_install }}"
config_key_store_enabled: "{{ keycloak_quarkus_config_key_store_password != '' }}"
log: log:
file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}" file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}"
level: "{{ keycloak_quarkus_log_level }}" level: "{{ keycloak_quarkus_log_level }}"
format: "{{ keycloak_quarkus_log_format }}" format: "{{ keycloak_quarkus_log_format }}"
bootstrap_mnemonic: "# ansible-middleware/keycloak: bootstrapped"

View File

@@ -1,10 +0,0 @@
---
keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-17-openjdk-headless') }}"
keycloak_quarkus_prereq_package_list:
- "{{ keycloak_quarkus_varjvm_package }}"
- unzip
- procps-ng
- initscripts
- tzdata-java
keycloak_quarkus_sysconf_file: /etc/sysconfig/keycloak
keycloak_quarkus_pkg_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_varjvm_package | regex_search('(?<=java-)[0-9.]+') }}"

View File

@@ -26,14 +26,14 @@ keycloak_admin_password: ''
# and users is a list of account, see below for the format definition # and users is a list of account, see below for the format definition
# an empty name will skip the creation of the client # an empty name will skip the creation of the client
# #
# keycloak_clients: #keycloak_clients:
# - name: '' # - name: ''
# roles: "{{ keycloak_client_default_roles }}" # roles: "{{ keycloak_client_default_roles }}"
# realm: "{{ keycloak_realm }}" # realm: "{{ keycloak_realm }}"
# public_client: "{{ keycloak_client_public }}" # public_client: "{{ keycloak_client_public }}"
# web_origins: "{{ keycloak_client_web_origins }}" # web_origins: "{{ keycloak_client_web_origins }}"
# redirect_uris: "{{ keycloak_client_redirect_uris }}" # redirect_uris: "{{ keycloak_client_redirect_uris }}"
# users: "{{ keycloak_client_users }}" # users: "{{ keycloak_client_users }}"
keycloak_clients: [] keycloak_clients: []
# list of roles to create in the client # list of roles to create in the client

View File

@@ -10,7 +10,7 @@ argument_specs:
# line 5 of keycloak_realm/defaults/main.yml # line 5 of keycloak_realm/defaults/main.yml
default: "/auth" default: "/auth"
description: "Context path for rest calls" description: "Context path for rest calls"
type: "str" type: "str"
keycloak_http_port: keycloak_http_port:
# line 4 of keycloak_realm/defaults/main.yml # line 4 of keycloak_realm/defaults/main.yml
default: 8080 default: 8080
@@ -112,7 +112,7 @@ argument_specs:
sso_enable: sso_enable:
default: true default: true
description: "Enable Red Hat Single Sign-on installation" description: "Enable Red Hat Single Sign-on installation"
type: "bool" type: "str"
rhbk_version: rhbk_version:
default: "22.0.6" default: "22.0.6"
description: "Red Hat Build of Keycloak version" description: "Red Hat Build of Keycloak version"
@@ -132,4 +132,4 @@ argument_specs:
rhbk_enable: rhbk_enable:
default: true default: true
description: "Enable Red Hat Build of Keycloak installation" description: "Enable Red Hat Build of Keycloak installation"
type: "bool" type: "str"

View File

@@ -41,11 +41,11 @@
auth_realm: "{{ keycloak_auth_realm }}" auth_realm: "{{ keycloak_auth_realm }}"
auth_username: "{{ keycloak_admin_user }}" auth_username: "{{ keycloak_admin_user }}"
auth_password: "{{ keycloak_admin_password }}" auth_password: "{{ keycloak_admin_password }}"
realm: "{{ item.realm | default(keycloak_realm) }}" realm: "{{ item.realm }}"
name: "{{ item.name }}" name: "{{ item.name }}"
state: present state: present
provider_id: "{{ item.provider_id }}" provider_id: "{{ item.provider_id }}"
provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}" provider_type: "{{ item.provider_type | default(org.keycloak.storage.UserStorageProvider) }}"
config: "{{ item.config }}" config: "{{ item.config }}"
mappers: "{{ item.mappers | default(omit) }}" mappers: "{{ item.mappers | default(omit) }}"
no_log: "{{ keycloak_no_log | default('True') }}" no_log: "{{ keycloak_no_log | default('True') }}"
@@ -71,7 +71,7 @@
auth_realm: "{{ keycloak_auth_realm }}" auth_realm: "{{ keycloak_auth_realm }}"
auth_username: "{{ keycloak_admin_user }}" auth_username: "{{ keycloak_admin_user }}"
auth_password: "{{ keycloak_admin_password }}" auth_password: "{{ keycloak_admin_password }}"
realm: "{{ item.realm | default(keycloak_realm) }}" realm: "{{ item.realm }}"
default_roles: "{{ item.roles | default(omit) }}" default_roles: "{{ item.roles | default(omit) }}"
client_id: "{{ item.client_id | default(omit) }}" client_id: "{{ item.client_id | default(omit) }}"
id: "{{ item.id | default(omit) }}" id: "{{ item.id | default(omit) }}"

View File

@@ -1,7 +1,7 @@
- name: Create client roles - name: Create client roles
middleware_automation.keycloak.keycloak_role: middleware_automation.keycloak.keycloak_role:
name: "{{ item }}" name: "{{ item }}"
realm: "{{ client.realm | default(keycloak_realm) }}" realm: "{{ client.realm }}"
client_id: "{{ client.name }}" client_id: "{{ client.name }}"
auth_client_id: "{{ keycloak_auth_client }}" auth_client_id: "{{ keycloak_auth_client }}"
auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}" auth_keycloak_url: "{{ keycloak_url }}{{ keycloak_context }}"

View File

@@ -10,4 +10,4 @@
loop: "{{ client.users | flatten }}" loop: "{{ client.users | flatten }}"
loop_control: loop_control:
loop_var: user loop_var: user
when: "'client_roles' in user" when: "'client_roles' in user"

View File

@@ -1,7 +1,7 @@
--- ---
- name: "Get Realm for role" - name: "Get Realm for role"
ansible.builtin.uri: ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | default(keycloak_realm) }}" url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm }}"
method: GET method: GET
status_code: status_code:
- 200 - 200
@@ -12,9 +12,7 @@
- name: Check if Mapping is available - name: Check if Mapping is available
ansible.builtin.uri: ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | \ url: "{{ keycloak_url }}{{ keycloak_context }}/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"
default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \
selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}/available"
method: GET method: GET
status_code: status_code:
- 200 - 200
@@ -25,9 +23,7 @@
- name: "Create Role Mapping" - name: "Create Role Mapping"
ansible.builtin.uri: ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ client_role.realm | \ url: "{{ keycloak_url }}{{ keycloak_context }}/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 }}"
default(keycloak_realm) }}/users/{{ (keycloak_user.json | first).id }}/role-mappings/clients/{{ (create_client_result.results | \
selectattr('end_state.clientId', 'equalto', client_role.client) | list | first).end_state.id }}"
method: POST method: POST
body: body:
- id: "{{ item.id }}" - id: "{{ item.id }}"