Compare commits

...

117 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
Guido Grazioli
d74820190f ci: rename keycloak_quarkus infinispan jinja2 template 2024-02-28 17:10:02 +01:00
ansible-middleware-core
6541b5e386 Bump version to 2.1.1 2024-02-28 15:58:47 +00:00
ansible-middleware-core
1e1665adb0 Update changelog for release 2.1.0
Signed-off-by: ansible-middleware-core <ansible-middleware-core@redhat.com>
2024-02-28 15:58:33 +00:00
Guido Grazioli
33a839fec6 Merge pull request #171 from guidograzioli/170_quarkus_java_home_typo
keycloak_quarkus: fix custom JAVA_HOME parameter name
2024-02-27 19:35:31 +01:00
Guido Grazioli
d97ddbde3c add test 2024-02-27 19:27:07 +01:00
Guido Grazioli
7f021a849e Linter 2024-02-27 17:17:24 +01:00
Guido Grazioli
167bf512c5 fix typo in variable name 2024-02-27 17:17:14 +01:00
Guido Grazioli
beee25dec2 Merge pull request #169 from ansible-middleware/mol_sudo
Adapt molecule tests to work with none root user on target (sudo)
2024-02-26 18:39:42 +01:00
Romain Pelisse
5bd39a0d0e molecule: use block to skip assets download entirely if needed 2024-02-26 16:46:30 +01:00
Romain Pelisse
7324f48e8d molecule: cleanup prepare to use one play 2024-02-26 16:46:30 +01:00
Romain Pelisse
b3ca517583 molecule: adapt sudo setup to work when ansible is not connecting as root on the target 2024-02-26 16:46:26 +01:00
Guido Grazioli
b1848046dc Merge pull request #168 from Footur/update-keycloak-v23.0.7
Update Keycloak to version 23.0.7
2024-02-26 10:19:54 +01:00
Guido Grazioli
983a1fb8f2 Merge pull request #167 from guidograzioli/xa_enable_recovery
Set enable-recovery when xa transactions are enabled
2024-02-26 10:19:44 +01:00
Footur
d4fb20b230 Update Keycloak to version 23.0.7 2024-02-22 17:10:22 +01:00
Guido Grazioli
f7bef0a956 set enable-recovery when xa transactions are enabled 2024-02-22 16:28:24 +01:00
Guido Grazioli
f62a97709a Merge pull request #163 from world-direct/feature/162_keycloak_quarkus_sticky-session-encoder
keycloak_quarkus: `sticky-session`s for infinispan routes
2024-02-08 21:31:12 +01:00
Guido Grazioli
9593752e62 Merge pull request #161 from world-direct/feature/160_keycloak_quarkus_logging
keycloak_quarkus: Allow configuring log rotate options in quarkus configuration
2024-02-08 21:27:48 +01:00
Guido Grazioli
d6c29ed4fc Merge pull request #159 from world-direct/feature/inifinispan_ha
#158: Feature/inifinispan TCPPING
2024-02-08 21:24:53 +01:00
Helmut Wolf
df81dc5497 #158: move TCPPING config to ispn config file 2024-02-08 16:26:48 +01:00
Helmut Wolf
4adab64dc0 #158: support for TCPPING 2024-02-08 16:26:48 +01:00
Helmut Wolf
e0d4920a49 feature/162: keycloak_quarkus: make spi-sticky-session-encoder-infinispan-should-attach-route configurable in keycloak.conf 2024-02-08 16:19:14 +01:00
Helmut Wolf
c2009a0a12 feature/160: CR changes 2024-02-08 16:10:32 +01:00
Helmut Wolf
0c5047bcc1 feature/160: keycloak_quarkus: Allow easier log setting configuration 2024-01-22 13:53:28 +01:00
Helmut Wolf
63f83d7744 add initial support for templating cache-ispn.xml 2024-01-22 12:38:29 +01:00
Guido Grazioli
64fa8bb788 Merge pull request #157 from world-direct/fix/156_infinispan
keycloak_quarkus: renamed infinispan host list configuration
2024-01-22 08:14:36 +01:00
Helmut Wolf
688ec956fc fix #156: quarkus 3 ispn config renamings 2024-01-19 09:54:54 +01:00
ansible-middleware-core
e866d1f4e4 Bump version to 2.0.3 2024-01-17 08:50:31 +00:00
ansible-middleware-core
2985f808ea Update changelog for release 2.0.2
Signed-off-by: ansible-middleware-core <ansible-middleware-core@redhat.com>
2024-01-17 08:50:24 +00:00
Guido Grazioli
30309582f3 Update README.md 2024-01-16 09:17:47 +01:00
Guido Grazioli
40229631e6 Merge pull request #150 from world-direct/fix/149
keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit
2024-01-16 09:04:54 +01:00
Helmut Wolf
8adc018cb3 fix/#149: keycloak_quarkus: Allow ports <1024 (e.g., :443) 2024-01-16 08:33:34 +01:00
Guido Grazioli
053d0f9873 Merge pull request #152 from world-direct/fix/151
keycloak_quarkus: allow configuration of `hostname-strict-backchannel`
2024-01-16 00:42:12 +01:00
Guido Grazioli
eb80ed0bd4 Merge pull request #148 from world-direct/feature/rhbk_mssql_driver
keycloak_quarkus: Add support for sqlserver jdbc driver
2024-01-16 00:41:47 +01:00
Guido Grazioli
d138b4b2ff Merge pull request #145 from world-direct/feature/keycloak_quarkus_systemd
keycloak_quarkus: systemd restart behavior
2024-01-16 00:41:35 +01:00
Helmut Wolf
922e4c10f5 #145 - CR changes 2024-01-15 14:40:46 +01:00
Guido Grazioli
313bd8452a Merge pull request #154 from world-direct/fix/#153
fix/#153: keycloak_quarkus: Use `keycloak_quarkus_java_opts`
2024-01-15 09:57:34 +01:00
Helmut Wolf
b1b31427d5 fix/#153: keycloak_quarkus: Use keycloak_quarkus_java_opts
Note: when multiple -X options of the same kind are provided, the last option seems to take precendence as per <https://stackoverflow.com/a/26727332>:

> java -Xmx1G -XX:+PrintFlagsFinal -Xmx2G 2>/dev/null | grep MaxHeapSize
2024-01-10 16:30:02 +01:00
Helmut Wolf
b057f0297a fix/#151: keycloak_quarkus: allow configuration of hostname-strict-backchannel 2024-01-09 08:46:11 +01:00
Helmut Wolf
bfd9db6703 fix/147: keycloak_quarkus: RBKC: Add support for sqlserver jdbc driver 2024-01-08 17:51:11 +01:00
Helmut Wolf
1d5ce87c16 keycloak_quarkus: Remove legacy (?) keycloak_management_url 2023-12-19 09:55:02 +01:00
Helmut Wolf
83bcb6712a keycloak_quarkus: add systemd control options
* keycloak_quarkus_service_restart_always
* keycloak_quarkus_service_restart_on_failure
* keycloak_quarkus_service_restartsec
2023-12-19 09:30:30 +01:00
Guido Grazioli
dab388d744 Merge pull request #142 from RanabirChakraborty/AMW-170
AMW-170 Ansible Hub links for rhbk are broken
2023-12-12 15:32:00 +01:00
Ranabir Chakraborty
ed6dbd60fb AMW-170 Ansible Hub links for rhbk are broken 2023-12-11 22:12:39 +05:30
ansible-middleware-core
db19fd5d19 Bump version to 2.0.2 2023-12-07 14:30:27 +00:00
ansible-middleware-core
473fb212c3 Update changelog for release 2.0.1
Signed-off-by: ansible-middleware-core <ansible-middleware-core@redhat.com>
2023-12-07 14:30:17 +00:00
Guido Grazioli
98b82ccb4f ci: runner playbook no keypair 2023-12-07 11:15:12 +01:00
Guido Grazioli
0fbf454279 ci: test alternate certs dir 2023-12-07 11:00:28 +01:00
Guido Grazioli
d469d5df8b ci: downstream update sample playbooks 2023-12-06 18:52:46 +01:00
Guido Grazioli
a23bf4c540 ci: downstream use correct version 2023-12-06 18:24:29 +01:00
Guido Grazioli
ac0b421456 downstream: fix rhbk install path 2023-12-06 16:34:55 +01:00
Guido Grazioli
5b8fcb67dc ci: update sample quarkus playbook 2023-12-06 16:03:37 +01:00
Guido Grazioli
acdee7fa63 ci: downstream arg specs for realm role 2023-12-06 15:40:28 +01:00
Guido Grazioli
86576de6e8 Merge pull request #141 from guidograzioli/rhbk_arg_specs
downstream: add rhbk bits
2023-12-06 10:16:05 +01:00
Guido Grazioli
89944a6cd1 downstream: add rhbk bits 2023-12-06 09:57:33 +01:00
Guido Grazioli
33e6d428b5 Merge pull request #140 from guidograzioli/molecule_jbcs_to_nginx
use nginx instead of jbcs for https_revproxy test
2023-12-05 20:09:08 +01:00
Guido Grazioli
f365351abf use nginx instead of jbcs for https_revproxy test 2023-12-05 19:53:26 +01:00
Guido Grazioli
75899dfa77 Merge pull request #139 from guidograzioli/128_hostname_strict
keycloak_quarkus: add hostname-strict parameter
2023-12-05 12:44:02 +01:00
Guido Grazioli
593c4df861 keycloak_quarkus: add hostname-strict parameter 2023-12-05 10:48:48 +01:00
Guido Grazioli
4a72e3818c Merge pull request #138 from guidograzioli/fix_keycloak_23_booleans
Update template to lowercase booleans
2023-12-05 10:39:38 +01:00
Guido Grazioli
72ca9f5dfa switch pull_req_target to pull_req 2023-12-05 10:26:20 +01:00
Guido Grazioli
842e61c43e Update template to lowercase booleans 2023-12-05 10:13:12 +01:00
Guido Grazioli
1728b20cd3 Merge pull request #133 from Footur/update-keycloak
Update Keycloak to version 23.0.1
2023-12-01 14:11:04 +01:00
Footur
c01ffed113 Merge branch 'ansible-middleware:main' into update-keycloak 2023-12-01 14:02:45 +01:00
Guido Grazioli
fea7ae0c6f Merge pull request #134 from guidograzioli/linter_yaml_2
Linter yaml 2
2023-12-01 12:42:10 +01:00
Guido Grazioli
94530640c1 update wf 2023-12-01 12:37:20 +01:00
Guido Grazioli
d6f020ab44 linter fixes 2023-12-01 12:36:20 +01:00
Footur
55c02d7fc5 Update Keycloak to version 23.0.1 2023-12-01 10:34:04 +01:00
Guido Grazioli
5e8e8c67e8 Merge pull request #132 from saadsb20/patch-1
Add prefix check for keycloak_quarkus_http_relative_path
2023-11-30 12:52:18 +01:00
Saâd Bouryaln
88935abb62 Validate relative path
validate the relative path ... must begin with /
2023-11-30 12:26:22 +01:00
Saâd Bouryaln
3a1d9099a7 reverte change 2023-11-30 12:01:49 +01:00
Saâd Bouryaln
a439ccab5e fix health_url 2023-11-29 15:36:00 +01:00
ansible-middleware-core
e086ee8d29 Bump version to 2.0.1 2023-11-20 17:10:52 +00:00
ansible-middleware-core
2841c7a951 Update changelog for release 2.0.0
Signed-off-by: ansible-middleware-core <ansible-middleware-core@redhat.com>
2023-11-20 17:10:43 +00:00
Guido Grazioli
d947e85745 Merge pull request #129 from JMuff22/patch-1
Update admin password variable in keycloak_quarkus.yml
2023-11-17 16:55:35 +01:00
Jake Muff
143084d726 Update admin password variable in keycloak_quarkus.yml 2023-11-16 10:19:47 +02:00
Guido Grazioli
23bda1b4c5 Merge pull request #127 from RanabirChakraborty/AMWSUP-17
AMWSUP-17 keycloak Ansible Hub documentation link broken
2023-11-13 18:27:55 +01:00
Guido Grazioli
efc3e547fe ci: https_revproxy molecule verify step 2023-11-13 18:24:06 +01:00
Guido Grazioli
8af5d6e556 ci: https_revproxy molecule verify step 2023-11-13 18:10:40 +01:00
Guido Grazioli
a0f6a4931f ci: https_revproxy molecule verify step 2023-11-13 16:47:03 +01:00
Guido Grazioli
49c5071733 ci: fix envvars 2023-11-13 16:38:11 +01:00
Ranabir Chakraborty
7a1eeec6b6 AMWSUP-17 keycloak Ansible Hub documentation link broken 2023-11-13 18:18:52 +05:30
Guido Grazioli
69bd5b6ca8 Merge pull request #119 from guidograzioli/min_ansible_version
Update minimum ansible-core version > 2.14
2023-11-13 11:37:53 +01:00
Guido Grazioli
cee02cfd36 Merge pull request #116 from Footur/keystore
[keycloak_quarkus] Enable config of a key store and trust store
2023-11-13 11:37:36 +01:00
Guido Grazioli
ea086e8a62 ci: add missing header to molecule test 2023-11-13 11:37:18 +01:00
Guido Grazioli
24787e4607 Merge pull request #115 from gionn/114-add-more-configs
Add support for more http-related configs
2023-11-13 11:36:50 +01:00
Giovanni Toraldo
0e510c093a Set default keycloak_quarkus_http_relative_path as per upstream docs 2023-11-13 10:07:01 +01:00
Giovanni Toraldo
880d70ffb9 enable https_revproxy test 2023-11-07 10:21:05 +01:00
Giovanni Toraldo
c8f968a587 cleanup vars 2023-11-07 10:20:01 +01:00
Giovanni Toraldo
8eb5185287 use relative path to build health url 2023-11-07 10:20:01 +01:00
Giovanni Toraldo
316cde4759 Add support for more http-related configs
* keycloak_quarkus_http_relative_path var now populate http-relative-path config [breaking change]
* http-relative-path defaults to / [breaking change]
* enable configuration of hostname-url and hostname-admin-url
2023-11-07 10:20:01 +01:00
Guido Grazioli
92639e40cb Merge pull request #124 from jacobdotcosta/issue-57
feat: jboss port offset configuration
2023-11-06 16:03:02 +01:00
A.C
027ac1a78e Merge branch 'main' into issue-57 2023-11-06 15:10:05 +01:00
Antonio Costa
5543217c6a rebase for changes made in PR 120 2023-11-06 15:02:28 +01:00
Guido Grazioli
61730b981b ddisable new test 2023-11-06 15:02:28 +01:00
Guido Grazioli
03175e283b molecule test for keycloakx with proxy 2023-11-06 15:02:28 +01:00
Footur
62e5380d38 Update Keycloak to version 22.0.5 2023-11-06 15:02:28 +01:00
Antonio Costa
a538828f0d feat: add a destination variable for the log link
docs: argument specs for the keycloak_quarkus_log_target

docs: added parameter to the roles README

fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target
2023-11-06 15:02:25 +01:00
Guido Grazioli
12147b4769 linter 2023-11-06 15:01:39 +01:00
Guido Grazioli
cad87557d6 Merge pull request #121 from guidograzioli/quarkus_rev_proxy_test
internal: molecule test for keycloakx with proxy
2023-11-03 11:16:10 +01:00
Guido Grazioli
363c5d9f9e ddisable new test 2023-11-03 10:58:25 +01:00
Guido Grazioli
19a2013fa8 Merge pull request #122 from Footur/update-keycloak
Update Keycloak to version 22.0.5
2023-11-03 10:56:18 +01:00
Guido Grazioli
b819c98ab3 Merge pull request #120 from jacobdotcosta/issue-79
feat: add a destination variable for the log link
2023-11-03 10:55:21 +01:00
Antonio Costa
9ddd6d7d5e feat: jboss port offset configuration 2023-10-30 09:27:30 +01:00
Footur
6f26fa3da4 Update Keycloak to version 22.0.5 2023-10-27 15:32:15 +02:00
Antonio Costa
6970236201 feat: add a destination variable for the log link
docs: argument specs for the keycloak_quarkus_log_target

docs: added parameter to the roles README

fix: role variable is keycloak_log_target and not keycloak_quarkus_log_target
2023-10-26 09:18:07 +02:00
Guido Grazioli
e5f0a3efe1 molecule test for keycloakx with proxy 2023-10-25 18:51:49 +02:00
Guido Grazioli
41c1306602 linter 2023-10-25 18:20:03 +02:00
Guido Grazioli
c67b301f97 Merge pull request #118 from gionn/fixup-molecule-hera
Do not require hosts edit for running quarkus molecule suite locally
2023-10-16 16:41:07 +02:00
Giovanni Toraldo
d945c51172 apply review suggestions 2023-10-16 15:52:04 +02:00
Guido Grazioli
d6c57a17a8 Merge pull request #117 from Footur/update-keycloak
Update Keycloak to version 22.0.4
2023-10-16 15:29:29 +02:00
Guido Grazioli
bf1cb3695e Update minimum ansible-core version > 2.14 2023-10-16 15:27:24 +02:00
Giovanni Toraldo
307eee771f Do not require hosts edit for running quarkus molecule suite 2023-10-16 12:59:44 +02:00
Footur
e842462a22 Enable config of a key store and trust store 2023-10-13 16:30:58 +02:00
Footur
0f7bbc7ef9 Update Keycloak to version 22.0.4 2023-10-13 16:24:46 +02:00
ansible-middleware-core
00e6cb6b0e Bump version to 1.3.1 2023-09-25 10:57:25 +00:00
81 changed files with 1264 additions and 395 deletions

View File

@@ -6,7 +6,7 @@ on:
- main
pull_request:
schedule:
- cron: '0 6 * * *'
- cron: '15 6 * * *'
jobs:
ci:
@@ -15,4 +15,4 @@ jobs:
with:
fqcn: 'middleware_automation/keycloak'
molecule_tests: >-
[ "default", "quarkus", "overridexml", "quarkus-devmode" ]
[ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ]

View File

@@ -1,11 +1,82 @@
============================================
middleware_automation.keycloak Release Notes
============================================
=============================================
middleware\_automation.keycloak Release Notes
=============================================
.. contents:: Topics
This changelog describes changes after version 0.2.6.
v2.1.0
======
Major Changes
-------------
- Implement infinispan TCPPING discovery protocol `#159 <https://github.com/ansible-middleware/keycloak/pull/159>`_
Minor Changes
-------------
- Set enable-recovery when xa transactions are enabled `#167 <https://github.com/ansible-middleware/keycloak/pull/167>`_
- keycloak_quarkus: Allow configuring log rotate options in quarkus configuration `#161 <https://github.com/ansible-middleware/keycloak/pull/161>`_
- keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 <https://github.com/ansible-middleware/keycloak/pull/163>`_
Breaking Changes / Porting Guide
--------------------------------
- keycloak_quarkus: renamed infinispan host list configuration `#157 <https://github.com/ansible-middleware/keycloak/pull/157>`_
Bugfixes
--------
- keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 <https://github.com/ansible-middleware/keycloak/pull/171>`_
v2.0.2
======
Minor Changes
-------------
- keycloak_quarkus: Add support for sqlserver jdbc driver `#148 <https://github.com/ansible-middleware/keycloak/pull/148>`_
- keycloak_quarkus: allow configuration of ``hostname-strict-backchannel`` `#152 <https://github.com/ansible-middleware/keycloak/pull/152>`_
- keycloak_quarkus: systemd restart behavior `#145 <https://github.com/ansible-middleware/keycloak/pull/145>`_
Bugfixes
--------
- keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 <https://github.com/ansible-middleware/keycloak/pull/154>`_
- keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 <https://github.com/ansible-middleware/keycloak/pull/150>`_
v2.0.1
======
Minor Changes
-------------
- keycloak_quarkus: add hostname-strict parameter `#139 <https://github.com/ansible-middleware/keycloak/pull/139>`_
- keycloak_quarkus: update to version 23.0.1 `#133 <https://github.com/ansible-middleware/keycloak/pull/133>`_
Bugfixes
--------
- keycloak_quarkus: template requires lowercase boolean values `#138 <https://github.com/ansible-middleware/keycloak/pull/138>`_
v2.0.0
======
Minor Changes
-------------
- Add new parameter for port offset configuration `#124 <https://github.com/ansible-middleware/keycloak/pull/124>`_
- Update Keycloak to version 22.0.5 `#122 <https://github.com/ansible-middleware/keycloak/pull/122>`_
Breaking Changes / Porting Guide
--------------------------------
- Add support for more http-related configs `#115 <https://github.com/ansible-middleware/keycloak/pull/115>`_
- Update minimum ansible-core version > 2.14 `#119 <https://github.com/ansible-middleware/keycloak/pull/119>`_
- keycloak_quarkus: enable config of key store and trust store `#116 <https://github.com/ansible-middleware/keycloak/pull/116>`_
v1.3.0
======
@@ -223,7 +294,6 @@ Release Summary
Minor enhancements, bug and documentation fixes.
Major Changes
-------------
@@ -241,4 +311,3 @@ Release Summary
---------------
This is the first stable release of the ``middleware_automation.keycloak`` collection.

View File

@@ -3,15 +3,15 @@
<!--start build_status -->
[![Build Status](https://github.com/ansible-middleware/keycloak/workflows/CI/badge.svg?branch=main)](https://github.com/ansible-middleware/keycloak/actions/workflows/ci.yml)
> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.**
> **_NOTE:_ If you are Red Hat customer, install `redhat.sso` (for Red Hat Single Sign-On) or `redhat.rhbk` (for Red Hat Build of Keycloak) from [Automation Hub](https://console.redhat.com/ansible/ansible-dashboard) as the certified version of this collection.**
<!--end build_status -->
Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on).
Collection to install and configure [Keycloak](https://www.keycloak.org/) or [Red Hat Single Sign-On](https://access.redhat.com/products/red-hat-single-sign-on) / [Red Hat Build of Keycloak](https://access.redhat.com/products/red-hat-build-of-keycloak).
<!--start requires_ansible-->
## Ansible version compatibility
This collection has been tested against following Ansible versions: **>=2.9.10**.
This collection has been tested against following Ansible versions: **>=2.14.0**.
Plugins and modules within a collection may be tested with only specific Ansible versions. A collection may contain metadata that identifies these versions.
<!--end requires_ansible-->
@@ -44,33 +44,34 @@ A requirement file is provided to install:
pip install -r requirements.txt
<!--start roles_paths -->
### Included roles
* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service.
* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service (keycloak <= 19.0).
* [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service.
* [`keycloak_quarkus`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_quarkus/README.md): role for installing the quarkus variant of keycloak (>= 17.0.0).
<!--end roles_paths -->
## Usage
### Install Playbook
* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs based on the defined variables (using most defaults).
<!--start rhbk_playbook -->
* [`playbooks/keycloak.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak.yml) installs keycloak legacy based on the defined variables (using most defaults).
* [`playbooks/keycloak_quarkus.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_quarkus.yml) installs keycloak >= 17 based on the defined variables (using most defaults).
Both playbooks include the `keycloak` role, with different settings, as described in the following sections.
For full service configuration details, refer to the [keycloak role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md).
<!--end rhbk_playbook -->
#### Install from controller node (offline)
Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `True`, allows to skip
Making the keycloak zip archive available to the playbook working directory, and setting `keycloak_offline_install` to `true`, allows to skip
the download tasks. The local path for the archive does match the downloaded archive path, so that it is also used as a cache when multiple hosts are provisioned in a cluster.
```yaml
keycloak_offline_install: True
keycloak_offline_install: true
```
@@ -85,7 +86,7 @@ It is possible to perform downloads from alternate sources, using the `keycloak_
### Example installation command
Execute the following command from the source root directory
Execute the following command from the source root directory
```
ansible-playbook -i <ansible_hosts> -e @rhn-creds.yml playbooks/keycloak.yml -e keycloak_admin_password=<changeme>
@@ -106,9 +107,9 @@ Note: when deploying clustered configurations, all hosts belonging to the cluste
### Config Playbook
<!--start rhbk_realm_playbook -->
[`playbooks/keycloak_realm.yml`](https://github.com/ansible-middleware/keycloak/blob/main/playbooks/keycloak_realm.yml) creates or updates provided realm, user federation(s), client(s), client role(s) and client user(s).
<!--end rhbk_realm_playbook -->
### Example configuration command
@@ -126,9 +127,9 @@ ansible-playbook -i <ansible_hosts> playbooks/keycloak_realm.yml -e keycloak_adm
[keycloak]
localhost ansible_connection=local
```
<!--start rhbk_realm_readme -->
For full configuration details, refer to the [keycloak_realm role README](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md).
<!--end rhbk_realm_readme -->
<!--start support -->
<!--end support -->
@@ -137,6 +138,7 @@ For full configuration details, refer to the [keycloak_realm role README](https:
## License
Apache License v2.0 or later
<!--start license -->
See [LICENSE](LICENSE) to view the full text.
<!--end license -->

View File

@@ -315,3 +315,107 @@ releases:
- 112.yaml
- 113.yaml
release_date: '2023-09-25'
2.0.0:
changes:
breaking_changes:
- 'Add support for more http-related configs `#115 <https://github.com/ansible-middleware/keycloak/pull/115>`_
'
- 'Update minimum ansible-core version > 2.14 `#119 <https://github.com/ansible-middleware/keycloak/pull/119>`_
'
- 'keycloak_quarkus: enable config of key store and trust store `#116 <https://github.com/ansible-middleware/keycloak/pull/116>`_
'
minor_changes:
- 'Add new parameter for port offset configuration `#124 <https://github.com/ansible-middleware/keycloak/pull/124>`_
'
- 'Update Keycloak to version 22.0.5 `#122 <https://github.com/ansible-middleware/keycloak/pull/122>`_
'
fragments:
- 115.yaml
- 116.yaml
- 119.yaml
- 122.yaml
- 124.yaml
release_date: '2023-11-20'
2.0.1:
changes:
bugfixes:
- 'keycloak_quarkus: template requires lowercase boolean values `#138 <https://github.com/ansible-middleware/keycloak/pull/138>`_
'
minor_changes:
- 'keycloak_quarkus: add hostname-strict parameter `#139 <https://github.com/ansible-middleware/keycloak/pull/139>`_
'
- 'keycloak_quarkus: update to version 23.0.1 `#133 <https://github.com/ansible-middleware/keycloak/pull/133>`_
'
fragments:
- 133.yaml
- 138.yaml
- 139.yaml
release_date: '2023-12-07'
2.0.2:
changes:
bugfixes:
- 'keycloak_quarkus: Use ``keycloak_quarkus_java_opts`` `#154 <https://github.com/ansible-middleware/keycloak/pull/154>`_
'
- 'keycloak_quarkus: allow ports <1024 (e.g. :443) in systemd unit `#150 <https://github.com/ansible-middleware/keycloak/pull/150>`_
'
minor_changes:
- 'keycloak_quarkus: Add support for sqlserver jdbc driver `#148 <https://github.com/ansible-middleware/keycloak/pull/148>`_
'
- 'keycloak_quarkus: allow configuration of ``hostname-strict-backchannel``
`#152 <https://github.com/ansible-middleware/keycloak/pull/152>`_
'
- 'keycloak_quarkus: systemd restart behavior `#145 <https://github.com/ansible-middleware/keycloak/pull/145>`_
'
fragments:
- 145.yaml
- 148.yaml
- 150.yaml
- 152.yaml
- 154.yaml
release_date: '2024-01-17'
2.1.0:
changes:
breaking_changes:
- 'keycloak_quarkus: renamed infinispan host list configuration `#157 <https://github.com/ansible-middleware/keycloak/pull/157>`_
'
bugfixes:
- 'keycloak_quarkus: fix custom JAVA_HOME parameter name `#171 <https://github.com/ansible-middleware/keycloak/pull/171>`_
'
major_changes:
- 'Implement infinispan TCPPING discovery protocol `#159 <https://github.com/ansible-middleware/keycloak/pull/159>`_
'
minor_changes:
- 'Set enable-recovery when xa transactions are enabled `#167 <https://github.com/ansible-middleware/keycloak/pull/167>`_
'
- 'keycloak_quarkus: Allow configuring log rotate options in quarkus configuration
`#161 <https://github.com/ansible-middleware/keycloak/pull/161>`_
'
- 'keycloak_quarkus: ``sticky-session`` for infinispan routes `#163 <https://github.com/ansible-middleware/keycloak/pull/163>`_
'
fragments:
- 157.yaml
- 159.yaml
- 161.yaml
- 163.yaml
- 167.yaml
- 171.yaml
release_date: '2024-02-28'

View File

@@ -1,12 +1,13 @@
---
namespace: middleware_automation
name: keycloak
version: "1.3.0"
version: "2.1.1"
readme: README.md
authors:
- Romain Pelisse <rpelisse@redhat.com>
- Guido Grazioli <ggraziol@redhat.com>
- Pavan Kumar Motaparthi <pmotapar@redhat.com>
- Helmut Wolf <hwo@world-direct.at>
description: Install and configure a keycloak, or Red Hat Single Sign-on, service.
license_file: "LICENSE"
tags:

View File

@@ -1,2 +1,2 @@
---
requires_ansible: ">=2.9.10"
requires_ansible: ">=2.14.0"

View File

@@ -10,6 +10,8 @@
port: 16667
- host: myhost2
port: 16668
keycloak_jboss_port_offset: 10
keycloak_log_target: /tmp/keycloak
roles:
- role: keycloak
tasks:

View File

@@ -1,16 +1,9 @@
---
- name: Prepare
hosts: all
tasks:
- name: Install sudo
ansible.builtin.yum:
name:
- sudo
- java-1.8.0-openjdk
state: present
- name: Prepare
hosts: all
gather_facts: yes
vars:
sudo_pkg_name: sudo
tasks:
- name: "Run preparation common to all scenario"
ansible.builtin.include_tasks: ../prepare.yml
@@ -18,3 +11,12 @@
assets:
- "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip"
- "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip"
- name: Install JDK8
become: yes
ansible.builtin.yum:
name:
- java-1.8.0-openjdk
state: present

View File

@@ -4,8 +4,9 @@
vars:
keycloak_admin_password: "remembertochangeme"
keycloak_jvm_package: java-11-openjdk-headless
keycloak_uri: http://localhost:8080
keycloak_management_port: http://localhost:9990
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:
@@ -55,3 +56,34 @@
ansible.builtin.assert:
that:
- (keycloak_query_clients.json | selectattr('clientId','equalto','TestClient') | first)["attributes"]["post.logout.redirect.uris"] == '/public/logout'
- name: "Privilege escalation as some files/folders may requires it"
become: yes
block:
- name: Check log folder
ansible.builtin.stat:
path: "/tmp/keycloak"
register: keycloak_log_folder
- name: Check that keycloak log folder exists and is a link
ansible.builtin.assert:
that:
- keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk
- name: Check log file
ansible.builtin.stat:
path: "/tmp/keycloak/server.log"
register: keycloak_log_file
- name: Check if keycloak file exists
ansible.builtin.assert:
that:
- keycloak_log_file.stat.exists
- not keycloak_log_file.stat.isdir
- name: Check default log folder
ansible.builtin.stat:
path: "/var/log/keycloak"
register: keycloak_default_log_folder
failed_when: false
- name: Check that default keycloak log folder doesn't exist
ansible.builtin.assert:
that:
- not keycloak_default_log_folder.stat.exists

View File

@@ -0,0 +1,16 @@
---
- name: Converge
hosts: all
vars:
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm
keycloak_quarkus_host: instance
keycloak_quarkus_log: file
keycloak_quarkus_http_enabled: True
keycloak_quarkus_http_port: 8080
keycloak_quarkus_proxy_mode: edge
keycloak_quarkus_http_relative_path: /
keycloak_quarkus_frontend_url: https://proxy/
roles:
- role: keycloak_quarkus

View File

@@ -0,0 +1,57 @@
---
driver:
name: docker
platforms:
- name: instance
image: registry.access.redhat.com/ubi8/ubi-init:latest
pre_build_image: true
privileged: true
command: "/usr/sbin/init"
networks:
- name: keycloak
port_bindings:
- "8080/tcp"
published_ports:
- 0.0.0.0:8080:8080/tcp
- name: proxy
image: registry.access.redhat.com/ubi8/ubi-init:latest
pre_build_image: true
privileged: true
command: "/usr/sbin/init"
networks:
- name: keycloak
port_bindings:
- "443/tcp"
published_ports:
- 0.0.0.0:443:443/tcp
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
ssh_connection:
pipelining: false
playbooks:
prepare: prepare.yml
converge: converge.yml
verify: verify.yml
inventory:
host_vars:
localhost:
ansible_python_interpreter: "{{ ansible_playbook_python }}"
env:
ANSIBLE_FORCE_COLOR: "true"
verifier:
name: ansible
scenario:
test_sequence:
- cleanup
- destroy
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy

View File

@@ -0,0 +1,49 @@
---
- name: Prepare
hosts: all
tasks:
- name: Install sudo
ansible.builtin.dnf:
name: sudo
state: present
- name: "Display hera_home if defined."
ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}"
- name: Prepare proxy
hosts: proxy
vars:
nginx_proxy: |
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://instance:8080;
}
roles:
- elan.simple_nginx_reverse_proxy
pre_tasks:
- 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=proxy'
delegate_to: localhost
changed_when: false
- name: Make certificate directory
ansible.builtin.file:
path: /etc/nginx/tls
state: directory
mode: 0755
- name: Copy certificates
ansible.builtin.copy:
src: "{{ item.name }}"
dest: "{{ item.dest }}"
mode: 0444
become: true
loop:
- { name: 'cert.pem', dest: '/etc/nginx/tls/certificate.crt' }
- { name: 'key.pem', dest: '/etc/nginx/tls/certificate.key' }
- name: Update CA trust
ansible.builtin.command: update-ca-trust
changed_when: false
become: true

View File

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

View File

@@ -0,0 +1,28 @@
---
- name: Verify
hosts: instance
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.uri:
url: http://localhost:8080/realms/master/.well-known/openid-configuration
validate_certs: false
headers:
Host: proxy
register: openid_config
changed_when: False
- name: Verify endpoint URLs
ansible.builtin.assert:
that:
- openid_config.json['issuer'] == 'https://proxy/realms/master'
- openid_config.json['authorization_endpoint'] == 'https://proxy/realms/master/protocol/openid-connect/auth'

View File

@@ -1,6 +1,9 @@
---
- name: Prepare
hosts: all
gather_facts: yes
vars:
sudo_pkg_name: sudo
tasks:
- name: "Run preparation common to all scenario"
ansible.builtin.include_tasks: ../prepare.yml

View File

@@ -3,9 +3,27 @@
ansible.builtin.debug:
msg: "Ansible version is {{ ansible_version.full }}"
- name: Install sudo
- name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)."
ansible.builtin.yum:
name:
name: "{{ sudo_pkg_name }}"
when:
- ansible_user_id == 'root'
- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto
- name: "Check if {{ sudo_pkg_name }} is installed."
ansible.builtin.assert:
that:
- sudo_pkg_name in ansible_facts.packages
- name: Install sudo
become: yes
ansible.builtin.yum:
name:
- sudo
- iproute
state: present
@@ -14,22 +32,21 @@
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
- name: "Download artefacts only if assets_server is set"
when:
- assets_server is defined
- assets_server | length > 0
block:
- name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact:
sso_offline_install: True
- name: "Download and deploy zips from {{ assets_server }}"
ansible.builtin.get_url:
url: "{{ asset }}"
dest: "{{ lookup('env', 'PWD') }}"
validate_certs: no
delegate_to: localhost
loop: "{{ assets }}"
loop_control:
loop_var: asset
when:
- assets_server is defined
- assets_server | length > 0
- name: "Download and deploy zips from {{ assets_server }}"
ansible.builtin.get_url:
url: "{{ asset }}"
dest: "{{ lookup('env', 'PWD') }}"
validate_certs: no
delegate_to: localhost
loop: "{{ assets }}"
loop_control:
loop_var: asset

View File

@@ -5,11 +5,11 @@
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm
keycloak_quarkus_http_relative_path: ''
keycloak_quarkus_log: file
keycloak_quarkus_frontend_url: 'http://localhost:8080/'
keycloak_quarkus_start_dev: True
keycloak_quarkus_proxy_mode: none
keycloak_quarkus_java_home: /opt/openjdk/
roles:
- role: keycloak_quarkus
- role: keycloak_realm

View File

@@ -1,12 +1,22 @@
---
- name: Prepare
hosts: all
become: yes
tasks:
- name: Install sudo
ansible.builtin.yum:
name: sudo
name:
- sudo
- java-17-openjdk-headless
state: present
- name: Link default logs directory
ansible.builtin.file:
state: link
src: /usr/lib/jvm/jre-17-openjdk
dest: /opt/openjdk
force: true
- name: "Display hera_home if defined."
ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}"

View File

@@ -11,6 +11,14 @@
- ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled"
- name: Verify we are running on requested JAVA_HOME # noqa blocked_modules command-instead-of-module
ansible.builtin.shell: |
set -o pipefail
ps -ef | grep '/opt/openjdk' | grep -v grep
args:
executable: /bin/bash
changed_when: False
- name: Set internal envvar
ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}"

View File

@@ -6,11 +6,11 @@
keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm
keycloak_quarkus_host: instance
keycloak_quarkus_http_relative_path: ''
keycloak_quarkus_log: file
keycloak_quarkus_https_enabled: True
keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/key.pem"
keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/cert.pem"
keycloak_quarkus_https_key_file_enabled: True
keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem"
keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem"
keycloak_quarkus_log_target: /tmp/keycloak
roles:
- role: keycloak_quarkus
- role: keycloak_realm

View File

@@ -3,6 +3,7 @@
hosts: all
tasks:
- name: Install sudo
become: yes
ansible.builtin.yum:
name: sudo
state: present
@@ -16,27 +17,17 @@
delegate_to: localhost
changed_when: False
- name: Set /etc/hosts
ansible.builtin.lineinfile:
dest: /etc/hosts
line: "127.0.0.1 instance"
state: present
delegate_to: localhost
become: yes
when:
- hera_home is defined
- hera_home | length == 0
- name: Create conf directory # risky-file-permissions in test user account does not exist yet
ansible.builtin.file:
state: directory
path: /opt/keycloak/keycloak-22.0.3/conf/
path: "/opt/keycloak/certs/"
mode: 0755
- name: Copy certificates
become: yes
ansible.builtin.copy:
src: "{{ item }}"
dest: "/opt/keycloak/keycloak-22.0.3/conf/{{ item }}"
dest: "/opt/keycloak/certs/{{ item }}"
mode: 0444
loop:
- cert.pem

View File

@@ -16,11 +16,14 @@
hera_home: "{{ lookup('env', 'HERA_HOME') }}"
- name: Verify openid config
when:
- hera_home is defined
- hera_home | length == 0
block:
- name: Fetch openID config # noqa blocked_modules command-instead-of-module
ansible.builtin.shell: |
set -o pipefail
curl https://instance:8443/realms/master/.well-known/openid-configuration -k | jq .
curl -H 'Host: instance' https://localhost:8443/realms/master/.well-known/openid-configuration -k | jq .
args:
executable: /bin/bash
delegate_to: localhost
@@ -34,6 +37,37 @@
- (openid_config.stdout | from_json)['authorization_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/auth'
- (openid_config.stdout | from_json)['token_endpoint'] == 'https://instance/realms/master/protocol/openid-connect/token'
delegate_to: localhost
when:
- hera_home is defined
- hera_home | length == 0
- name: Check log folder
ansible.builtin.stat:
path: "/tmp/keycloak"
register: keycloak_log_folder
- name: Check that keycloak log folder exists and is a link
ansible.builtin.assert:
that:
- keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk
- name: Check log file
ansible.builtin.stat:
path: "/tmp/keycloak/keycloak.log"
register: keycloak_log_file
- name: Check if keycloak file exists
ansible.builtin.assert:
that:
- keycloak_log_file.stat.exists
- not keycloak_log_file.stat.isdir
- name: Check default log folder
ansible.builtin.stat:
path: "/var/log/keycloak"
register: keycloak_default_log_folder
failed_when: false
- name: Check that default keycloak log folder doesn't exist
ansible.builtin.assert:
that:
- not keycloak_default_log_folder.stat.exists

View File

@@ -1,8 +1,11 @@
---
collections:
- name: middleware_automation.common
- name: middleware_automation.jbcs
- name: community.general
- name: ansible.posix
- name: community.docker
version: ">=1.9.1"
roles:
- name: elan.simple_nginx_reverse_proxy

View File

@@ -55,14 +55,14 @@
- TestClient1Admin
- TestClient1User
realm: "{{ keycloak_realm }}"
public_client: True
public_client: true
web_origins:
- http://testclient1origin/application
- http://testclient1origin/other
users:
- username: TestUser
password: password
client_roles:
- client: TestClient1
role: TestClient1User
realm: "{{ keycloak_realm }}"
- username: TestUser
password: password
client_roles:
- client: TestClient1
role: TestClient1User
realm: "{{ keycloak_realm }}"

View File

@@ -2,13 +2,10 @@
- name: Playbook for Keycloak X Hosts with HTTPS enabled
hosts: all
vars:
keycloak_admin_password: "remembertochangeme"
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_quarkus_host: localhost
keycloak_quarkus_port: 8443
keycloak_quarkus_http_relative_path: ''
keycloak_quarkus_log: file
keycloak_quarkus_https_enabled: True
keycloak_quarkus_key_file: conf/key.pem
keycloak_quarkus_cert_file: conf/cert.pem
keycloak_quarkus_proxy_mode: none
roles:
- middleware_automation.keycloak.keycloak_quarkus

View File

@@ -5,7 +5,6 @@
keycloak_admin_password: "remembertochangeme"
keycloak_quarkus_host: localhost
keycloak_quarkus_port: 8080
keycloak_quarkus_http_relative_path: ''
keycloak_quarkus_log: file
keycloak_quarkus_start_dev: true
keycloak_quarkus_proxy_mode: none

View File

@@ -10,17 +10,17 @@
- TestClient1Admin
- TestClient1User
realm: TestRealm
public_client: True
public_client: true
web_origins:
- http://testclient1origin/application
- http://testclient1origin/other
users:
- username: TestUser
password: password
client_roles:
- client: TestClient1
role: TestClient1User
realm: TestRealm
- username: TestUser
password: password
client_roles:
- client: TestClient1
role: TestClient1User
realm: TestRealm
roles:
- role: middleware_automation.keycloak.keycloak_realm
keycloak_realm: TestRealm

View File

@@ -3,6 +3,6 @@
hosts: sso
vars:
keycloak_admin_password: "remembertochangeme"
sso_enable: True
sso_enable: true
roles:
- middleware_automation.keycloak.keycloak

View File

@@ -568,7 +568,6 @@ EXAMPLES = '''
realm: my-realm
name: my-federation
state: absent
'''
RETURN = '''

View File

@@ -39,7 +39,7 @@ Versions
Patching
--------
When variable `keycloak_rhsso_apply_patches` is `True` (default: `False`), the role will automatically apply the latest cumulative patch for the selected base version.
When variable `keycloak_rhsso_apply_patches` is `true` (default: `false`), the role will automatically apply the latest cumulative patch for the selected base version.
| RH-SSO VERSION | Release Date | RH-SSO LATEST CP | Notes |
|:---------------|:------------------|:-----------------|:----------------|
@@ -55,7 +55,7 @@ Role Defaults
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if keycloak_db_enabled else `TCPPING` |
|`keycloak_ha_discovery`| Discovery protocol for HA cluster members | `JDBC_PING` if `keycloak_db_enabled` else `TCPPING` |
|`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` |
|`keycloak_remote_cache_enabled`| Enable remote cache store when in clustered ha configurations | `True` if `keycloak_ha_enabled` else `False` |
|`keycloak_admin_user`| Administration console user account | `admin` |
@@ -68,19 +68,19 @@ Role Defaults
|`keycloak_jgroups_port`| jgroups cluster tcp port | `7600` |
|`keycloak_management_http_port`| Management port | `9990` |
|`keycloak_management_https_port`| TLS management port | `9993` |
|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` |
|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `true` |
|`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` |
|`keycloak_service_user`| posix account username | `keycloak` |
|`keycloak_service_group`| posix account group | `keycloak` |
|`keycloak_service_restart_always`| systemd restart always behavior activation | `False`
|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False`
|`keycloak_service_restart_always`| systemd restart always behavior activation | `False` |
|`keycloak_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` |
|`keycloak_service_startlimitintervalsec`| systemd StartLimitIntervalSec | `300` |
|`keycloak_service_startlimitburst`| systemd StartLimitBurst | `5` |
|`keycloak_service_restartsec`| systemd RestartSec | `10s` |
|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak/keycloak.pid` |
|`keycloak_features` | List of `name`/`status` pairs of features (also known as profiles on RH-SSO) to `enable` or `disable`, example: `[ { name: 'docker', status: 'enabled' } ]` | `[]`
|`keycloak_jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-headless` |
|`keycloak_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path | `None` |
|`keycloak_java_home`| `JAVA_HOME` of installed JRE, leave empty for using RPM path at `keycloak_jvm_package` | `None` |
|`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
@@ -88,12 +88,12 @@ Role Defaults
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_offline_install` | perform an offline install | `False`|
|`keycloak_offline_install` | perform an offline install | `false`|
|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/<version>/<archive>`|
|`keycloak_version`| keycloak.org package version | `18.0.2` |
|`keycloak_dest`| Installation root path | `/opt/keycloak` |
|`keycloak_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}` |
|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
|`keycloak_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `false` |
* Miscellaneous configuration
@@ -104,20 +104,21 @@ Role Defaults
|`keycloak_download_url_9x` | Download URL for keycloak (deprecated) | `https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}` |
|`keycloak_installdir` | Installation path | `{{ keycloak_dest }}/keycloak-{{ keycloak_version }}` |
|`keycloak_jboss_home` | Installation work directory | `{{ keycloak_rhsso_installdir }}` |
|`keycloak_jboss_port_offset` | Port offset for the JBoss socket binding | `0` |
|`keycloak_config_dir` | Path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration` |
|`keycloak_config_path_to_standalone_xml` | Custom path for configuration | `{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}` |
|`keycloak_config_override_template` | Path to custom template for standalone.xml configuration | `''` |
|`keycloak_auth_realm` | Name for rest authentication realm | `master` |
|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` |
|`keycloak_force_install` | Remove pre-existing versions of service | `False` |
|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port }}` |
|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port }}` |
|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `False` |
|`keycloak_db_background_validation` | Enable background validation of database connection | `False` |
|`keycloak_force_install` | Remove pre-existing versions of service | `false` |
|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}` |
|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}` |
|`keycloak_frontend_url_force` | Force backend requests to use the frontend URL | `false` |
|`keycloak_db_background_validation` | Enable background validation of database connection | `false` |
|`keycloak_db_background_validation_millis`| How frequenly the connection pool is validated in the background | `10000` if background validation enabled |
|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `False` |
|`keycloak_db_background_validate_on_match` | Enable validate on match for database connections | `false` |
|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` |
|`keycloak_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` |
Role Variables
@@ -131,7 +132,7 @@ The following are a set of _required_ variables for the role:
|`keycloak_frontend_url` | frontend URL for keycloak endpoint | `http://localhost:8080/auth/` |
The following parameters are _required_ only when `keycloak_ha_enabled` is True:
The following parameters are _required_ only when `keycloak_ha_enabled` is true:
| Variable | Description | Default |
|:---------|:------------|:--------|
@@ -149,7 +150,7 @@ The following parameters are _required_ only when `keycloak_ha_enabled` is True:
|`keycloak_infinispan_trust_store_password`| Password for opening truststore | `changeit` |
The following parameters are _required_ only when `keycloak_db_enabled` is True:
The following parameters are _required_ only when `keycloak_db_enabled` is true:
| Variable | Description | Default |
|:---------|:------------|:---------|
@@ -195,7 +196,7 @@ Example Playbook
name: keycloak
vars:
keycloak_admin_password: "remembertochangeme"
keycloak_offline_install: True
keycloak_offline_install: true
# This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip
```

View File

@@ -5,13 +5,14 @@ keycloak_archive: "keycloak-legacy-{{ keycloak_version }}.zip"
keycloak_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/{{ keycloak_archive }}"
keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_version }}/{{ keycloak_archive }}"
keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}"
keycloak_offline_install: False
keycloak_offline_install: false
### Install location and service settings
keycloak_jvm_package: java-1.8.0-openjdk-headless
keycloak_java_home:
keycloak_dest: /opt/keycloak
keycloak_jboss_home: "{{ keycloak_installdir }}"
keycloak_jboss_port_offset: 0
keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration"
keycloak_config_standalone_xml: "keycloak.xml"
keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}"
@@ -25,13 +26,13 @@ keycloak_service_name: keycloak
keycloak_service_desc: Keycloak
keycloak_service_start_delay: 10
keycloak_service_start_retries: 25
keycloak_service_restart_always: False
keycloak_service_restart_on_failure: False
keycloak_service_restart_always: false
keycloak_service_restart_on_failure: false
keycloak_service_startlimitintervalsec: "300"
keycloak_service_startlimitburst: "5"
keycloak_service_restartsec: "10s"
keycloak_configure_firewalld: False
keycloak_configure_firewalld: false
### administrator console password
keycloak_admin_password: ''
@@ -48,11 +49,11 @@ keycloak_management_port_bind_address: 127.0.0.1
keycloak_management_http_port: 9990
keycloak_management_https_port: 9993
keycloak_java_opts: "-Xms1024m -Xmx2048m"
keycloak_prefer_ipv4: True
keycloak_prefer_ipv4: true
keycloak_features: []
### Enable configuration for database backend, clustering and remote caches on infinispan
keycloak_ha_enabled: False
keycloak_ha_enabled: false
### Enable database configuration, must be enabled when HA is configured
keycloak_db_enabled: "{{ True if keycloak_ha_enabled else False }}"
### Discovery protocol for ha cluster members, valus [ 'JDBC_PING', 'TCPPING' ]
@@ -65,7 +66,7 @@ keycloak_admin_user: admin
keycloak_auth_realm: master
keycloak_auth_client: admin-cli
keycloak_force_install: False
keycloak_force_install: false
### mod_cluster reverse proxy list
keycloak_modcluster_enabled: "{{ True if keycloak_ha_enabled else False }}"
@@ -77,7 +78,7 @@ keycloak_modcluster_urls:
### keycloak frontend url
keycloak_frontend_url: http://localhost:8080/auth/
keycloak_frontend_url_force: False
keycloak_frontend_url_force: false
keycloak_admin_url:
### infinispan remote caches access (hotrod)
@@ -85,7 +86,7 @@ keycloak_infinispan_user: supervisor
keycloak_infinispan_pass: supervisor
keycloak_infinispan_url: localhost
keycloak_infinispan_sasl_mechanism: SCRAM-SHA-512
keycloak_infinispan_use_ssl: False
keycloak_infinispan_use_ssl: false
# if ssl is enabled, import ispn server certificate here
keycloak_infinispan_trust_store_path: /etc/pki/java/cacerts
keycloak_infinispan_trust_store_password: changeit
@@ -96,9 +97,9 @@ keycloak_jdbc_engine: postgres
keycloak_db_user: keycloak-user
keycloak_db_pass: keycloak-pass
## connection validation
keycloak_db_background_validation: False
keycloak_db_background_validation: false
keycloak_db_background_validation_millis: "{{ 10000 if keycloak_db_background_validation else 0 }}"
keycloak_db_background_validate_on_match: False
keycloak_db_background_validate_on_match: false
keycloak_jdbc_url: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].url }}"
keycloak_jdbc_driver_version: "{{ keycloak_default_jdbc[keycloak_jdbc_engine].version }}"
# override the variables above, following defaults show minimum supported versions
@@ -113,4 +114,7 @@ keycloak_default_jdbc:
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
version: 12.2.0
# role specific vars
keycloak_no_log: True
keycloak_no_log: true
### logging configuration
keycloak_log_target: /var/log/keycloak

View File

@@ -54,6 +54,10 @@ argument_specs:
default: "{{ keycloak_installdir }}"
description: "Installation work directory"
type: "str"
keycloak_jboss_port_offset:
default: 0
description: "Port offset for the JBoss socket binding"
type: "int"
keycloak_config_dir:
# line 26 of keycloak/defaults/main.yml
default: "{{ keycloak_jboss_home }}/standalone/configuration"
@@ -210,7 +214,7 @@ argument_specs:
description: "Frontend URL for keycloak endpoints when a reverse proxy is used"
type: "str"
keycloak_frontend_url_force:
default: False
default: false
description: "Force backend requests to use the frontend URL"
type: "bool"
keycloak_infinispan_user:
@@ -280,12 +284,12 @@ argument_specs:
type: "str"
keycloak_url:
# line 12 of keycloak/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
default: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}"
description: "URL for configuration rest calls"
type: "str"
keycloak_management_url:
# line 13 of keycloak/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}"
default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}"
description: "URL for management console rest calls"
type: "str"
keycloak_service_name:
@@ -333,7 +337,7 @@ argument_specs:
description: "Enable remote cache store when in clustered ha configurations"
type: "bool"
keycloak_db_background_validation:
default: False
default: false
description: "Enable background validation of database connection"
type: "bool"
keycloak_db_background_validation_millis:
@@ -341,21 +345,25 @@ argument_specs:
description: "How frequenly the connection pool is validated in the background"
type: 'int'
keycloak_db_background_validate_on_match:
default: False
default: false
description: "Enable validate on match for database connections"
type: "bool"
keycloak_db_valid_conn_sql:
required: False
required: false
description: "Override the default database connection validation query sql"
type: "str"
keycloak_admin_url:
required: False
required: false
description: "Override the default administration endpoint URL"
type: "str"
keycloak_jgroups_subnet:
required: False
required: false
description: "Override the subnet match for jgroups cluster formation; if not defined, it will be inferred from local machine route configuration"
type: "str"
keycloak_log_target:
default: '/var/log/keycloak'
type: "str"
description: "Set the destination of the keycloak log folder link"
downstream:
options:
sso_version:
@@ -375,15 +383,15 @@ argument_specs:
description: "Installation path for Red Hat SSO"
type: "str"
sso_apply_patches:
default: False
default: false
description: "Install Red Hat SSO most recent cumulative patch"
type: "bool"
sso_enable:
default: True
default: true
description: "Enable Red Hat Single Sign-on installation"
type: "str"
sso_offline_install:
default: False
default: false
description: "Perform an offline install"
type: "bool"
sso_service_name:
@@ -395,7 +403,7 @@ argument_specs:
description: "systemd description for Red Hat Single Sign-On"
type: "str"
sso_patch_version:
required: False
required: false
description: "Red Hat Single Sign-On latest cumulative patch version to apply; defaults to latest version when sso_apply_patches is True"
type: "str"
sso_patch_bundle:

View File

@@ -12,12 +12,12 @@ galaxy_info:
license: Apache License 2.0
min_ansible_version: "2.9"
min_ansible_version: "2.14"
platforms:
- name: EL
versions:
- 8
- name: EL
versions:
- "8"
galaxy_tags:
- keycloak

View File

@@ -1,19 +1,16 @@
---
- name: Check packages to be installed
block:
- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster
ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}"
register: rpm_info
changed_when: rpm_info.failed
- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster
ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}"
register: rpm_info
changed_when: false
failed_when: false
rescue:
- name: "Add missing packages to the yum install list"
ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}"
when: rpm_info.failed
- name: "Add missing packages to the yum install list"
ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
- name: "Install packages: {{ packages_to_install }}"
become: yes
become: true
ansible.builtin.yum:
name: "{{ packages_to_install }}"
state: present

View File

@@ -6,19 +6,19 @@
- firewalld
- name: Enable and start the firewalld service
become: yes
become: true
ansible.builtin.systemd:
name: firewalld
enabled: yes
enabled: true
state: started
- name: "Configure firewall for {{ keycloak.service_name }} ports"
become: yes
- name: "Configure firewall ports for {{ keycloak.service_name }}"
become: true
ansible.posix.firewalld:
port: "{{ item }}"
permanent: true
state: enabled
immediate: yes
immediate: true
loop:
- "{{ keycloak_http_port }}/tcp"
- "{{ keycloak_https_port }}/tcp"

View File

@@ -11,7 +11,7 @@
quiet: true
- name: Check for an existing deployment
become: yes
become: true
ansible.builtin.stat:
path: "{{ keycloak_jboss_home }}"
register: existing_deploy
@@ -20,32 +20,32 @@
when: existing_deploy.stat.exists and keycloak_force_install | bool
block:
- name: "Stop the old {{ keycloak.service_name }} service"
become: yes
ignore_errors: yes
become: true
failed_when: false
ansible.builtin.systemd:
name: keycloak
state: stopped
- name: "Remove the old {{ keycloak.service_name }} deployment"
become: yes
become: true
ansible.builtin.file:
path: "{{ keycloak_jboss_home }}"
state: absent
- name: Check for an existing deployment after possible forced removal
become: yes
become: true
ansible.builtin.stat:
path: "{{ keycloak_jboss_home }}"
- name: "Create {{ keycloak.service_name }} service user/group"
become: yes
- name: "Create service user/group for {{ keycloak.service_name }}"
become: true
ansible.builtin.user:
name: "{{ keycloak_service_user }}"
home: /opt/keycloak
system: yes
create_home: no
- name: "Create {{ keycloak.service_name }} install location"
become: yes
- name: "Create install location for {{ keycloak.service_name }}"
become: true
ansible.builtin.file:
dest: "{{ keycloak_dest }}"
state: directory
@@ -54,7 +54,7 @@
mode: 0750
- name: Create pidfile folder
become: yes
become: true
ansible.builtin.file:
dest: "{{ keycloak_service_pidfile | dirname }}"
state: directory
@@ -68,7 +68,7 @@
archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}"
- name: Check download archive path
become: yes
become: true
ansible.builtin.stat:
path: "{{ archive }}"
register: archive_path
@@ -86,7 +86,7 @@
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: 0644
delegate_to: localhost
run_once: yes
run_once: true
when:
- archive_path is defined
- archive_path.stat is defined
@@ -96,7 +96,7 @@
- name: Perform download from RHN using JBoss Network API
delegate_to: localhost
run_once: yes
run_once: true
when:
- archive_path is defined
- archive_path.stat is defined
@@ -114,13 +114,13 @@
register: rhn_products
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: yes
run_once: true
- name: Determine install zipfile from search results
ansible.builtin.set_fact:
rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + sso_archive + '$') }}"
delegate_to: localhost
run_once: yes
run_once: true
- name: Download Red Hat Single Sign-On
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
@@ -130,7 +130,7 @@
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: yes
run_once: true
- name: Download rhsso archive from alternate location
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
@@ -138,7 +138,7 @@
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: 0644
delegate_to: localhost
run_once: yes
run_once: true
when:
- archive_path is defined
- archive_path.stat is defined
@@ -166,23 +166,23 @@
- not archive_path.stat.exists
- local_archive_path.stat is defined
- local_archive_path.stat.exists
become: yes
become: true
- name: "Check target directory: {{ keycloak.home }}"
ansible.builtin.stat:
path: "{{ keycloak.home }}"
register: path_to_workdir
become: yes
become: true
- name: "Extract {{ keycloak_service_desc }} archive on target"
ansible.builtin.unarchive:
remote_src: yes
remote_src: true
src: "{{ archive }}"
dest: "{{ keycloak_dest }}"
creates: "{{ keycloak.home }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
become: yes
become: true
when:
- new_version_downloaded.changed or not path_to_workdir.stat.exists
notify:
@@ -200,13 +200,13 @@
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
recurse: true
become: yes
become: true
changed_when: false
- name: Ensure permissions are correct on existing deploy
ansible.builtin.command: chown -R "{{ keycloak_service_user }}:{{ keycloak_service_group }}" "{{ keycloak.home }}"
when: keycloak_service_runas
become: yes
become: true
changed_when: false
# driver and configuration
@@ -215,7 +215,7 @@
when: keycloak_jdbc[keycloak_jdbc_engine].enabled
- name: "Deploy custom {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }} from {{ keycloak_config_override_template }}"
become: yes
become: true
ansible.builtin.template:
src: "templates/{{ keycloak_config_override_template }}"
dest: "{{ keycloak_config_path_to_standalone_xml }}"
@@ -227,7 +227,7 @@
when: keycloak_config_override_template | length > 0
- name: "Deploy standalone {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}"
become: yes
become: true
ansible.builtin.template:
src: templates/standalone.xml.j2
dest: "{{ keycloak_config_path_to_standalone_xml }}"
@@ -255,7 +255,7 @@
when: keycloak_ha_enabled and keycloak_ha_discovery == 'TCPPING'
- name: "Deploy HA {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}"
become: yes
become: true
ansible.builtin.template:
src: templates/standalone-ha.xml.j2
dest: "{{ keycloak_config_path_to_standalone_xml }}"
@@ -270,7 +270,7 @@
- keycloak_config_override_template | length == 0
- name: "Deploy HA {{ keycloak.service_name }} config with infinispan remote cache store to {{ keycloak_config_path_to_standalone_xml }}"
become: yes
become: true
ansible.builtin.template:
src: templates/standalone-infinispan.xml.j2
dest: "{{ keycloak_config_path_to_standalone_xml }}"
@@ -285,7 +285,7 @@
- keycloak_config_override_template | length == 0
- name: "Deploy profile.properties file to {{ keycloak_config_path_to_properties }}"
become: yes
become: true
ansible.builtin.template:
src: keycloak-profile.properties.j2
dest: "{{ keycloak_config_path_to_properties }}"

View File

@@ -3,17 +3,17 @@
ansible.builtin.stat:
path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}"
register: dest_path
become: yes
become: true
- name: "Set up module dir for JDBC Driver {{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}"
ansible.builtin.file:
path: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}"
state: directory
recurse: yes
recurse: true
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
become: yes
become: true
when:
- not dest_path.stat.exists
@@ -24,7 +24,7 @@
group: "{{ keycloak_service_group }}"
owner: "{{ keycloak_service_user }}"
mode: 0640
become: yes
become: true
- name: "Deploy module.xml for JDBC Driver"
ansible.builtin.template:
@@ -33,4 +33,4 @@
group: "{{ keycloak_service_group }}"
owner: "{{ keycloak_service_user }}"
mode: 0640
become: yes
become: true

View File

@@ -34,8 +34,8 @@
ansible.builtin.file:
state: link
src: "{{ keycloak_jboss_home }}/standalone/log"
dest: /var/log/keycloak
become: yes
dest: "{{ keycloak_log_target }}"
become: true
- name: Set admin credentials and restart if not already created
block:
@@ -44,7 +44,7 @@
url: "{{ keycloak_url }}/auth/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no
validate_certs: false
register: keycloak_auth_response
until: keycloak_auth_response.status == 200
retries: 2
@@ -58,8 +58,8 @@
- "-rmaster"
- "-u{{ keycloak_admin_user }}"
- "-p{{ keycloak_admin_password }}"
changed_when: yes
become: yes
changed_when: true
become: true
- name: "Restart {{ keycloak.service_name }}"
ansible.builtin.include_tasks: tasks/restart_keycloak.yml
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"

View File

@@ -3,7 +3,7 @@
ansible.builtin.assert:
that:
- keycloak_admin_password | length > 12
quiet: True
quiet: true
fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string"
success_msg: "{{ 'Console administrator password OK' }}"
@@ -11,7 +11,7 @@
ansible.builtin.assert:
that:
- (keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and keycloak_db_enabled) or (not keycloak_ha_enabled and not keycloak_db_enabled)
quiet: True
quiet: true
fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_ha_enabled and keycloak_db_enabled"
success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}"
@@ -20,7 +20,7 @@
that:
- (rhn_username is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install
- (rhn_password is defined and sso_enable is defined and sso_enable) or not sso_enable is defined or not sso_enable or keycloak_offline_install
quiet: True
quiet: true
fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined"
success_msg: "Installing {{ keycloak_service_desc }}"
@@ -31,7 +31,7 @@
- keycloak_jdbc_url | length > 0
- keycloak_db_user | length > 0
- keycloak_db_pass | length > 0
quiet: True
quiet: true
fail_msg: "Configuration for the JDBC persistence is invalid or incomplete"
success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database"
when: keycloak_db_enabled

View File

@@ -2,11 +2,12 @@
- name: "Restart and enable {{ keycloak.service_name }} service"
ansible.builtin.systemd:
name: keycloak
enabled: yes
enabled: true
state: restarted
become: yes
daemon_reload: true
become: true
delegate_to: "{{ ansible_play_hosts | first }}"
run_once: True
run_once: true
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
ansible.builtin.uri:
@@ -14,7 +15,7 @@
register: keycloak_status
until: keycloak_status.status == 200
delegate_to: "{{ ansible_play_hosts | first }}"
run_once: True
run_once: true
retries: "{{ keycloak_service_start_retries }}"
delay: "{{ keycloak_service_start_delay }}"
@@ -23,5 +24,5 @@
name: keycloak
enabled: yes
state: restarted
become: yes
become: true
when: inventory_hostname != ansible_play_hosts | first

View File

@@ -12,11 +12,11 @@
path: "{{ patch_archive }}"
register: patch_archive_path
when: sso_patch_version is defined
become: yes
become: true
- name: Perform patch download from RHN via JBossNetwork API
delegate_to: localhost
run_once: yes
run_once: true
when:
- sso_enable is defined and sso_enable
- not keycloak_offline_install
@@ -32,21 +32,21 @@
register: rhn_products
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: yes
run_once: true
- name: Determine patch versions list
ansible.builtin.set_fact:
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 }}"
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 }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost
run_once: yes
run_once: true
- name: Determine latest version
ansible.builtin.set_fact:
sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost
run_once: yes
run_once: true
- name: Determine install zipfile from search results
ansible.builtin.set_fact:
@@ -55,7 +55,7 @@
patch_version: "{{ sso_latest_version }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost
run_once: yes
run_once: true
- name: "Determine selected patch from supplied version: {{ sso_patch_version }}"
ansible.builtin.set_fact:
@@ -64,7 +64,7 @@
patch_version: "{{ sso_patch_version }}"
when: sso_patch_version is defined
delegate_to: localhost
run_once: yes
run_once: true
- name: Download Red Hat Single Sign-On patch
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
@@ -74,7 +74,7 @@
dest: "{{ local_path.stat.path }}/{{ patch_bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: yes
run_once: true
- name: Set download patch archive path
ansible.builtin.set_fact:
@@ -84,7 +84,7 @@
ansible.builtin.stat:
path: "{{ patch_archive }}"
register: patch_archive_path
become: yes
become: true
## copy and unpack
- name: Copy patch archive to target nodes
@@ -99,7 +99,7 @@
- not patch_archive_path.stat.exists
- local_archive_path.stat is defined
- local_archive_path.stat.exists
become: yes
become: true
- name: "Check installed patches"
ansible.builtin.include_tasks: rhsso_cli.yml
@@ -107,7 +107,7 @@
query: "patch info"
args:
apply:
become: yes
become: true
become_user: "{{ keycloak_service_user }}"
- name: "Perform patching"
@@ -122,7 +122,7 @@
query: "patch apply {{ patch_archive }}"
args:
apply:
become: yes
become: true
become_user: "{{ keycloak_service_user }}"
- name: "Restart server to ensure patch content is running"
@@ -133,7 +133,7 @@
- cli_result.rc == 0
args:
apply:
become: yes
become: true
become_user: "{{ keycloak_service_user }}"
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
@@ -150,7 +150,7 @@
query: "patch info"
args:
apply:
become: yes
become: true
become_user: "{{ keycloak_service_user }}"
- name: "Verify installed patch version"

View File

@@ -2,9 +2,10 @@
- name: "Start {{ keycloak.service_name }} service"
ansible.builtin.systemd:
name: keycloak
enabled: yes
enabled: true
state: started
become: yes
daemon_reload: true
become: true
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
ansible.builtin.uri:

View File

@@ -2,6 +2,6 @@
- name: "Stop {{ keycloak.service_name }}"
ansible.builtin.systemd:
name: keycloak
enabled: yes
enabled: true
state: stopped
become: yes
become: true

View File

@@ -1,6 +1,6 @@
---
- name: "Configure {{ keycloak.service_name }} service script wrapper"
become: yes
become: true
ansible.builtin.template:
src: keycloak-service.sh.j2
dest: "{{ keycloak_dest }}/keycloak-service.sh"
@@ -15,7 +15,7 @@
rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}"
- name: "Configure sysconfig file for {{ keycloak.service_name }} service"
become: yes
become: true
ansible.builtin.template:
src: keycloak-sysconfig.j2
dest: /etc/sysconfig/keycloak
@@ -34,20 +34,14 @@
owner: root
group: root
mode: 0644
become: yes
become: true
register: systemdunit
notify:
- restart keycloak
- name: Reload systemd
become: yes
ansible.builtin.systemd:
daemon_reload: yes
when: systemdunit.changed
- name: "Start and wait for {{ keycloak.service_name }} service (first node db)"
ansible.builtin.include_tasks: start_keycloak.yml
run_once: yes
run_once: true
when: keycloak_db_enabled
- name: "Start and wait for {{ keycloak.service_name }} service (remaining nodes)"
@@ -56,7 +50,7 @@
- name: Check service status
ansible.builtin.command: "systemctl status keycloak"
register: keycloak_service_status
changed_when: False
changed_when: false
- name: Verify service status
ansible.builtin.assert:

View File

@@ -737,7 +737,7 @@
<inet-address value="{{ keycloak_bind_address }}"/>
</interface>
</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:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>

View File

@@ -638,7 +638,7 @@
<inet-address value="{{ keycloak_bind_address }}"/>
</interface>
</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:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>

View File

@@ -734,7 +734,7 @@
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>

View File

@@ -598,7 +598,7 @@
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>

View File

@@ -674,7 +674,7 @@
<inet-address value="{{ keycloak_bind_address }}"/>
</interface>
</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:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>

View File

@@ -712,7 +712,7 @@
<inet-address value="{{ keycloak_bind_address }}"/>
</interface>
</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:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>

View File

@@ -604,7 +604,7 @@
<inet-address value="{{ keycloak_bind_address }}"/>
</interface>
</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:{{ keycloak_jboss_port_offset }}}">
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>

View File

@@ -2,8 +2,8 @@
# internal variables below
# locations
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}"
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + keycloak_jboss_port_offset }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + keycloak_jboss_port_offset }}"
keycloak:

View File

@@ -11,7 +11,7 @@ Role Defaults
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` |
|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` |
* Service configuration
@@ -19,34 +19,55 @@ Role Defaults
| 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_bind_address`| Address for binding service ports | `0.0.0.0` |
|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` |
|`keycloak_quarkus_port`| The port used by the proxy when exposing the hostname | `-1` |
|`keycloak_quarkus_path`| This should be set if proxy uses a different context-path for Keycloak | |
|`keycloak_quarkus_http_port`| HTTP listening port | `8080` |
|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` |
|`keycloak_quarkus_ajp_port`| AJP port | `8009` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7600` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|`keycloak_quarkus_service_user`| Posix account username | `keycloak` |
|`keycloak_quarkus_service_group`| Posix account group | `keycloak` |
|`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_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_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` |
|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_quarkus_frontend_url`| Service public URL | `http://localhost:8080/auth` |
|`keycloak_quarkus_http_relative_path` | Service context path | `auth` |
|`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_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` |
|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` |
|`keycloak_quarkus_https_enabled`| Enable listener on HTTPS port | `False` |
|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` |
|`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_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` |
|`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` |
|`keycloak_quarkus_key_store_password`| Password for the key store | `""` |
|`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` |
|`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` |
* Hostname configuration
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` |
|`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` |
|`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
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres] | `postgres` |
|`keycloak_quarkus_jdbc_engine` | Database engine [mariadb,postres,mssql] | `postgres` |
|`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` |
|`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` |
|`keycloak_quarkus_jdbc_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` |
@@ -59,11 +80,11 @@ Role Defaults
|:---------|:------------|:--------|
|`keycloak_quarkus_ispn_user` | Username for connecting to infinispan | `supervisor` |
|`keycloak_quarkus_ispn_pass` | Password for connecting to infinispan | `supervisor` |
|`keycloak_quarkus_ispn_url` | URL for connecting to infinispan | `localhost` |
|`keycloak_quarkus_ispn_hosts` | host name/port for connecting to infinispan, eg. host1:11222;host2:11222 | `localhost:11222` |
|`keycloak_quarkus_ispn_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` |
|`keycloak_quarkus_ispn_use_ssl` | Whether infinispan uses TLS connection | `false` |
|`keycloak_quarkus_ispn_trust_store_path` | Path to infinispan server trust certificate | `/etc/pki/java/cacerts` |
|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` |
|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` |
* Install options
@@ -71,8 +92,7 @@ Role Defaults
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|`keycloak_quarkus_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/<version>/<archive>`|
|`keycloak_quarkus_version`| keycloak.org package version | `22.0.3` |
|`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` |
@@ -92,15 +112,18 @@ Role Defaults
|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` |
|`keycloak_force_install` | Remove pre-existing versions of service | `False` |
|`keycloak_url` | URL for configuration rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_http_port }}` |
|`keycloak_management_url` | URL for management console rest calls | `http://{{ keycloak_quarkus_host }}:{{ keycloak_management_http_port }}` |
|`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` |
|`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` |
|`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` |
|`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` |
|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` |
|`keycloak_quarkus_log_max_file_size`| 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. | `10M` |
|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep" | `10` |
|`keycloak_quarkus_log_file_suffix`| 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. | `.yyyy-MM-dd.zip` |
|`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy | `edge` |
|`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` |
|`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` |
Role Variables
--------------
@@ -108,6 +131,8 @@ Role Variables
| Variable | Description | Required |
|:---------|:------------|----------|
|`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_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` |
License

View File

@@ -1,12 +1,12 @@
---
### Configuration specific to keycloak
keycloak_quarkus_version: 22.0.3
keycloak_quarkus_version: 23.0.7
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 }}"
# whether to install from local archive
keycloak_quarkus_offline_install: False
keycloak_quarkus_offline_install: false
### Install location and service settings
keycloak_quarkus_jvm_package: java-17-openjdk-headless
@@ -14,57 +14,84 @@ keycloak_quarkus_java_home:
keycloak_quarkus_dest: /opt/keycloak
keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}"
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_group: keycloak
keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid"
keycloak_quarkus_configure_firewalld: False
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_service_restart_always: false
keycloak_quarkus_service_restart_on_failure: false
keycloak_quarkus_service_restartsec: "10s"
### administrator console password
keycloak_quarkus_admin_user: admin
keycloak_quarkus_admin_pass: ''
keycloak_quarkus_admin_pass:
keycloak_quarkus_master_realm: master
### Configuration settings
keycloak_quarkus_bind_address: 0.0.0.0
keycloak_quarkus_host: localhost
keycloak_quarkus_port: -1
keycloak_quarkus_http_enabled: True
keycloak_quarkus_path:
keycloak_quarkus_http_enabled: true
keycloak_quarkus_http_port: 8080
keycloak_quarkus_https_port: 8443
keycloak_quarkus_ajp_port: 8009
keycloak_quarkus_jgroups_port: 7600
keycloak_quarkus_jgroups_port: 7800
keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m"
### TLS/HTTPS configuration
keycloak_quarkus_https_enabled: False
keycloak_quarkus_https_key_file_enabled: false
keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem"
keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem"
#### key store configuration
keycloak_quarkus_https_key_store_enabled: false
keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12"
keycloak_quarkus_key_store_password: ''
##### trust store configuration
keycloak_quarkus_https_trust_store_enabled: false
keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12"
keycloak_quarkus_trust_store_password: ''
### 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"
### Enable database configuration, must be enabled when HA is configured
keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}"
### keycloak frontend url
keycloak_quarkus_http_relative_path: auth
keycloak_quarkus_frontend_url: http://localhost:8080/auth
keycloak_quarkus_frontend_url:
keycloak_quarkus_admin_url:
### Set the path relative to / for serving resources. The path must start with a /
### (set to `/auth` for retrocompatibility with pre-quarkus releases)
keycloak_quarkus_http_relative_path: /
# 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: true
# 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_hostname_strict_backchannel: false
# proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough]
keycloak_quarkus_proxy_mode: edge
# disable xa transactions
keycloak_quarkus_transaction_xa_enabled: True
keycloak_quarkus_transaction_xa_enabled: true
keycloak_quarkus_metrics_enabled: False
keycloak_quarkus_health_enabled: True
# 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_spi_sticky_session_encoder_infinispan_should_attach_route: true
keycloak_quarkus_metrics_enabled: false
keycloak_quarkus_health_enabled: true
### infinispan remote caches access (hotrod)
keycloak_quarkus_ispn_user: supervisor
keycloak_quarkus_ispn_pass: supervisor
keycloak_quarkus_ispn_url: localhost
keycloak_quarkus_ispn_hosts: "localhost:11222"
keycloak_quarkus_ispn_sasl_mechanism: SCRAM-SHA-512
keycloak_quarkus_ispn_use_ssl: False
keycloak_quarkus_ispn_use_ssl: false
# if ssl is enabled, import ispn server certificate here
keycloak_quarkus_ispn_trust_store_path: /etc/pki/java/cacerts
keycloak_quarkus_ispn_trust_store_password: changeit
@@ -84,9 +111,16 @@ keycloak_quarkus_default_jdbc:
mariadb:
url: 'jdbc:mariadb://localhost:3306/keycloak'
version: 2.7.4
mssql:
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
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" # 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
keycloak_quarkus_log: file
keycloak_quarkus_log_level: info
keycloak_quarkus_log_file: data/log/keycloak.log
keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n'
keycloak_quarkus_log_target: /var/log/keycloak
keycloak_quarkus_log_max_file_size: 10M
keycloak_quarkus_log_max_backup_index: 10
keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip'

View File

@@ -1,4 +1,8 @@
---
# handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes
- name: "Rebuild {{ keycloak.service_name }} config"
ansible.builtin.include_tasks: rebuild_config.yml
listen: "rebuild keycloak config"
- name: "Restart {{ keycloak.service_name }}"
ansible.builtin.include_tasks: restart.yml
listen: "restart keycloak"

View File

@@ -69,14 +69,24 @@ argument_specs:
default: false
description: "Ensure firewalld is running and configure keycloak ports"
type: "bool"
keycloak_service_restart_always:
default: false
description: "systemd restart always behavior of service; takes precedence over keycloak_service_restart_on_failure if true"
type: "bool"
keycloak_service_restart_on_failure:
default: false
description: "systemd restart on-failure behavior of service"
type: "bool"
keycloak_service_restartsec:
default: "10s"
description: "systemd RestartSec for service"
type: "str"
keycloak_quarkus_admin_user:
# line 22 of defaults/main.yml
default: "admin"
description: "Administration console user account"
type: "str"
keycloak_quarkus_admin_pass:
# line 23 of defaults/main.yml
default: ""
required: true
description: "Password of console admin account"
type: "str"
keycloak_quarkus_master_realm:
@@ -97,19 +107,23 @@ argument_specs:
default: -1
description: "The port used by the proxy when exposing the hostname"
type: "int"
keycloak_quarkus_path:
required: false
description: "This should be set if proxy uses a different context-path for Keycloak"
type: "str"
keycloak_quarkus_http_enabled:
default: true
description: "Enable listener on HTTP port"
type: "bool"
type: "bool"
keycloak_quarkus_http_port:
# line 29 of defaults/main.yml
default: 8080
description: "HTTP port"
type: "int"
keycloak_quarkus_https_enabled:
keycloak_quarkus_https_key_file_enabled:
default: false
description: "Enable listener on HTTPS port"
type: "bool"
description: "Enable configuration of HTTPS via files in PEM format"
type: "bool"
keycloak_quarkus_key_file:
default: "{{ keycloak.home }}/conf/server.key.pem"
description: "The file path to a private key in PEM format"
@@ -118,6 +132,30 @@ argument_specs:
default: "{{ keycloak.home }}/conf/server.crt.pem"
description: "The file path to a server certificate or certificate chain in PEM format"
type: "str"
keycloak_quarkus_https_key_store_enabled:
default: false
description: "Enable configuration of HTTPS via a key store"
type: "bool"
keycloak_quarkus_key_store_file:
default: "{{ keycloak.home }}/conf/key_store.p12"
description: "The file path to the key store"
type: "str"
keycloak_quarkus_key_store_password:
default: ""
description: "Password for the key store"
type: "str"
keycloak_quarkus_https_trust_store_enabled:
default: false
description: "Enalbe confiugration of a trust store"
type: "bool"
keycloak_quarkus_trust_store_file:
default: "{{ keycloak.home }}/conf/trust_store.p12"
description: "The file path to the trust store"
type: "str"
keycloak_quarkus_trust_store_password:
default: ""
description: "Password for the trust store"
type: "str"
keycloak_quarkus_https_port:
# line 30 of defaults/main.yml
default: 8443
@@ -130,7 +168,7 @@ argument_specs:
type: "int"
keycloak_quarkus_jgroups_port:
# line 32 of defaults/main.yml
default: 7600
default: 7800
description: "jgroups cluster tcp port"
type: "int"
keycloak_quarkus_java_opts:
@@ -143,21 +181,28 @@ argument_specs:
default: false
description: "Enable auto configuration for database backend, clustering and remote caches on infinispan"
type: "bool"
keycloak_quarkus_ha_discovery:
default: "TCPPING"
description: "Discovery protocol for HA cluster members"
type: "str"
keycloak_quarkus_db_enabled:
# line 38 of defaults/main.yml
default: "{{ True if keycloak_quarkus_ha_enabled else False }}"
description: "Enable auto configuration for database backend"
type: "str"
keycloak_quarkus_http_relative_path:
# line 41 of defaults/main.yml
default: "auth"
description: "Service context path"
required: false
default: /
description: "Set the path relative to / for serving resources. The path must start with a /"
type: "str"
keycloak_quarkus_frontend_url:
# line 41 of defaults/main.yml
default: "http://localhost:8080/auth"
required: false
description: "Service public URL"
type: "str"
keycloak_quarkus_admin_url:
required: false
description: "Service URL for the admin console"
type: "str"
keycloak_quarkus_metrics_enabled:
# line 43 of defaults/main.yml
default: false
@@ -177,10 +222,10 @@ argument_specs:
default: "supervisor"
description: "Password for connecting to infinispan"
type: "str"
keycloak_quarkus_ispn_url:
keycloak_quarkus_ispn_hosts:
# line 48 of defaults/main.yml
default: "localhost"
description: "URL for connecting to infinispan"
default: "localhost:11222"
description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222"
type: "str"
keycloak_quarkus_ispn_sasl_mechanism:
# line 49 of defaults/main.yml
@@ -205,7 +250,7 @@ argument_specs:
keycloak_quarkus_jdbc_engine:
# line 56 of defaults/main.yml
default: "postgres"
description: "Database engine [mariadb,postres]"
description: "Database engine [mariadb,postres,mssql]"
type: "str"
keycloak_quarkus_db_user:
# line 58 of defaults/main.yml
@@ -243,15 +288,93 @@ argument_specs:
default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n'
type: "str"
description: "Set a format specific to file log entries"
keycloak_quarkus_log_target:
default: '/var/log/keycloak'
type: "str"
description: "Set the destination of the keycloak log folder link"
keycloak_quarkus_log_max_file_size:
default: 10M
type: "str"
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."
keycloak_quarkus_log_max_backup_index:
default: 10
type: "str"
description: "Set the maximum number of archived log files to keep"
keycloak_quarkus_log_file_suffix:
default: '.yyyy-MM-dd.zip'
type: "str"
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."
keycloak_quarkus_proxy_mode:
default: 'edge'
type: "str"
description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy"
keycloak_quarkus_start_dev:
default: False
default: false
type: "bool"
description: "Whether to start the service in development mode (start-dev)"
keycloak_quarkus_transaction_xa_enabled:
default: True
default: true
type: "bool"
description: "Enable or disable XA transactions which may not be supported by some DBMS"
keycloak_quarkus_hostname_strict:
default: true
type: "bool"
description: "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:
default: false
type: "bool"
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."
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route:
default: true
type: "bool"
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"
downstream:
options:
rhbk_version:
default: "22.0.6"
description: "Red Hat Build of Keycloak version"
type: "str"
rhbk_archive:
default: "rhbk-{{ rhbk_version }}.zip"
description: "Red Hat Build of Keycloak install archive filename"
type: "str"
rhbk_dest:
default: "/opt/rhbk"
description: "Root installation directory"
type: "str"
rhbk_installdir:
default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version }}"
description: "Installation path for Red Hat Build of Keycloak"
type: "str"
rhbk_apply_patches:
default: false
description: "Install Red Hat Build of Keycloak most recent cumulative patch"
type: "bool"
rhbk_enable:
default: true
description: "Enable Red Hat Build of Keycloak installation"
type: "str"
rhbk_offline_install:
default: false
description: "Perform an offline install"
type: "bool"
rhbk_service_name:
default: "rhbk"
description: "systemd service name for Red Hat Build of Keycloak"
type: "str"
rhbk_service_desc:
default: "Red Hat Build of Keycloak"
description: "systemd description for Red Hat Build of Keycloak"
type: "str"
rhbk_patch_version:
required: false
description: "Red Hat Build of Keycloak latest cumulative patch version to apply; defaults to latest version when rhbk_apply_patches is True"
type: "str"
rhbk_patch_bundle:
default: "rhbk-{{ rhbk_patch_version | default('[0-9]+[.][0-9]+[.][0-9]+') }}-patch.zip"
description: "Red Hat Build of Keycloak patch archive filename"
type: "str"
rhbk_product_category:
default: "rhbk"
description: "JBossNetwork API category for Red Hat Build of Keycloak"
type: "str"

View File

@@ -8,12 +8,12 @@ galaxy_info:
license: Apache License 2.0
min_ansible_version: "2.9"
min_ansible_version: "2.14"
platforms:
- name: EL
versions:
- 8
- name: EL
versions:
- "8"
galaxy_tags:
- keycloak
@@ -24,3 +24,4 @@ galaxy_info:
- authentication
- identity
- security
- rhbk

View File

@@ -1,19 +1,16 @@
---
- name: Check packages to be installed
block:
- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster
ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}"
register: rpm_info
changed_when: rpm_info.failed
- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster
ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}"
register: rpm_info
changed_when: false
failed_when: false
rescue:
- name: "Add missing packages to the yum install list"
ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | flatten }}"
when: rpm_info.failed
- name: "Add missing packages to the yum install list"
ansible.builtin.set_fact:
packages_to_install: "{{ packages_to_install | default([]) + rpm_info.stdout_lines | map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
- name: "Install packages: {{ packages_to_install | join(',') }}"
become: yes
- name: "Install packages: {{ packages_to_install }}"
become: true
ansible.builtin.yum:
name: "{{ packages_to_install }}"
state: present

View File

@@ -6,19 +6,19 @@
- firewalld
- name: Enable and start the firewalld service
become: yes
become: true
ansible.builtin.systemd:
name: firewalld
enabled: yes
enabled: true
state: started
- name: "Configure firewall for {{ keycloak.service_name }} ports"
become: yes
become: true
ansible.posix.firewalld:
port: "{{ item }}"
permanent: true
state: enabled
immediate: yes
immediate: true
loop:
- "{{ keycloak_quarkus_http_port }}/tcp"
- "{{ keycloak_quarkus_https_port }}/tcp"

View File

@@ -11,21 +11,21 @@
quiet: true
- name: Check for an existing deployment
become: yes
become: true
ansible.builtin.stat:
path: "{{ keycloak.home }}"
register: existing_deploy
- name: "Create {{ keycloak.service_name }} service user/group"
become: yes
become: true
ansible.builtin.user:
name: "{{ keycloak.service_user }}"
home: /opt/keycloak
system: yes
system: true
create_home: no
- name: "Create {{ keycloak.service_name }} install location"
become: yes
become: true
ansible.builtin.file:
dest: "{{ keycloak_quarkus_dest }}"
state: directory
@@ -39,7 +39,7 @@
archive: "{{ keycloak_quarkus_dest }}/{{ keycloak.bundle }}"
- name: Check download archive path
become: yes
become: true
ansible.builtin.stat:
path: "{{ archive }}"
register: archive_path
@@ -57,11 +57,51 @@
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: 0640
delegate_to: localhost
run_once: true
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- not keycloak.offline_install
- not rhbk_enable is defined or not rhbk_enable
- name: Perform download from RHN using JBoss Network API
delegate_to: localhost
run_once: true
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- rhbk_enable is defined and rhbk_enable
- not keycloak.offline_install
block:
- name: Retrieve product download using JBoss Network API
middleware_automation.common.product_search:
client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}"
product_type: DISTRIBUTION
product_version: "{{ rhbk_version }}"
product_category: "{{ rhbk_product_category }}"
register: rhn_products
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: true
- name: Determine install zipfile from search results
ansible.builtin.set_fact:
rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '[^/]*/' + rhbk_archive + '$') }}"
delegate_to: localhost
run_once: true
- name: Download Red Hat Build of Keycloak
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}"
product_id: "{{ (rhn_filtered_products | first).id }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: true
- name: Check downloaded archive
ansible.builtin.stat:
@@ -76,29 +116,29 @@
dest: "{{ archive }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0750
mode: 0640
register: new_version_downloaded
when:
- not archive_path.stat.exists
- local_archive_path.stat is defined
- local_archive_path.stat.exists
become: yes
become: true
- name: "Check target directory: {{ keycloak.home }}/bin/"
ansible.builtin.stat:
path: "{{ keycloak.home }}/bin/"
register: path_to_workdir
become: yes
become: true
- name: "Extract Keycloak archive on target"
ansible.builtin.unarchive:
remote_src: yes
remote_src: true
src: "{{ archive }}"
dest: "{{ keycloak_quarkus_dest }}"
creates: "{{ keycloak.home }}/bin/"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
become: yes
become: true
when:
- (not path_to_workdir.stat.exists) or new_version_downloaded.changed
notify:
@@ -109,3 +149,9 @@
msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression"
when:
- (not new_version_downloaded.changed) and path_to_workdir.stat.exists
- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver"
ansible.builtin.include_tasks: jdbc_driver.yml
when:
- rhbk_enable is defined and rhbk_enable
- keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined

View File

@@ -0,0 +1,12 @@
---
- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}"
ansible.builtin.get_url:
url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url }}"
dest: "{{ keycloak.home }}/providers"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0640
become: true
notify:
- restart keycloak

View File

@@ -28,8 +28,9 @@
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0644
become: yes
become: true
notify:
- rebuild keycloak config
- restart keycloak
- name: "Configure quarkus config for keycloak service"
@@ -39,9 +40,35 @@
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0644
become: yes
become: true
notify:
- restart keycloak
- restart keycloak
- name: Create tcpping cluster node list
ansible.builtin.set_fact:
keycloak_quarkus_cluster_nodes: >
{{ keycloak_quarkus_cluster_nodes | default([]) + [
{
"name": item,
"address": 'jgroups-' + item,
"inventory_host": hostvars[item].ansible_default_ipv4.address | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']',
"value": hostvars[item].ansible_default_ipv4.address | default(item)
}
] }}
loop: "{{ ansible_play_batch }}"
when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING'
- name: "Configure infinispan config for keycloak service"
ansible.builtin.template:
src: cache-ispn.xml.j2
dest: "{{ keycloak.home }}/conf/cache-ispn.xml"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0644
become: true
notify:
- rebuild keycloak config
- restart keycloak
- name: Ensure logdirectory exists
ansible.builtin.file:
@@ -50,7 +77,7 @@
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: 0775
become: yes
become: true
- name: Flush pending handlers
ansible.builtin.meta: flush_handlers
@@ -61,12 +88,12 @@
- name: Check service status
ansible.builtin.command: "systemctl status keycloak"
register: keycloak_service_status
changed_when: False
changed_when: false
- name: Link default logs directory
ansible.builtin.file:
state: link
src: "{{ keycloak.log.file | dirname }}"
dest: /var/log/keycloak
force: yes
become: yes
dest: "{{ keycloak_quarkus_log_target }}"
force: true
become: true

View File

@@ -3,15 +3,23 @@
ansible.builtin.assert:
that:
- 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 variable to a 12+ char long string"
success_msg: "{{ 'Console administrator password OK' }}"
- name: Validate relative path
ansible.builtin.assert:
that:
- keycloak_quarkus_http_relative_path is regex('^/.*')
quiet: true
fail_msg: "the relative path must begin with /"
success_msg: "{{ 'relative path OK' }}"
- name: Validate configuration
ansible.builtin.assert:
that:
- (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)
quiet: True
quiet: true
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' }}"

View File

@@ -0,0 +1,7 @@
---
# cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup
- name: "Rebuild {{ keycloak.service_name }} config"
ansible.builtin.shell: |
{{ keycloak.home }}/bin/kc.sh build
become: true
changed_when: true

View File

@@ -2,6 +2,7 @@
- name: "Restart and enable {{ keycloak.service_name }} service"
ansible.builtin.systemd:
name: keycloak
enabled: yes
enabled: true
state: restarted
become: yes
daemon_reload: true
become: true

View File

@@ -2,9 +2,10 @@
- name: "Start {{ keycloak.service_name }} service"
ansible.builtin.systemd:
name: keycloak
enabled: yes
enabled: true
state: started
become: yes
daemon_reload: true
become: true
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
ansible.builtin.uri:

View File

@@ -4,7 +4,7 @@
rpm_java_home: "/etc/alternatives/jre_{{ keycloak_quarkus_jvm_package | regex_search('(?<=java-)[0-9.]+') }}"
- name: "Configure sysconfig file for keycloak service"
become: yes
become: true
ansible.builtin.template:
src: keycloak-sysconfig.j2
dest: /etc/sysconfig/keycloak
@@ -23,13 +23,7 @@
owner: root
group: root
mode: 0644
become: yes
become: true
register: systemdunit
notify:
- restart keycloak
- name: Reload systemd
become: yes
ansible.builtin.systemd:
daemon_reload: yes
when: systemdunit.changed

View File

@@ -0,0 +1,101 @@
<!-- {{ ansible_managed }} -->
<!--
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
~ and other contributors as indicated by the @author tags.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<infinispan
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:14.0 http://www.infinispan.org/schemas/infinispan-config-14.0.xsd"
xmlns="urn:infinispan:config:14.0">
{% set stack_expression='' %}
{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %}
{% set stack_expression='stack="tcpping"' %}
<jgroups>
<stack name="tcpping" extends="tcp">
<!-- <TCP external_addr="${env.KC_EXTERNAL_ADDR}" bind_addr="{{ keycloak_quarkus_bind_address }}" bind_port="{{ keycloak_quarkus_jgroups_port }}" /> -->
<TCPPING
initial_hosts="{{ keycloak_quarkus_cluster_nodes | map(attribute='inventory_host') | join (',') }}"
port_range="0"
stack.combine="REPLACE"
stack.position="MPING"
/>
</stack>
</jgroups>
{% endif %}
<cache-container name="keycloak">
<transport lock-timeout="60000" {{ stack_expression }}/>
<local-cache name="realms" simple-cache="true">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<local-cache name="users" simple-cache="true">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<distributed-cache name="sessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="authenticationSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="offlineSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="clientSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="offlineClientSessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<distributed-cache name="loginFailures" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
<local-cache name="authorization" simple-cache="true">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<memory max-count="10000"/>
</local-cache>
<replicated-cache name="work">
<expiration lifespan="-1"/>
</replicated-cache>
<local-cache name="keys" simple-cache="true">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="3600000"/>
<memory max-count="1000"/>
</local-cache>
<distributed-cache name="actionTokens" owners="2">
<encoding>
<key media-type="application/x-java-object"/>
<value media-type="application/x-java-object"/>
</encoding>
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
<memory max-count="-1"/>
</distributed-cache>
</cache-container>
</infinispan>

View File

@@ -1,5 +1,6 @@
# {{ ansible_managed }}
KEYCLOAK_ADMIN={{ keycloak_quarkus_admin_user }}
KEYCLOAK_ADMIN_PASSWORD='{{ keycloak_quarkus_admin_pass }}'
PATH={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME={{ keycloak_java_home | default(keycloak_rpm_java_home, true) }}
PATH={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
JAVA_HOME={{ keycloak_quarkus_java_home | default(keycloak_rpm_java_home, true) }}
JAVA_OPTS_APPEND={{ keycloak_quarkus_java_opts }}

View File

@@ -9,41 +9,58 @@ db-password={{ keycloak_quarkus_db_pass }}
{% endif %}
# Observability
metrics-enabled={{ keycloak_quarkus_metrics_enabled }}
health-enabled={{ keycloak_quarkus_health_enabled }}
metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }}
health-enabled={{ keycloak_quarkus_health_enabled | lower }}
# HTTP
http-enabled={{ keycloak_quarkus_http_enabled }}
http-enabled={{ keycloak_quarkus_http_enabled | lower }}
http-port={{ keycloak_quarkus_http_port }}
http-relative-path={{ keycloak_quarkus_http_relative_path }}
# HTTPS
https-port={{ keycloak_quarkus_https_port }}
{% if keycloak_quarkus_https_enabled %}
{% if keycloak_quarkus_https_key_file_enabled %}
https-certificate-file={{ keycloak_quarkus_cert_file}}
https-certificate-key-file={{ keycloak_quarkus_key_file }}
{% endif %}
{% if keycloak_quarkus_https_key_store_enabled %}
https-key-store-file={{ keycloak_quarkus_key_store_file }}
https-key-store-password={{ keycloak_quarkus_key_store_password }}
{% endif %}
{% if keycloak_quarkus_https_trust_store_enabled %}
https-trust-store-file={{ keycloak_quarkus_trust_store_file }}
https-trust-store-password={{ keycloak_quarkus_trust_store_password }}
{% endif %}
# Hostname for the Keycloak server.
# Client URL configuration
{% if keycloak_quarkus_frontend_url %}
hostname-url={{ keycloak_quarkus_frontend_url }}
{% else %}
hostname={{ keycloak_quarkus_host }}
hostname-port={{ keycloak_quarkus_port }}
hostname-path={{ keycloak_quarkus_http_relative_path }}
hostname-path={{ keycloak_quarkus_path }}
{% endif %}
hostname-admin-url={{ keycloak_quarkus_admin_url }}
hostname-strict={{ keycloak_quarkus_hostname_strict | lower }}
hostname-strict-backchannel={{ keycloak_quarkus_hostname_strict_backchannel | lower }}
# Cluster
{% if keycloak_quarkus_ha_enabled %}
cache=ispn
cache-config-file=cache-ispn.xml
cache-stack=tcp
{% if keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING' %}
# cache-stack=tcp # configured directly in `cache-ispn.xml`
{% endif %}
{% endif %}
{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %}
# Proxy
proxy={{ keycloak_quarkus_proxy_mode }}
{% endif %}
# Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy
#spi-sticky-session-encoder-infinispan-should-attach-route=false
spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }}
# Transaction
transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled }}
transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }}
# Logging
#log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n

View File

@@ -10,9 +10,19 @@ PIDFile={{ keycloak_quarkus_service_pidfile }}
{% if keycloak_quarkus_start_dev %}
ExecStart={{ keycloak.home }}/bin/kc.sh start-dev
{% else %}
ExecStart={{ keycloak.home }}/bin/kc.sh start --log={{ keycloak_quarkus_log }}
ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized
{% endif %}
User={{ keycloak.service_user }}
Group={{ keycloak.service_group }}
{% if keycloak_quarkus_service_restart_always %}
Restart=always
{% elif keycloak_quarkus_service_restart_on_failure %}
Restart=on-failure
{% endif %}
RestartSec={{ keycloak_quarkus_service_restartsec }}
{% if keycloak_quarkus_http_port|int < 1024 or keycloak_quarkus_https_port|int < 1024 %}
AmbientCapabilities=CAP_NET_BIND_SERVICE
{% endif %}
[Install]
WantedBy=multi-user.target

View File

@@ -1,10 +1,16 @@
# {{ ansible_managed }}
{% if keycloak_quarkus_ha_enabled %}
quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_url }}
quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE
quarkus.infinispan-client.use-auth=true
{% if not rhbk_enable or keycloak_quarkus_version.split('.')[0]|int < 22 %}
quarkus.infinispan-client.server-list={{ keycloak_quarkus_ispn_hosts }}
quarkus.infinispan-client.auth-username={{ keycloak_quarkus_ispn_user }}
quarkus.infinispan-client.auth-password={{ keycloak_quarkus_ispn_pass }}
{% else %}
quarkus.infinispan-client.hosts={{ keycloak_quarkus_ispn_hosts }}
quarkus.infinispan-client.username={{ keycloak_quarkus_ispn_user }}
quarkus.infinispan-client.password={{ keycloak_quarkus_ispn_pass }}
{% endif %}
quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE
quarkus.infinispan-client.use-auth=true
quarkus.infinispan-client.auth-realm=default
quarkus.infinispan-client.auth-server-name=infinispan
quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_ispn_sasl_mechanism }}
@@ -14,6 +20,10 @@ quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_ispn_trust_st
quarkus.infinispan-client.trust-store-type=jks
{% endif %}
#quarkus.infinispan-client.use-schema-registration=true
#quarkus.infinispan-client.auth-client-subject
#quarkus.infinispan-client.auth-callback-handler
{% endif %}
{% endif %}
quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }}
quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }}
quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }}
{% if keycloak_quarkus_db_enabled %}
quarkus.transaction-manager.enable-recovery=true
{% endif %}

View File

@@ -4,7 +4,7 @@ keycloak:
config_dir: "{{ keycloak_quarkus_config_dir }}"
bundle: "{{ keycloak_quarkus_archive }}"
service_name: "keycloak"
health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}/realms/master/.well-known/openid-configuration"
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"
cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh"
service_user: "{{ keycloak_quarkus_service_user }}"
service_group: "{{ keycloak_quarkus_service_group }}"

View File

@@ -40,7 +40,7 @@ keycloak_clients: []
keycloak_client_default_roles: []
# if True, create a public client; otherwise, a confidetial client
keycloak_client_public: True
keycloak_client_public: true
# allowed web origins for the client
keycloak_client_web_origins: '+'

View File

@@ -83,18 +83,18 @@ argument_specs:
type: "list"
keycloak_url:
# line 14 of keycloak_realm/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
default: "http://{{ keycloak_host }}:{{ keycloak_http_port + ( keycloak_jboss_port_offset | default(0) ) }}"
description: "URL for configuration rest calls"
type: "str"
keycloak_management_url:
# line 15 of keycloak_realm/vars/main.yml
default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}"
default: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + ( keycloak_jboss_port_offset | default(0) ) }}"
description: "URL for management console rest calls"
type: "str"
downstream:
options:
sso_version:
default: "7.5.0"
default: "7.6.0"
description: "Red Hat Single Sign-On version"
type: "str"
sso_dest:
@@ -106,10 +106,30 @@ argument_specs:
description: "Installation path for Red Hat SSO"
type: "str"
sso_apply_patches:
default: False
default: false
description: "Install Red Hat SSO most recent cumulative patch"
type: "bool"
sso_enable:
default: True
default: true
description: "Enable Red Hat Single Sign-on installation"
type: "str"
rhbk_version:
default: "22.0.6"
description: "Red Hat Build of Keycloak version"
type: "str"
rhbk_archive:
default: "rhbk-{{ rhbk_version }}.zip"
description: "Red Hat Build of Keycloak install archive filename"
type: "str"
rhbk_dest:
default: "/opt/rhbk"
description: "Root installation directory"
type: "str"
rhbk_installdir:
default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version.split('.')[0] }}.{{ rhbk_version.split('.')[1] }}"
description: "Installation path for Red Hat Build of Keycloak"
type: "str"
rhbk_enable:
default: true
description: "Enable Red Hat Build of Keycloak installation"
type: "str"

View File

@@ -8,12 +8,12 @@ galaxy_info:
license: Apache License 2.0
min_ansible_version: "2.9"
min_ansible_version: "2.14"
platforms:
- name: EL
versions:
- 8
- name: EL
versions:
- "8"
galaxy_tags:
- keycloak

View File

@@ -4,7 +4,7 @@
url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no
validate_certs: false
no_log: "{{ keycloak_no_log | default('True') }}"
register: keycloak_auth_response
until: keycloak_auth_response.status == 200
@@ -28,7 +28,7 @@
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms"
method: POST
body: "{{ lookup('template', 'realm.json.j2') }}"
validate_certs: no
validate_certs: false
body_format: json
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
@@ -59,7 +59,7 @@
- item.name is defined and item.name | length > 0
- (item.client_id is defined and item.client_id | length > 0) or (item.id is defined and item.id | length > 0)
fail_msg: "For each keycloak client, attributes `name` and either `id` or `client_id` is required"
quiet: True
quiet: true
loop: "{{ keycloak_clients | flatten }}"
loop_control:
label: "{{ item.name | default('unnamed client') }}"

View File

@@ -2,7 +2,7 @@
- name: "Check if User Already Exists"
ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}"
validate_certs: no
validate_certs: false
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_user_search_result
@@ -18,7 +18,7 @@
email: "{{ user.email | default(omit) }}"
firstName: "{{ user.firstName | default(omit) }}"
lastName: "{{ user.lastName | default(omit) }}"
validate_certs: no
validate_certs: false
body_format: json
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
@@ -28,7 +28,7 @@
- name: "Get User"
ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}"
validate_certs: no
validate_certs: false
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_user
@@ -41,7 +41,7 @@
type: password
temporary: false
value: "{{ user.password }}"
validate_certs: no
validate_certs: false
body_format: json
status_code:
- 200

View File

@@ -31,7 +31,7 @@
containerId: "{{ item.containerId }}"
name: "{{ item.name }}"
composite: "{{ item.composite }}"
validate_certs: False
validate_certs: false
body_format: json
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"

View File

@@ -3,7 +3,7 @@
ansible.builtin.uri:
url: "{{ keycloak_url }}{{ keycloak_context }}/admin/realms/{{ keycloak_realm }}/users?username={{ user.username }}"
headers:
validate_certs: no
validate_certs: false
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_user
@@ -12,7 +12,7 @@
url: "{{ keycloak_url }}{{ keycloak_context }}/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id={{ keycloak_auth_client }}&username={{ keycloak_admin_user }}&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no
validate_certs: false
register: keycloak_auth_response
no_log: "{{ keycloak_no_log | default('True') }}"
until: keycloak_auth_response.status == 200

View File

@@ -5,5 +5,5 @@
keycloak_realm:
# other settings
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}"
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port + (keycloak_jboss_port_offset | default(0)) }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port + (keycloak_jboss_port_offset | default(0)) }}"