Compare commits

..

2 Commits

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

View File

@@ -28,16 +28,14 @@ warn_list:
- name[casing] - name[casing]
- fqcn[action] - fqcn[action]
- schema[meta] - schema[meta]
- var-naming[no-role-prefix]
- key-order[task] - key-order[task]
- blocked_modules - blocked_modules
- run-once[task]
skip_list: skip_list:
- vars_should_not_be_used - vars_should_not_be_used
- file_is_small_enough - file_is_small_enough
- file_has_valid_name
- name[template] - name[template]
- var-naming[no-role-prefix]
use_default_rules: true use_default_rules: true
parseable: true parseable: true

View File

@@ -5,7 +5,6 @@ on:
branches: branches:
- main - main
pull_request: pull_request:
workflow_dispatch:
schedule: schedule:
- cron: '15 6 * * *' - cron: '15 6 * * *'
@@ -16,4 +15,4 @@ jobs:
with: with:
fqcn: 'middleware_automation/keycloak' fqcn: 'middleware_automation/keycloak'
molecule_tests: >- molecule_tests: >-
[ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode", "quarkus_upgrade", "debian", "quarkus_ha" ] [ "default", "overridexml", "https_revproxy", "quarkus", "quarkus-devmode" ]

View File

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

View File

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

View File

@@ -1,26 +0,0 @@
name: Collect traffic stats
on:
schedule:
- cron: "51 23 * * 0"
workflow_dispatch:
jobs:
traffic:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: "gh-pages"
- name: GitHub traffic
uses: sangonzal/repository-traffic-action@v.0.1.6
env:
TRAFFIC_ACTION_TOKEN: ${{ secrets.TRIGGERING_PAT }}
- name: Commit changes
uses: EndBug/add-and-commit@v4
with:
author_name: Ansible Middleware
message: "GitHub traffic"
add: "./traffic/*"
ref: "gh-pages"

2
.gitignore vendored
View File

@@ -12,5 +12,3 @@ docs/_build/
*.retry *.retry
changelogs/.plugin-cache.yaml changelogs/.plugin-cache.yaml
*.pem *.pem
*.key
*.p12

View File

@@ -15,8 +15,7 @@ rules:
commas: commas:
max-spaces-after: -1 max-spaces-after: -1
level: error level: error
comments: comments: disable
min-spaces-from-content: 1
comments-indentation: disable comments-indentation: disable
document-start: disable document-start: disable
empty-lines: empty-lines:
@@ -31,8 +30,4 @@ rules:
new-lines: new-lines:
type: unix type: unix
trailing-spaces: disable trailing-spaces: disable
truthy: disable truthy: disable
octal-values:
forbid-implicit-octal: true
forbid-explicit-octal: true

View File

@@ -6,131 +6,6 @@ middleware\_automation.keycloak Release Notes
This changelog describes changes after version 0.2.6. This changelog describes changes after version 0.2.6.
v2.4.2
======
Minor Changes
-------------
- New parameter ``keycloak_quarkus_download_path`` `#239 <https://github.com/ansible-middleware/keycloak/pull/239>`_
Bugfixes
--------
- Add wait_for_port number parameter `#237 <https://github.com/ansible-middleware/keycloak/pull/237>`_
v2.4.1
======
Release Summary
---------------
Internal release, documentation or test changes only.
v2.4.0
======
Major Changes
-------------
- Enable by default health check on restart `#234 <https://github.com/ansible-middleware/keycloak/pull/234>`_
- Update minimum ansible-core version > 2.15 `#232 <https://github.com/ansible-middleware/keycloak/pull/232>`_
v2.3.0
======
Major Changes
-------------
- Allow for custom providers hosted on maven repositories `#223 <https://github.com/ansible-middleware/keycloak/pull/223>`_
- Restart handler strategy behaviour `#231 <https://github.com/ansible-middleware/keycloak/pull/231>`_
Minor Changes
-------------
- Add support for policy files `#225 <https://github.com/ansible-middleware/keycloak/pull/225>`_
- Allow to add extra custom env vars in sysconfig file `#229 <https://github.com/ansible-middleware/keycloak/pull/229>`_
- Download from alternate URL with optional http authentication `#220 <https://github.com/ansible-middleware/keycloak/pull/220>`_
- Update Keycloak to version 24.0.4 `#218 <https://github.com/ansible-middleware/keycloak/pull/218>`_
- ``proxy-header`` enhancement `#227 <https://github.com/ansible-middleware/keycloak/pull/227>`_
Bugfixes
--------
- ``kc.sh build`` uses configured jdk `#211 <https://github.com/ansible-middleware/keycloak/pull/211>`_
v2.2.2
======
Minor Changes
-------------
- Copying of key material for TLS configuration `#210 <https://github.com/ansible-middleware/keycloak/pull/210>`_
- Validate certs parameter for JDBC driver downloads `#207 <https://github.com/ansible-middleware/keycloak/pull/207>`_
Bugfixes
--------
- Turn off controller privilege escalation `#209 <https://github.com/ansible-middleware/keycloak/pull/209>`_
v2.2.1
======
Release Summary
---------------
Internal release, documentation or test changes only.
Bugfixes
--------
- JDBC provider: fix clause in argument validation `#204 <https://github.com/ansible-middleware/keycloak/pull/204>`_
v2.2.0
======
Major Changes
-------------
- Support java keystore for configuration of sensitive options `#189 <https://github.com/ansible-middleware/keycloak/pull/189>`_
Minor Changes
-------------
- Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 <https://github.com/ansible-middleware/keycloak/pull/199>`_
- Customize jdbc driver downloads, optional authentication `#202 <https://github.com/ansible-middleware/keycloak/pull/202>`_
- Keystore-based vault SPI configuration `#196 <https://github.com/ansible-middleware/keycloak/pull/196>`_
- New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 <https://github.com/ansible-middleware/keycloak/pull/195>`_
- Providers config and custom providers `#201 <https://github.com/ansible-middleware/keycloak/pull/201>`_
- Remove administrator credentials from files once keycloak is bootstrapped `#197 <https://github.com/ansible-middleware/keycloak/pull/197>`_
- Update keycloak to 24.0 `#194 <https://github.com/ansible-middleware/keycloak/pull/194>`_
v2.1.2
======
Release Summary
---------------
Internal release, documentation or test changes only.
v2.1.1
======
Minor Changes
-------------
- Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 <https://github.com/ansible-middleware/keycloak/pull/187>`_
- Debian/Ubuntu compatibility `#178 <https://github.com/ansible-middleware/keycloak/pull/178>`_
- Use ``keycloak_realm`` as default for sub-entities `#180 <https://github.com/ansible-middleware/keycloak/pull/180>`_
Bugfixes
--------
- Fix permissions on controller-side downloaded artifacts `#184 <https://github.com/ansible-middleware/keycloak/pull/184>`_
- JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186 <https://github.com/ansible-middleware/keycloak/pull/186>`_
- Unrelax configuration file permissions `#191 <https://github.com/ansible-middleware/keycloak/pull/191>`_
- Utilize comment filter for ``ansible_managed`` annotations `#176 <https://github.com/ansible-middleware/keycloak/pull/176>`_
v2.1.0 v2.1.0
====== ======
@@ -379,11 +254,6 @@ Minor Changes
v1.0.4 v1.0.4
====== ======
Release Summary
---------------
Internal release, documentation or test changes only.
v1.0.3 v1.0.3
====== ======

View File

@@ -6,13 +6,12 @@
> **_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.** > **_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 --> <!--end build_status -->
<!--start description -->
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). 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).
<!--end description -->
<!--start requires_ansible--> <!--start requires_ansible-->
## Ansible version compatibility ## Ansible version compatibility
This collection has been tested against following Ansible versions: **>=2.15.0**. 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. 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--> <!--end requires_ansible-->
@@ -40,7 +39,6 @@ collections:
The keycloak collection also depends on the following python packages to be present on the controller host: The keycloak collection also depends on the following python packages to be present on the controller host:
* netaddr * netaddr
* lxml
A requirement file is provided to install: A requirement file is provided to install:
@@ -102,7 +100,7 @@ ansible-playbook -i <ansible_hosts> -e @rhn-creds.yml playbooks/keycloak.yml -e
localhost ansible_connection=local localhost ansible_connection=local
``` ```
Note: when deploying clustered configurations, all hosts belonging to the cluster must be present in `ansible_play_batch`; ie. they must be targeted by the same ansible-playbook execution. Note: when deploying clustered configurations, all hosts belonging to the cluster must be present in ansible_play_batch; ie. they must be targeted by the same ansible-playbook execution.
## Configuration ## Configuration

View File

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

View File

@@ -59,10 +59,6 @@ releases:
- 31.yaml - 31.yaml
release_date: '2022-05-09' release_date: '2022-05-09'
1.0.4: 1.0.4:
changes:
release_summary: 'Internal release, documentation or test changes only.
'
release_date: '2022-05-11' release_date: '2022-05-11'
1.0.5: 1.0.5:
changes: changes:
@@ -423,184 +419,3 @@ releases:
- 167.yaml - 167.yaml
- 171.yaml - 171.yaml
release_date: '2024-02-28' release_date: '2024-02-28'
2.1.1:
changes:
bugfixes:
- 'Fix permissions on controller-side downloaded artifacts `#184 <https://github.com/ansible-middleware/keycloak/pull/184>`_
'
- 'JVM args moved to ``JAVA_OPTS`` envvar (instead of JAVA_OPTS_APPEND) `#186
<https://github.com/ansible-middleware/keycloak/pull/186>`_
'
- 'Unrelax configuration file permissions `#191 <https://github.com/ansible-middleware/keycloak/pull/191>`_
'
- 'Utilize comment filter for ``ansible_managed`` annotations `#176 <https://github.com/ansible-middleware/keycloak/pull/176>`_
'
minor_changes:
- 'Add reverse ``proxy_headers`` config, supersedes ``proxy_mode`` `#187 <https://github.com/ansible-middleware/keycloak/pull/187>`_
'
- 'Debian/Ubuntu compatibility `#178 <https://github.com/ansible-middleware/keycloak/pull/178>`_
'
- 'Use ``keycloak_realm`` as default for sub-entities `#180 <https://github.com/ansible-middleware/keycloak/pull/180>`_
'
fragments:
- 176.yaml
- 178.yaml
- 180.yaml
- 184.yaml
- 186.yaml
- 187.yaml
- 191.yaml
release_date: '2024-04-17'
2.1.2:
changes:
release_summary: 'Internal release, documentation or test changes only.
'
release_date: '2024-04-17'
2.2.0:
changes:
major_changes:
- 'Support java keystore for configuration of sensitive options `#189 <https://github.com/ansible-middleware/keycloak/pull/189>`_
'
minor_changes:
- 'Add ``wait_for_port`` and ``wait_for_log`` systemd unit logic `#199 <https://github.com/ansible-middleware/keycloak/pull/199>`_
'
- 'Customize jdbc driver downloads, optional authentication `#202 <https://github.com/ansible-middleware/keycloak/pull/202>`_
'
- 'Keystore-based vault SPI configuration `#196 <https://github.com/ansible-middleware/keycloak/pull/196>`_
'
- 'New ``keycloak_quarkus_hostname_strict_https`` parameter `#195 <https://github.com/ansible-middleware/keycloak/pull/195>`_
'
- 'Providers config and custom providers `#201 <https://github.com/ansible-middleware/keycloak/pull/201>`_
'
- 'Remove administrator credentials from files once keycloak is bootstrapped
`#197 <https://github.com/ansible-middleware/keycloak/pull/197>`_
'
- 'Update keycloak to 24.0 `#194 <https://github.com/ansible-middleware/keycloak/pull/194>`_
'
fragments:
- 189.yaml
- 194.yaml
- 195.yaml
- 196.yaml
- 197.yaml
- 199.yaml
- 201.yaml
- 202.yaml
release_date: '2024-05-01'
2.2.1:
changes:
bugfixes:
- 'JDBC provider: fix clause in argument validation `#204 <https://github.com/ansible-middleware/keycloak/pull/204>`_
'
release_summary: Internal release, documentation or test changes only.
fragments:
- 204.yaml
- v2.2.1-devel_summary.yaml
release_date: '2024-05-02'
2.2.2:
changes:
bugfixes:
- 'Turn off controller privilege escalation `#209 <https://github.com/ansible-middleware/keycloak/pull/209>`_
'
minor_changes:
- 'Copying of key material for TLS configuration `#210 <https://github.com/ansible-middleware/keycloak/pull/210>`_
'
- 'Validate certs parameter for JDBC driver downloads `#207 <https://github.com/ansible-middleware/keycloak/pull/207>`_
'
fragments:
- 207.yaml
- 209.yaml
- 210.yaml
release_date: '2024-05-06'
2.3.0:
changes:
bugfixes:
- '``kc.sh build`` uses configured jdk `#211 <https://github.com/ansible-middleware/keycloak/pull/211>`_
'
major_changes:
- 'Allow for custom providers hosted on maven repositories `#223 <https://github.com/ansible-middleware/keycloak/pull/223>`_
'
- 'Restart handler strategy behaviour `#231 <https://github.com/ansible-middleware/keycloak/pull/231>`_
'
minor_changes:
- 'Add support for policy files `#225 <https://github.com/ansible-middleware/keycloak/pull/225>`_
'
- 'Allow to add extra custom env vars in sysconfig file `#229 <https://github.com/ansible-middleware/keycloak/pull/229>`_
'
- 'Download from alternate URL with optional http authentication `#220 <https://github.com/ansible-middleware/keycloak/pull/220>`_
'
- 'Update Keycloak to version 24.0.4 `#218 <https://github.com/ansible-middleware/keycloak/pull/218>`_
'
- '``proxy-header`` enhancement `#227 <https://github.com/ansible-middleware/keycloak/pull/227>`_
'
fragments:
- 211.yaml
- 218.yaml
- 220.yaml
- 223.yaml
- 225.yaml
- 227.yaml
- 229.yaml
- 231.yaml
release_date: '2024-05-20'
2.4.0:
changes:
major_changes:
- 'Enable by default health check on restart `#234 <https://github.com/ansible-middleware/keycloak/pull/234>`_
'
- 'Update minimum ansible-core version > 2.15 `#232 <https://github.com/ansible-middleware/keycloak/pull/232>`_
'
fragments:
- 232.yaml
- 234.yaml
release_date: '2024-06-04'
2.4.1:
changes:
release_summary: Internal release, documentation or test changes only.
fragments:
- v2.4.1-devel_summary.yaml
release_date: '2024-07-02'
2.4.2:
changes:
bugfixes:
- 'Add wait_for_port number parameter `#237 <https://github.com/ansible-middleware/keycloak/pull/237>`_
'
minor_changes:
- 'New parameter ``keycloak_quarkus_download_path`` `#239 <https://github.com/ansible-middleware/keycloak/pull/239>`_
'
fragments:
- 237.yaml
- 239.yaml
release_date: '2024-09-26'

View File

@@ -11,22 +11,22 @@ notesdir: fragments
prelude_section_name: release_summary prelude_section_name: release_summary
prelude_section_title: Release Summary prelude_section_title: Release Summary
sections: sections:
- - major_changes - - major_changes
- Major Changes - Major Changes
- - minor_changes - - minor_changes
- Minor Changes - Minor Changes
- - breaking_changes - - breaking_changes
- Breaking Changes / Porting Guide - Breaking Changes / Porting Guide
- - deprecated_features - - deprecated_features
- Deprecated Features - Deprecated Features
- - removed_features - - removed_features
- Removed Features - Removed Features
- - security_fixes - - security_fixes
- Security Fixes - Security Fixes
- - bugfixes - - bugfixes
- Bugfixes - Bugfixes
- - known_issues - - known_issues
- Known Issues - Known Issues
title: middleware_automation.keycloak title: middleware_automation.keycloak
trivial_section_name: trivial trivial_section_name: trivial
use_fqcn: true use_fqcn: true

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
--- ---
namespace: middleware_automation namespace: middleware_automation
name: keycloak name: keycloak
version: "2.4.2" version: "2.1.1"
readme: README.md readme: README.md
authors: authors:
- Romain Pelisse <rpelisse@redhat.com> - Romain Pelisse <rpelisse@redhat.com>
@@ -26,7 +26,7 @@ tags:
- middleware - middleware
- a4mw - a4mw
dependencies: dependencies:
"middleware_automation.common": ">=1.2.1" "middleware_automation.common": ">=1.1.0"
"ansible.posix": ">=1.4.0" "ansible.posix": ">=1.4.0"
repository: https://github.com/ansible-middleware/keycloak repository: https://github.com/ansible-middleware/keycloak
documentation: https://ansible-middleware.github.io/keycloak documentation: https://ansible-middleware.github.io/keycloak
@@ -35,6 +35,7 @@ issues: https://github.com/ansible-middleware/keycloak/issues
build_ignore: build_ignore:
- .gitignore - .gitignore
- .github - .github
- .ansible-lint
- .yamllint - .yamllint
- '*.tar.gz' - '*.tar.gz'
- '*.zip' - '*.zip'

View File

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

View File

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

View File

@@ -1,48 +0,0 @@
---
driver:
name: docker
platforms:
- name: instance
image: ghcr.io/hspaans/molecule-containers:debian-11
pre_build_image: true
privileged: true
port_bindings:
- "8080/tcp"
- "8443/tcp"
- "8009/tcp"
cgroupns_mode: host
command: "/lib/systemd/systemd"
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
provisioner:
name: ansible
config_options:
defaults:
interpreter_python: auto_silent
ssh_connection:
pipelining: false
playbooks:
prepare: prepare.yml
converge: converge.yml
verify: verify.yml
inventory:
host_vars:
localhost:
ansible_python_interpreter: /usr/bin/python3
env:
ANSIBLE_FORCE_COLOR: "true"
ANSIBLE_REMOTE_TMP: /tmp/.ansible/tmp
verifier:
name: ansible
scenario:
test_sequence:
- cleanup
- destroy
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy

View File

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

View File

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

View File

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

View File

@@ -1,47 +1,62 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_quarkus_host: instance keycloak_jvm_package: java-11-openjdk-headless
keycloak_quarkus_log: file keycloak_modcluster_enabled: True
keycloak_quarkus_log_level: debug keycloak_modcluster_urls:
keycloak_quarkus_log_target: /tmp/keycloak - host: myhost1
keycloak_quarkus_start_dev: True port: 16667
keycloak_quarkus_proxy_mode: none - host: myhost2
keycloak_quarkus_offline_install: true port: 16668
keycloak_quarkus_download_path: /tmp/keycloak/ keycloak_jboss_port_offset: 10
keycloak_log_target: /tmp/keycloak
roles: roles:
- role: keycloak_quarkus - role: keycloak
- role: keycloak_realm tasks:
keycloak_context: '' - name: Keycloak Realm Role
keycloak_client_default_roles: ansible.builtin.include_role:
- TestRoleAdmin name: keycloak_realm
- TestRoleUser vars:
keycloak_client_users: keycloak_client_default_roles:
- username: TestUser - TestRoleAdmin
password: password - TestRoleUser
client_roles: keycloak_client_users:
- client: TestClient - username: TestUser
role: TestRoleUser password: password
realm: "{{ keycloak_realm }}" client_roles:
- username: TestAdmin - client: TestClient
password: password role: TestRoleUser
client_roles: realm: "{{ keycloak_realm }}"
- client: TestClient - username: TestAdmin
role: TestRoleUser password: password
realm: "{{ keycloak_realm }}" client_roles:
- client: TestClient - client: TestClient
role: TestRoleAdmin role: TestRoleUser
realm: "{{ keycloak_realm }}" realm: "{{ keycloak_realm }}"
keycloak_realm: TestRealm - client: TestClient
keycloak_clients: role: TestRoleAdmin
- name: TestClient realm: "{{ keycloak_realm }}"
roles: "{{ keycloak_client_default_roles }}" keycloak_realm: TestRealm
realm: "{{ keycloak_realm }}" keycloak_clients:
public_client: "{{ keycloak_client_public }}" - name: TestClient
web_origins: "{{ keycloak_client_web_origins }}" roles: "{{ keycloak_client_default_roles }}"
users: "{{ keycloak_client_users }}" realm: "{{ keycloak_realm }}"
client_id: TestClient public_client: "{{ keycloak_client_public }}"
web_origins: "{{ keycloak_client_web_origins }}"
users: "{{ keycloak_client_users }}"
client_id: TestClient
attributes:
post.logout.redirect.uris: '/public/logout'
pre_tasks:
- name: "Retrieve assets server from env"
ansible.builtin.set_fact:
assets_server: "{{ lookup('env','MIDDLEWARE_DOWNLOAD_RELEASE_SERVER_URL') }}"
- name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact:
sso_offline_install: True
when:
- assets_server is defined
- assets_server | length > 0

View File

@@ -12,18 +12,11 @@
- "{{ assets_server }}/sso/7.6.0/rh-sso-7.6.0-server-dist.zip" - "{{ 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" - "{{ assets_server }}/sso/7.6.1/rh-sso-7.6.1-patch.zip"
- name: Create controller directory for downloads - name: Install JDK8
ansible.builtin.file: # noqa risky-file-permissions delegated, uses controller host user become: yes
path: /tmp/keycloak ansible.builtin.yum:
state: directory name:
mode: '0750' - java-1.8.0-openjdk
delegate_to: localhost state: present
run_once: true
- name: Download keycloak archive to controller directory
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: https://github.com/keycloak/keycloak/releases/download/24.0.4/keycloak-24.0.4.zip
dest: /tmp/keycloak
mode: '0640'
delegate_to: localhost
run_once: true

View File

@@ -3,7 +3,10 @@
hosts: all hosts: all
vars: vars:
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_uri: "http://localhost:8080" keycloak_jvm_package: java-11-openjdk-headless
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: tasks:
- name: Populate service facts - name: Populate service facts
ansible.builtin.service_facts: ansible.builtin.service_facts:
@@ -12,9 +15,16 @@
that: that:
- ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled" - ansible_facts.services["keycloak.service"]["status"] == "enabled"
- name: Verify we are running on requested jvm # noqa blocked_modules command-instead-of-module
ansible.builtin.shell: |
set -o pipefail
ps -ef | grep '/etc/alternatives/jre_11/' | grep -v grep
args:
executable: /bin/bash
changed_when: no
- name: Verify token api call - name: Verify token api call
ansible.builtin.uri: ansible.builtin.uri:
url: "{{ keycloak_uri }}/realms/master/protocol/openid-connect/token" url: "{{ keycloak_uri }}/auth/realms/master/protocol/openid-connect/token"
method: POST method: POST
body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password" body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no validate_certs: no
@@ -22,3 +32,58 @@
until: keycloak_auth_response.status == 200 until: keycloak_auth_response.status == 200
retries: 2 retries: 2
delay: 2 delay: 2
- name: Fetch openid-connect config
ansible.builtin.uri:
url: "{{ keycloak_uri }}/auth/realms/TestRealm/.well-known/openid-configuration"
method: GET
validate_certs: no
status_code: 200
register: keycloak_openid_config
- name: Verify expected config
ansible.builtin.assert:
that:
- keycloak_openid_config.json.registration_endpoint == 'http://localhost:8080/auth/realms/TestRealm/clients-registrations/openid-connect'
- name: Get test realm clients
ansible.builtin.uri:
url: "{{ keycloak_uri }}/auth/admin/realms/TestRealm/clients"
method: GET
validate_certs: no
status_code: 200
headers:
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_query_clients
- name: Verify expected config
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

@@ -1,8 +1,7 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm keycloak_realm: TestRealm

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,8 +1,7 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm keycloak_realm: TestRealm

View File

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

View File

@@ -1,53 +1,16 @@
--- ---
- name: Converge - name: Converge
hosts: all hosts: all
vars: vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_admin_pass: "remembertochangeme" keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme" keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm keycloak_realm: TestRealm
keycloak_quarkus_host: instance keycloak_quarkus_host: instance
keycloak_quarkus_log: file keycloak_quarkus_log: file
keycloak_quarkus_log_level: debug # needed for the verify step keycloak_quarkus_https_key_file_enabled: True
keycloak_quarkus_https_key_file_enabled: true keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem"
keycloak_quarkus_key_file_copy_enabled: true keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem"
keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}"
keycloak_quarkus_cert_file_copy_enabled: true
keycloak_quarkus_cert_file_src: cert.pem
keycloak_quarkus_log_target: /tmp/keycloak keycloak_quarkus_log_target: /tmp/keycloak
keycloak_quarkus_ks_vault_enabled: true
keycloak_quarkus_ks_vault_file: "/opt/keycloak/vault/keystore.p12"
keycloak_quarkus_ks_vault_pass: keystorepassword
keycloak_quarkus_systemd_wait_for_port: true
keycloak_quarkus_systemd_wait_for_timeout: 20
keycloak_quarkus_systemd_wait_for_delay: 2
keycloak_quarkus_systemd_wait_for_log: true
keycloak_quarkus_providers:
- id: http-client
spi: connections
default: true
restart: true
properties:
- key: default-connection-pool-size
value: 10
- id: spid-saml
url: https://github.com/italia/spid-keycloak-provider/releases/download/24.0.2/spid-provider.jar
- id: keycloak-kerberos-federation
maven:
repository_url: https://repo1.maven.org/maven2/ # https://mvnrepository.com/artifact/org.keycloak/keycloak-kerberos-federation/24.0.4
group_id: org.keycloak
artifact_id: keycloak-kerberos-federation
version: 24.0.4 # optional
# username: myUser # optional
# password: myPAT # optional
# - id: my-static-theme
# local_path: /tmp/my-static-theme.jar
keycloak_quarkus_policies:
- name: "xato-net-10-million-passwords.txt"
url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt"
- name: "xato-net-10-million-passwords-10.txt"
url: "https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords-10.txt"
type: password-blacklists
roles: roles:
- role: keycloak_quarkus - role: keycloak_quarkus
- role: keycloak_realm - role: keycloak_realm

View File

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

View File

@@ -1,8 +1,6 @@
--- ---
- name: Verify - name: Verify
hosts: all hosts: all
vars:
keycloak_admin_password: "remembertochangeme"
tasks: tasks:
- name: Populate service facts - name: Populate service facts
ansible.builtin.service_facts: ansible.builtin.service_facts:
@@ -12,7 +10,6 @@
that: that:
- ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled" - ansible_facts.services["keycloak.service"]["status"] == "enabled"
fail_msg: "Service not running"
- name: Set internal envvar - name: Set internal envvar
ansible.builtin.set_fact: ansible.builtin.set_fact:
@@ -43,7 +40,7 @@
- name: Check log folder - name: Check log folder
ansible.builtin.stat: ansible.builtin.stat:
path: /tmp/keycloak path: "/tmp/keycloak"
register: keycloak_log_folder register: keycloak_log_folder
- name: Check that keycloak log folder exists and is a link - name: Check that keycloak log folder exists and is a link
@@ -52,12 +49,10 @@
- keycloak_log_folder.stat.exists - keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir - not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk - keycloak_log_folder.stat.islnk
fail_msg: "Service log symlink not correctly created"
- name: Check log file - name: Check log file
become: true
ansible.builtin.stat: ansible.builtin.stat:
path: /tmp/keycloak/keycloak.log path: "/tmp/keycloak/keycloak.log"
register: keycloak_log_file register: keycloak_log_file
- name: Check if keycloak file exists - name: Check if keycloak file exists
@@ -67,9 +62,8 @@
- not keycloak_log_file.stat.isdir - not keycloak_log_file.stat.isdir
- name: Check default log folder - name: Check default log folder
become: yes
ansible.builtin.stat: ansible.builtin.stat:
path: /var/log/keycloak path: "/var/log/keycloak"
register: keycloak_default_log_folder register: keycloak_default_log_folder
failed_when: false failed_when: false
@@ -77,51 +71,3 @@
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- not keycloak_default_log_folder.stat.exists - not keycloak_default_log_folder.stat.exists
- name: Verify vault SPI in logfile
become: true
ansible.builtin.shell: |
set -o pipefail
zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip
changed_when: false
failed_when: slurped_log.rc != 0
register: slurped_log
- name: Verify token api call
ansible.builtin.uri:
url: "https://instance:8443/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id=admin-cli&username=admin&password={{ keycloak_admin_password }}&grant_type=password"
validate_certs: no
register: keycloak_auth_response
until: keycloak_auth_response.status == 200
retries: 2
delay: 2
- name: "Get Clients"
ansible.builtin.uri:
url: "https://instance:8443/admin/realms/TestRealm/clients"
headers:
validate_certs: false
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_clients
- name: Get client uuid
ansible.builtin.set_fact:
keycloak_client_uuid: "{{ ((keycloak_clients.json | selectattr('clientId', '==', 'TestClient')) | first).id }}"
- name: "Get Client {{ keycloak_client_uuid }}"
ansible.builtin.uri:
url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}"
headers:
validate_certs: false
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_test_client
- name: "Get Client roles"
ansible.builtin.uri:
url: "https://instance:8443/admin/realms/TestRealm/clients/{{ keycloak_client_uuid }}/roles"
headers:
validate_certs: false
Authorization: "Bearer {{ keycloak_auth_response.json.access_token }}"
register: keycloak_test_client_roles

View File

@@ -1,30 +0,0 @@
---
- name: Converge
hosts: keycloak
vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_admin_password: "remembertochangeme"
keycloak_realm: TestRealm
keycloak_quarkus_host: "{{ inventory_hostname }}"
keycloak_quarkus_log: file
keycloak_quarkus_log_level: info
keycloak_quarkus_https_key_file_enabled: true
keycloak_quarkus_key_file_copy_enabled: true
keycloak_quarkus_key_content: "{{ lookup('file', inventory_hostname + '.key') }}"
keycloak_quarkus_cert_file_copy_enabled: true
keycloak_quarkus_cert_file_src: "{{ inventory_hostname }}.pem"
keycloak_quarkus_ks_vault_enabled: true
keycloak_quarkus_ks_vault_file: "/opt/keycloak/vault/keystore.p12"
keycloak_quarkus_ks_vault_pass: keystorepassword
keycloak_quarkus_systemd_wait_for_port: true
keycloak_quarkus_systemd_wait_for_timeout: 20
keycloak_quarkus_systemd_wait_for_delay: 2
keycloak_quarkus_systemd_wait_for_log: true
keycloak_quarkus_ha_enabled: true
keycloak_quarkus_restart_strategy: restart/serial.yml
keycloak_quarkus_db_user: keycloak
keycloak_quarkus_db_pass: mysecretpass
keycloak_quarkus_jdbc_url: jdbc:postgresql://postgres:5432/keycloak
roles:
- role: keycloak_quarkus

View File

@@ -1,79 +0,0 @@
---
driver:
name: docker
platforms:
- name: instance1
image: registry.access.redhat.com/ubi9/ubi-init:latest
pre_build_image: true
privileged: true
command: "/usr/sbin/init"
groups:
- keycloak
networks:
- name: rhbk
port_bindings:
- "8080/tcp"
- "8443/tcp"
- name: instance2
image: registry.access.redhat.com/ubi9/ubi-init:latest
pre_build_image: true
privileged: true
command: "/usr/sbin/init"
groups:
- keycloak
networks:
- name: rhbk
port_bindings:
- "8080/tcp"
- "8443/tcp"
- name: postgres
image: ubuntu/postgres:14-22.04_beta
pre_build_image: true
privileged: true
command: postgres
groups:
- database
networks:
- name: rhbk
port_bindings:
- "5432/tcp"
mounts:
- type: bind
target: /etc/postgresql/postgresql.conf
source: ${PWD}/molecule/quarkus_ha/postgresql/postgresql.conf
env:
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: mysecretpass
POSTGRES_DB: keycloak
POSTGRES_HOST_AUTH_METHOD: trust
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

@@ -1,750 +0,0 @@
# -----------------------------
# PostgreSQL configuration file
# -----------------------------
#
# This file consists of lines of the form:
#
# name = value
#
# (The "=" is optional.) Whitespace may be used. Comments are introduced with
# "#" anywhere on a line. The complete list of parameter names and allowed
# values can be found in the PostgreSQL documentation.
#
# The commented-out settings shown in this file represent the default values.
# Re-commenting a setting is NOT sufficient to revert it to the default value;
# you need to reload the server.
#
# This file is read on server startup and when the server receives a SIGHUP
# signal. If you edit the file on a running system, you have to SIGHUP the
# server for the changes to take effect, run "pg_ctl reload", or execute
# "SELECT pg_reload_conf()". Some parameters, which are marked below,
# require a server shutdown and restart to take effect.
#
# Any parameter can also be given as a command-line option to the server, e.g.,
# "postgres -c log_connections=on". Some parameters can be changed at run time
# with the "SET" SQL command.
#
# Memory units: kB = kilobytes Time units: ms = milliseconds
# MB = megabytes s = seconds
# GB = gigabytes min = minutes
# TB = terabytes h = hours
# d = days
#------------------------------------------------------------------------------
# FILE LOCATIONS
#------------------------------------------------------------------------------
# The default values of these variables are driven from the -D command-line
# option or PGDATA environment variable, represented here as ConfigDir.
#data_directory = 'ConfigDir' # use data in another directory
# (change requires restart)
#hba_file = 'ConfigDir/pg_hba.conf' # host-based authentication file
# (change requires restart)
#ident_file = 'ConfigDir/pg_ident.conf' # ident configuration file
# (change requires restart)
# If external_pid_file is not explicitly set, no extra PID file is written.
#external_pid_file = '' # write an extra PID file
# (change requires restart)
#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------
# - Connection Settings -
listen_addresses = '*' # what IP address(es) to listen on;
# comma-separated list of addresses;
# defaults to 'localhost'; use '*' for all
# (change requires restart)
#port = 5432 # (change requires restart)
#max_connections = 100 # (change requires restart)
#superuser_reserved_connections = 3 # (change requires restart)
#unix_socket_directories = '/tmp' # comma-separated list of directories
# (change requires restart)
#unix_socket_group = '' # (change requires restart)
#unix_socket_permissions = 0777 # begin with 0 to use octal notation
# (change requires restart)
#bonjour = off # advertise server via Bonjour
# (change requires restart)
#bonjour_name = '' # defaults to the computer name
# (change requires restart)
# - TCP settings -
# see "man 7 tcp" for details
#tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds;
# 0 selects the system default
#tcp_keepalives_interval = 0 # TCP_KEEPINTVL, in seconds;
# 0 selects the system default
#tcp_keepalives_count = 0 # TCP_KEEPCNT;
# 0 selects the system default
#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds;
# 0 selects the system default
# - Authentication -
#authentication_timeout = 1min # 1s-600s
#password_encryption = md5 # md5 or scram-sha-256
#db_user_namespace = off
# GSSAPI using Kerberos
#krb_server_keyfile = ''
#krb_caseins_users = off
# - SSL -
#ssl = off
#ssl_ca_file = ''
#ssl_cert_file = 'server.crt'
#ssl_crl_file = ''
#ssl_key_file = 'server.key'
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_min_protocol_version = 'TLSv1'
#ssl_max_protocol_version = ''
#ssl_dh_params_file = ''
#ssl_passphrase_command = ''
#ssl_passphrase_command_supports_reload = off
#------------------------------------------------------------------------------
# RESOURCE USAGE (except WAL)
#------------------------------------------------------------------------------
# - Memory -
#shared_buffers = 32MB # min 128kB
# (change requires restart)
#huge_pages = try # on, off, or try
# (change requires restart)
#temp_buffers = 8MB # min 800kB
#max_prepared_transactions = 0 # zero disables the feature
# (change requires restart)
# Caution: it is not advisable to set max_prepared_transactions nonzero unless
# you actively intend to use prepared transactions.
#work_mem = 4MB # min 64kB
#maintenance_work_mem = 64MB # min 1MB
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
#max_stack_depth = 2MB # min 100kB
#shared_memory_type = mmap # the default is the first option
# supported by the operating system:
# mmap
# sysv
# windows
# (change requires restart)
#dynamic_shared_memory_type = posix # the default is the first option
# supported by the operating system:
# posix
# sysv
# windows
# mmap
# (change requires restart)
# - Disk -
#temp_file_limit = -1 # limits per-process temp file space
# in kB, or -1 for no limit
# - Kernel Resources -
#max_files_per_process = 1000 # min 25
# (change requires restart)
# - Cost-Based Vacuum Delay -
#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables)
#vacuum_cost_page_hit = 1 # 0-10000 credits
#vacuum_cost_page_miss = 10 # 0-10000 credits
#vacuum_cost_page_dirty = 20 # 0-10000 credits
#vacuum_cost_limit = 200 # 1-10000 credits
# - Background Writer -
#bgwriter_delay = 200ms # 10-10000ms between rounds
#bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables
#bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round
#bgwriter_flush_after = 0 # measured in pages, 0 disables
# - Asynchronous Behavior -
#effective_io_concurrency = 1 # 1-1000; 0 disables prefetching
#max_worker_processes = 8 # (change requires restart)
#max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
#max_parallel_workers_per_gather = 2 # taken from max_parallel_workers
#parallel_leader_participation = on
#max_parallel_workers = 8 # maximum number of max_worker_processes that
# can be used in parallel operations
#old_snapshot_threshold = -1 # 1min-60d; -1 disables; 0 is immediate
# (change requires restart)
#backend_flush_after = 0 # measured in pages, 0 disables
#------------------------------------------------------------------------------
# WRITE-AHEAD LOG
#------------------------------------------------------------------------------
# - Settings -
#wal_level = replica # minimal, replica, or logical
# (change requires restart)
#fsync = on # flush data to disk for crash safety
# (turning this off can cause
# unrecoverable data corruption)
#synchronous_commit = on # synchronization level;
# off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync # the default is the first option
# supported by the operating system:
# open_datasync
# fdatasync (default on Linux)
# fsync
# fsync_writethrough
# open_sync
#full_page_writes = on # recover from partial page writes
#wal_compression = off # enable compression of full-page writes
#wal_log_hints = off # also do full page writes of non-critical updates
# (change requires restart)
#wal_init_zero = on # zero-fill new WAL files
#wal_recycle = on # recycle WAL files
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
# (change requires restart)
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
#commit_delay = 0 # range 0-100000, in microseconds
#commit_siblings = 5 # range 1-1000
# - Checkpoints -
#checkpoint_timeout = 5min # range 30s-1d
#max_wal_size = 1GB
#min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 0 # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
# - Archiving -
#archive_mode = off # enables archiving; off, on, or always
# (change requires restart)
#archive_command = '' # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
# %f = file name only
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
#archive_timeout = 0 # force a logfile segment switch after this
# number of seconds; 0 disables
# - Archive Recovery -
# These are only used in recovery mode.
#restore_command = '' # command to use to restore an archived logfile segment
# placeholders: %p = path of file to restore
# %f = file name only
# e.g. 'cp /mnt/server/archivedir/%f %p'
# (change requires restart)
#archive_cleanup_command = '' # command to execute at every restartpoint
#recovery_end_command = '' # command to execute at completion of recovery
# - Recovery Target -
# Set these only when performing a targeted recovery.
#recovery_target = '' # 'immediate' to end recovery as soon as a
# consistent state is reached
# (change requires restart)
#recovery_target_name = '' # the named restore point to which recovery will proceed
# (change requires restart)
#recovery_target_time = '' # the time stamp up to which recovery will proceed
# (change requires restart)
#recovery_target_xid = '' # the transaction ID up to which recovery will proceed
# (change requires restart)
#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed
# (change requires restart)
#recovery_target_inclusive = on # Specifies whether to stop:
# just after the specified recovery target (on)
# just before the recovery target (off)
# (change requires restart)
#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID
# (change requires restart)
#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown'
# (change requires restart)
#------------------------------------------------------------------------------
# REPLICATION
#------------------------------------------------------------------------------
# - Sending Servers -
# Set these on the master and on any standby that will send replication data.
#max_wal_senders = 10 # max number of walsender processes
# (change requires restart)
#wal_keep_segments = 0 # in logfile segments; 0 disables
#wal_sender_timeout = 60s # in milliseconds; 0 disables
#max_replication_slots = 10 # max number of replication slots
# (change requires restart)
#track_commit_timestamp = off # collect timestamp of transaction commit
# (change requires restart)
# - Master Server -
# These settings are ignored on a standby server.
#synchronous_standby_names = '' # standby servers that provide sync rep
# method to choose sync standbys, number of sync standbys,
# and comma-separated list of application_name
# from standby(s); '*' = all
#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed
# - Standby Servers -
# These settings are ignored on a master server.
#primary_conninfo = '' # connection string to sending server
# (change requires restart)
#primary_slot_name = '' # replication slot on sending server
# (change requires restart)
#promote_trigger_file = '' # file name whose presence ends recovery
#hot_standby = on # "off" disallows queries during recovery
# (change requires restart)
#max_standby_archive_delay = 30s # max delay before canceling queries
# when reading WAL from archive;
# -1 allows indefinite delay
#max_standby_streaming_delay = 30s # max delay before canceling queries
# when reading streaming WAL;
# -1 allows indefinite delay
#wal_receiver_status_interval = 10s # send replies at least this often
# 0 disables
#hot_standby_feedback = off # send info from standby to prevent
# query conflicts
#wal_receiver_timeout = 60s # time that receiver waits for
# communication from master
# in milliseconds; 0 disables
#wal_retrieve_retry_interval = 5s # time to wait before retrying to
# retrieve WAL after a failed attempt
#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery
# - Subscribers -
# These settings are ignored on a publisher.
#max_logical_replication_workers = 4 # taken from max_worker_processes
# (change requires restart)
#max_sync_workers_per_subscription = 2 # taken from max_logical_replication_workers
#------------------------------------------------------------------------------
# QUERY TUNING
#------------------------------------------------------------------------------
# - Planner Method Configuration -
#enable_bitmapscan = on
#enable_hashagg = on
#enable_hashjoin = on
#enable_indexscan = on
#enable_indexonlyscan = on
#enable_material = on
#enable_mergejoin = on
#enable_nestloop = on
#enable_parallel_append = on
#enable_seqscan = on
#enable_sort = on
#enable_tidscan = on
#enable_partitionwise_join = off
#enable_partitionwise_aggregate = off
#enable_parallel_hash = on
#enable_partition_pruning = on
# - Planner Cost Constants -
#seq_page_cost = 1.0 # measured on an arbitrary scale
#random_page_cost = 4.0 # same scale as above
#cpu_tuple_cost = 0.01 # same scale as above
#cpu_index_tuple_cost = 0.005 # same scale as above
#cpu_operator_cost = 0.0025 # same scale as above
#parallel_tuple_cost = 0.1 # same scale as above
#parallel_setup_cost = 1000.0 # same scale as above
#jit_above_cost = 100000 # perform JIT compilation if available
# and query more expensive than this;
# -1 disables
#jit_inline_above_cost = 500000 # inline small functions if query is
# more expensive than this; -1 disables
#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if
# query is more expensive than this;
# -1 disables
#min_parallel_table_scan_size = 8MB
#min_parallel_index_scan_size = 512kB
#effective_cache_size = 4GB
# - Genetic Query Optimizer -
#geqo = on
#geqo_threshold = 12
#geqo_effort = 5 # range 1-10
#geqo_pool_size = 0 # selects default based on effort
#geqo_generations = 0 # selects default based on effort
#geqo_selection_bias = 2.0 # range 1.5-2.0
#geqo_seed = 0.0 # range 0.0-1.0
# - Other Planner Options -
#default_statistics_target = 100 # range 1-10000
#constraint_exclusion = partition # on, off, or partition
#cursor_tuple_fraction = 0.1 # range 0.0-1.0
#from_collapse_limit = 8
#join_collapse_limit = 8 # 1 disables collapsing of explicit
# JOIN clauses
#force_parallel_mode = off
#jit = on # allow JIT compilation
#plan_cache_mode = auto # auto, force_generic_plan or
# force_custom_plan
#------------------------------------------------------------------------------
# REPORTING AND LOGGING
#------------------------------------------------------------------------------
# - Where to Log -
#log_destination = 'stderr' # Valid values are combinations of
# stderr, csvlog, syslog, and eventlog,
# depending on platform. csvlog
# requires logging_collector to be on.
# This is used when logging to stderr:
#logging_collector = off # Enable capturing of stderr and csvlog
# into log files. Required to be on for
# csvlogs.
# (change requires restart)
# These are only used if logging_collector is on:
#log_directory = 'log' # directory where log files are written,
# can be absolute or relative to PGDATA
#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # log file name pattern,
# can include strftime() escapes
#log_file_mode = 0600 # creation mode for log files,
# begin with 0 to use octal notation
#log_truncate_on_rotation = off # If on, an existing log file with the
# same name as the new log file will be
# truncated rather than appended to.
# But such truncation only occurs on
# time-driven rotation, not on restarts
# or size-driven rotation. Default is
# off, meaning append to existing files
# in all cases.
#log_rotation_age = 1d # Automatic rotation of logfiles will
# happen after that time. 0 disables.
#log_rotation_size = 10MB # Automatic rotation of logfiles will
# happen after that much log output.
# 0 disables.
# These are relevant when logging to syslog:
#syslog_facility = 'LOCAL0'
#syslog_ident = 'postgres'
#syslog_sequence_numbers = on
#syslog_split_messages = on
# This is only relevant when logging to eventlog (win32):
# (change requires restart)
#event_source = 'PostgreSQL'
# - When to Log -
#log_min_messages = warning # values in order of decreasing detail:
# debug5
# debug4
# debug3
# debug2
# debug1
# info
# notice
# warning
# error
# log
# fatal
# panic
#log_min_error_statement = error # values in order of decreasing detail:
# debug5
# debug4
# debug3
# debug2
# debug1
# info
# notice
# warning
# error
# log
# fatal
# panic (effectively off)
#log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements
# and their durations, > 0 logs only
# statements running at least this number
# of milliseconds
#log_transaction_sample_rate = 0.0 # Fraction of transactions whose statements
# are logged regardless of their duration. 1.0 logs all
# statements from all transactions, 0.0 never logs.
# - What to Log -
#debug_print_parse = off
#debug_print_rewritten = off
#debug_print_plan = off
#debug_pretty_print = on
#log_checkpoints = off
#log_connections = off
#log_disconnections = off
#log_duration = off
#log_error_verbosity = default # terse, default, or verbose messages
#log_hostname = off
#log_line_prefix = '%m [%p] ' # special values:
# %a = application name
# %u = user name
# %d = database name
# %r = remote host and port
# %h = remote host
# %p = process ID
# %t = timestamp without milliseconds
# %m = timestamp with milliseconds
# %n = timestamp with milliseconds (as a Unix epoch)
# %i = command tag
# %e = SQL state
# %c = session ID
# %l = session line number
# %s = session start timestamp
# %v = virtual transaction ID
# %x = transaction ID (0 if none)
# %q = stop here in non-session
# processes
# %% = '%'
# e.g. '<%u%%%d> '
#log_lock_waits = off # log lock waits >= deadlock_timeout
#log_statement = 'none' # none, ddl, mod, all
#log_replication_commands = off
#log_temp_files = -1 # log temporary files equal or larger
# than the specified size in kilobytes;
# -1 disables, 0 logs all temp files
#log_timezone = 'GMT'
#------------------------------------------------------------------------------
# PROCESS TITLE
#------------------------------------------------------------------------------
#cluster_name = '' # added to process titles if nonempty
# (change requires restart)
#update_process_title = on
#------------------------------------------------------------------------------
# STATISTICS
#------------------------------------------------------------------------------
# - Query and Index Statistics Collector -
#track_activities = on
#track_counts = on
#track_io_timing = off
#track_functions = none # none, pl, all
#track_activity_query_size = 1024 # (change requires restart)
#stats_temp_directory = 'pg_stat_tmp'
# - Monitoring -
#log_parser_stats = off
#log_planner_stats = off
#log_executor_stats = off
#log_statement_stats = off
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
#autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min # time between autovacuum runs
#autovacuum_vacuum_threshold = 50 # min number of row updates before
# vacuum
#autovacuum_analyze_threshold = 50 # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
# (change requires restart)
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
# before forced vacuum
# (change requires restart)
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
#------------------------------------------------------------------------------
# CLIENT CONNECTION DEFAULTS
#------------------------------------------------------------------------------
# - Statement Behavior -
#client_min_messages = notice # values in order of decreasing detail:
# debug5
# debug4
# debug3
# debug2
# debug1
# log
# notice
# warning
# error
#search_path = '"$user", public' # schema names
#row_security = on
#default_tablespace = '' # a tablespace name, '' uses the default
#temp_tablespaces = '' # a list of tablespace names, '' uses
# only default tablespace
#default_table_access_method = 'heap'
#check_function_bodies = on
#default_transaction_isolation = 'read committed'
#default_transaction_read_only = off
#default_transaction_deferrable = off
#session_replication_role = 'origin'
#statement_timeout = 0 # in milliseconds, 0 is disabled
#lock_timeout = 0 # in milliseconds, 0 is disabled
#idle_in_transaction_session_timeout = 0 # in milliseconds, 0 is disabled
#vacuum_freeze_min_age = 50000000
#vacuum_freeze_table_age = 150000000
#vacuum_multixact_freeze_min_age = 5000000
#vacuum_multixact_freeze_table_age = 150000000
#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples
# before index cleanup, 0 always performs
# index cleanup
#bytea_output = 'hex' # hex, escape
#xmlbinary = 'base64'
#xmloption = 'content'
#gin_fuzzy_search_limit = 0
#gin_pending_list_limit = 4MB
# - Locale and Formatting -
#datestyle = 'iso, mdy'
#intervalstyle = 'postgres'
#timezone = 'GMT'
#timezone_abbreviations = 'Default' # Select the set of available time zone
# abbreviations. Currently, there are
# Default
# Australia (historical usage)
# India
# You can create your own file in
# share/timezonesets/.
#extra_float_digits = 1 # min -15, max 3; any value >0 actually
# selects precise output mode
#client_encoding = sql_ascii # actually, defaults to database
# encoding
# These settings are initialized by initdb, but they can be changed.
#lc_messages = 'C' # locale for system error message
# strings
#lc_monetary = 'C' # locale for monetary formatting
#lc_numeric = 'C' # locale for number formatting
#lc_time = 'C' # locale for time formatting
# default configuration for text search
#default_text_search_config = 'pg_catalog.simple'
# - Shared Library Preloading -
#shared_preload_libraries = '' # (change requires restart)
#local_preload_libraries = ''
#session_preload_libraries = ''
#jit_provider = 'llvmjit' # JIT library to use
# - Other Defaults -
#dynamic_library_path = '$libdir'
#------------------------------------------------------------------------------
# LOCK MANAGEMENT
#------------------------------------------------------------------------------
#deadlock_timeout = 1s
#max_locks_per_transaction = 64 # min 10
# (change requires restart)
#max_pred_locks_per_transaction = 64 # min 10
# (change requires restart)
#max_pred_locks_per_relation = -2 # negative values mean
# (max_pred_locks_per_transaction
# / -max_pred_locks_per_relation) - 1
#max_pred_locks_per_page = 2 # min 0
#------------------------------------------------------------------------------
# VERSION AND PLATFORM COMPATIBILITY
#------------------------------------------------------------------------------
# - Previous PostgreSQL Versions -
#array_nulls = on
#backslash_quote = safe_encoding # on, off, or safe_encoding
#escape_string_warning = on
#lo_compat_privileges = off
#operator_precedence_warning = off
#quote_all_identifiers = off
#standard_conforming_strings = on
#synchronize_seqscans = on
# - Other Platforms and Clients -
#transform_null_equals = off
#------------------------------------------------------------------------------
# ERROR HANDLING
#------------------------------------------------------------------------------
#exit_on_error = off # terminate session on any error?
#restart_after_crash = on # reinitialize after backend crash?
#data_sync_retry = off # retry or panic on failure to fsync
# data?
# (change requires restart)
#------------------------------------------------------------------------------
# CONFIG FILE INCLUDES
#------------------------------------------------------------------------------
# These options allow settings to be loaded from files other than the
# default postgresql.conf. Note that these are directives, not variable
# assignments, so they can usefully be given more than once.
#include_dir = '...' # include files ending in '.conf' from
# a directory, e.g., 'conf.d'
#include_if_exists = '...' # include file only if it exists
#include = '...' # include file
#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
# Add settings for extensions here

View File

@@ -1,44 +0,0 @@
---
- name: Prepare
hosts: keycloak
tasks:
- name: "Display hera_home if defined."
ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}"
- name: "Ensure common prepare phase are set."
ansible.builtin.include_tasks: ../prepare.yml
- name: Create certificate request
ansible.builtin.command: "openssl req -x509 -newkey rsa:4096 -keyout {{ inventory_hostname }}.key -out {{ inventory_hostname }}.pem -sha256 -days 365 -nodes -subj '/CN={{ inventory_hostname }}'"
delegate_to: localhost
changed_when: False
- name: Create vault directory
become: true
ansible.builtin.file:
state: directory
path: "/opt/keycloak/vault"
mode: 0755
- name: Make sure a jre is available (for keytool to prepare keystore)
delegate_to: localhost
ansible.builtin.package:
name: "{{ 'java-17-openjdk-headless' if hera_home | length > 0 else 'openjdk-17-jdk-headless' }}"
state: present
become: true
failed_when: false
- name: Create vault keystore
ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword
delegate_to: localhost
register: keytool_cmd
changed_when: False
failed_when: not 'already exists' in keytool_cmd.stdout and keytool_cmd.rc != 0
- name: Copy certificates and vault
become: true
ansible.builtin.copy:
src: keystore.p12
dest: /opt/keycloak/vault/keystore.p12
mode: 0444

View File

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

View File

@@ -1,29 +0,0 @@
---
- name: Verify
hosts: keycloak
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"
fail_msg: "Service not running"
- name: Set internal envvar
ansible.builtin.set_fact:
hera_home: "{{ lookup('env', 'HERA_HOME') }}"
- name: Check log file
become: true
ansible.builtin.stat:
path: /var/log/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

View File

@@ -1,10 +0,0 @@
---
- name: Converge
hosts: all
vars_files:
- vars.yml
vars:
keycloak_quarkus_show_deprecation_warnings: false
keycloak_quarkus_version: 24.0.3
roles:
- role: keycloak_quarkus

View File

@@ -1,43 +0,0 @@
---
dependency:
name: galaxy
options:
requirements-file: molecule/requirements.yml
driver:
name: docker
platforms:
- name: instance
image: registry.access.redhat.com/ubi9/ubi-init:latest
command: "/usr/sbin/init"
pre_build_image: true
privileged: true
port_bindings:
- 8080:8080
published_ports:
- 0.0.0.0:8080:8080/TCP
provisioner:
name: ansible
playbooks:
prepare: prepare.yml
converge: converge.yml
verify: verify.yml
inventory:
host_vars:
localhost:
ansible_python_interpreter: "{{ ansible_playbook_python }}"
verifier:
name: ansible
scenario:
test_sequence:
- dependency
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy

View File

@@ -1,52 +0,0 @@
---
- name: Prepare
hosts: all
vars_files:
- vars.yml
vars:
sudo_pkg_name: sudo
keycloak_quarkus_version: 23.0.7
pre_tasks:
- name: Install sudo
ansible.builtin.apt:
name:
- sudo
- openjdk-17-jdk-headless
state: present
when:
- ansible_facts.os_family == 'Debian'
- name: "Ensure common prepare phase are set."
ansible.builtin.include_tasks: ../prepare.yml
- name: Display Ansible version
ansible.builtin.debug:
msg: "Ansible version is {{ ansible_version.full }}"
- name: "Ensure {{ sudo_pkg_name }} is installed (if user is root)."
ansible.builtin.dnf:
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: Create certificate request
ansible.builtin.command: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance'
delegate_to: localhost
changed_when: false
roles:
- role: keycloak_quarkus
post_tasks:
- name: "Delete custom fact"
ansible.builtin.file:
path: /etc/ansible/facts.d/keycloak.fact
state: absent
become: true

View File

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

View File

@@ -1,14 +0,0 @@
---
keycloak_quarkus_offline_install: false
keycloak_quarkus_admin_password: "remembertochangeme"
keycloak_quarkus_admin_pass: "remembertochangeme"
keycloak_quarkus_realm: TestRealm
keycloak_quarkus_host: instance
keycloak_quarkus_log: file
keycloak_quarkus_https_key_file_enabled: true
keycloak_quarkus_log_target: /tmp/keycloak
keycloak_quarkus_hostname_strict: false
keycloak_quarkus_cert_file_copy_enabled: true
keycloak_quarkus_key_file_copy_enabled: true
keycloak_quarkus_key_content: "{{ lookup('file', 'key.pem') }}"
keycloak_quarkus_cert_file_src: cert.pem

View File

@@ -1,32 +0,0 @@
---
- name: Verify
hosts: instance
vars:
keycloak_quarkus_admin_password: "remembertochangeme"
keycloak_quarkus_port: http://localhost:8080
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 we are running on requested jvm
ansible.builtin.shell: |
set -eo pipefail
ps -ef | grep 'etc/alternatives/.*17' | grep -v grep
changed_when: false
- name: Verify token api call
ansible.builtin.uri:
url: "{{ keycloak_quarkus_port }}/realms/master/protocol/openid-connect/token"
method: POST
body: "client_id=admin-cli&username=admin&password={{ keycloak_quarkus_admin_password }}&grant_type=password"
validate_certs: no
register: keycloak_auth_response
until: keycloak_auth_response.status == 200
retries: 2
delay: 2

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
################################################# #################################################
# python dependencies required to be installed # python dependencies required to be installed
# on the controller host with: # on the controller host with:
# pip install -r requirements.txt # pip install -r requirements.txt
# #
netaddr netaddr
lxml # for middleware_automation.common.maven_artifact

View File

@@ -1,5 +1,4 @@
--- ---
collections: collections:
- name: middleware_automation.common - name: middleware_automation.common
version: ">=1.2.1"
- name: ansible.posix - name: ansible.posix

View File

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

View File

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

View File

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

View File

@@ -12,7 +12,7 @@ galaxy_info:
license: Apache License 2.0 license: Apache License 2.0
min_ansible_version: "2.15" min_ansible_version: "2.14"
platforms: platforms:
- name: EL - name: EL

View File

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

View File

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

View File

@@ -41,8 +41,8 @@
ansible.builtin.user: ansible.builtin.user:
name: "{{ keycloak_service_user }}" name: "{{ keycloak_service_user }}"
home: /opt/keycloak home: /opt/keycloak
system: true system: yes
create_home: false create_home: no
- name: "Create install location for {{ keycloak.service_name }}" - name: "Create install location for {{ keycloak.service_name }}"
become: true become: true
@@ -51,7 +51,7 @@
state: directory state: directory
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0750' mode: 0750
- name: Create pidfile folder - name: Create pidfile folder
become: true become: true
@@ -60,7 +60,7 @@
state: directory state: directory
owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}" owner: "{{ keycloak_service_user if keycloak_service_runas else omit }}"
group: "{{ keycloak_service_group if keycloak_service_runas else omit }}" group: "{{ keycloak_service_group if keycloak_service_runas else omit }}"
mode: '0750' mode: 0750
## check remote archive ## check remote archive
- name: Set download archive path - name: Set download archive path
@@ -84,7 +84,7 @@
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_download_url }}" url: "{{ keycloak_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0644' mode: 0644
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
when: when:
@@ -136,7 +136,7 @@
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_rhsso_download_url }}" url: "{{ keycloak_rhsso_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0644' mode: 0644
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
when: when:
@@ -160,7 +160,7 @@
dest: "{{ archive }}" dest: "{{ archive }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
register: new_version_downloaded register: new_version_downloaded
when: when:
- not archive_path.stat.exists - not archive_path.stat.exists
@@ -221,7 +221,7 @@
dest: "{{ keycloak_config_path_to_standalone_xml }}" dest: "{{ keycloak_config_path_to_standalone_xml }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
notify: notify:
- restart keycloak - restart keycloak
when: keycloak_config_override_template | length > 0 when: keycloak_config_override_template | length > 0
@@ -233,7 +233,7 @@
dest: "{{ keycloak_config_path_to_standalone_xml }}" dest: "{{ keycloak_config_path_to_standalone_xml }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
notify: notify:
- restart keycloak - restart keycloak
when: when:
@@ -261,7 +261,7 @@
dest: "{{ keycloak_config_path_to_standalone_xml }}" dest: "{{ keycloak_config_path_to_standalone_xml }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
notify: notify:
- restart keycloak - restart keycloak
when: when:
@@ -276,7 +276,7 @@
dest: "{{ keycloak_config_path_to_standalone_xml }}" dest: "{{ keycloak_config_path_to_standalone_xml }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
notify: notify:
- restart keycloak - restart keycloak
when: when:
@@ -291,7 +291,7 @@
dest: "{{ keycloak_config_path_to_properties }}" dest: "{{ keycloak_config_path_to_properties }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
notify: notify:
- restart keycloak - restart keycloak
when: keycloak_features | length > 0 when: keycloak_features | length > 0

View File

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

View File

@@ -12,17 +12,10 @@
recurse: true recurse: true
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0750' mode: 0750
become: true become: true
when: when:
- not dest_path.stat.exists - not dest_path.stat.exists
- name: "Verify valid parameters for download credentials when specified"
ansible.builtin.fail:
msg: >-
When JDBC driver download credentials are set, both the username and the password MUST be set
when: >
(keycloak_jdbc_download_user is undefined and keycloak_jdbc_download_pass is not undefined) or
(keycloak_jdbc_download_pass is undefined and keycloak_jdbc_download_user is not undefined)
- name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}" - name: "Retrieve JDBC Driver from {{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_url }}"
ansible.builtin.get_url: ansible.builtin.get_url:
@@ -30,10 +23,7 @@
dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}" dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/{{ keycloak_jdbc[keycloak_jdbc_engine].driver_jar_filename }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
url_username: "{{ keycloak_jdbc_download_user | default(omit) }}" mode: 0640
url_password: "{{ keycloak_jdbc_download_pass | default(omit) }}"
validate_certs: "{{ keycloak_jdbc_download_validate_certs | default(omit) }}"
mode: '0640'
become: true become: true
- name: "Deploy module.xml for JDBC Driver" - name: "Deploy module.xml for JDBC Driver"
@@ -42,5 +32,5 @@
dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/module.xml" dest: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_dir }}/module.xml"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
mode: '0640' mode: 0640
become: true become: true

View File

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

View File

@@ -4,16 +4,13 @@
that: that:
- keycloak_admin_password | length > 12 - keycloak_admin_password | length > 12
quiet: true quiet: true
fail_msg: > fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_admin_password variable to a 12+ char long string"
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' }}" success_msg: "{{ 'Console administrator password OK' }}"
- name: Validate configuration - name: Validate configuration
ansible.builtin.assert: ansible.builtin.assert:
that: > that:
(keycloak_ha_enabled and keycloak_db_enabled) or - (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)
(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" 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' }}" success_msg: "{{ 'Configuring HA' if keycloak_ha_enabled else 'Configuring standalone' }}"
@@ -39,20 +36,12 @@
success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database" success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database"
when: keycloak_db_enabled when: keycloak_db_enabled
- name: Validate OS family
ansible.builtin.assert:
that:
- ansible_os_family in ["RedHat", "Debian"]
quiet: true
fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}"
success_msg: "Installing on {{ ansible_os_family }}"
- name: Load OS specific variables
ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml"
tags:
- always
- name: Ensure required packages are installed - name: Ensure required packages are installed
ansible.builtin.include_tasks: fastpackages.yml ansible.builtin.include_tasks: fastpackages.yml
vars: vars:
packages_list: "{{ keycloak_prereq_package_list }}" packages_list:
- "{{ keycloak_jvm_package }}"
- unzip
- procps-ng
- initscripts
- tzdata-java

View File

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

View File

@@ -22,7 +22,7 @@
- name: "Restart and enable {{ keycloak.service_name }} service" - name: "Restart and enable {{ keycloak.service_name }} service"
ansible.builtin.systemd: ansible.builtin.systemd:
name: keycloak name: keycloak
enabled: true enabled: yes
state: restarted state: restarted
become: true become: true
when: inventory_hostname != ansible_play_hosts | first when: inventory_hostname != ansible_play_hosts | first

View File

@@ -10,4 +10,4 @@
ansible.builtin.command: > ansible.builtin.command: >
{{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }} {{ keycloak.cli_path }} --connect --command='{{ query }}' --controller={{ keycloak_host }}:{{ keycloak_management_http_port }}
changed_when: false changed_when: false
register: cli_result register: cli_result

View File

@@ -36,16 +36,14 @@
- name: Determine patch versions list - name: Determine patch versions list
ansible.builtin.set_fact: ansible.builtin.set_fact:
filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | \ filtered_versions: "{{ rhn_products.results | map(attribute='file_path') | select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*)-.*', '\\1') | list | unique }}"
select('match', '^[^/]*/rh-sso-.*[0-9]*[.][0-9]*[.][0-9]*.*$') | \
map('regex_replace', '[^/]*/rh-sso-([0-9]*[.][0-9]*[.][0-9]*(-[0-9])?)-.*', '\\1') | list | unique }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0 when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
- name: Determine latest version - name: Determine latest version
ansible.builtin.set_fact: ansible.builtin.set_fact:
sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}" sso_latest_version: "{{ filtered_versions | middleware_automation.common.version_sort | last }}"
when: sso_patch_version is not defined or sso_patch_version | length == 0 when: sso_patch_version is not defined or sso_patch_version | length == 0
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
@@ -72,7 +70,7 @@
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
client_id: "{{ rhn_username }}" client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}" client_secret: "{{ rhn_password }}"
product_id: "{{ (rhn_filtered_products | sort | last).id }}" product_id: "{{ (rhn_filtered_products | first).id }}"
dest: "{{ local_path.stat.path }}/{{ patch_bundle }}" dest: "{{ local_path.stat.path }}/{{ patch_bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}" no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost delegate_to: localhost
@@ -95,7 +93,7 @@
dest: "{{ patch_archive }}" dest: "{{ patch_archive }}"
owner: "{{ keycloak_service_user }}" owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: '0640' mode: 0640
register: new_version_downloaded register: new_version_downloaded
when: when:
- not patch_archive_path.stat.exists - not patch_archive_path.stat.exists
@@ -116,7 +114,7 @@
when: when:
- cli_result is defined - cli_result is defined
- cli_result.stdout is defined - cli_result.stdout is defined
- patch_version | regex_replace('-[0-9]$', '') not in cli_result.stdout - patch_version not in cli_result.stdout
block: block:
- name: "Apply patch {{ patch_version }} to server" - name: "Apply patch {{ patch_version }} to server"
ansible.builtin.include_tasks: rhsso_cli.yml ansible.builtin.include_tasks: rhsso_cli.yml
@@ -135,8 +133,8 @@
- cli_result.rc == 0 - cli_result.rc == 0
args: args:
apply: apply:
become: true become: true
become_user: "{{ keycloak_service_user }}" become_user: "{{ keycloak_service_user }}"
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}" - name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
ansible.builtin.uri: ansible.builtin.uri:
@@ -152,8 +150,8 @@
query: "patch info" query: "patch info"
args: args:
apply: apply:
become: true become: true
become_user: "{{ keycloak_service_user }}" become_user: "{{ keycloak_service_user }}"
- name: "Verify installed patch version" - name: "Verify installed patch version"
ansible.builtin.assert: ansible.builtin.assert:

View File

@@ -6,18 +6,24 @@
dest: "{{ keycloak_dest }}/keycloak-service.sh" dest: "{{ keycloak_dest }}/keycloak-service.sh"
owner: root owner: root
group: root group: root
mode: '0755' mode: 0755
notify: notify:
- restart keycloak - restart keycloak
- name: Determine JAVA_HOME for selected JVM RPM
ansible.builtin.set_fact:
rpm_java_home: "/etc/alternatives/jre_{{ keycloak_jvm_package | regex_search('(?<=java-)[0-9.]+') }}"
- name: "Configure sysconfig file for {{ keycloak.service_name }} service" - name: "Configure sysconfig file for {{ keycloak.service_name }} service"
become: true become: true
ansible.builtin.template: ansible.builtin.template:
src: keycloak-sysconfig.j2 src: keycloak-sysconfig.j2
dest: "{{ keycloak_sysconf_file }}" dest: /etc/sysconfig/keycloak
owner: root owner: root
group: root group: root
mode: '0644' mode: 0644
vars:
keycloak_rpm_java_home: "{{ rpm_java_home }}"
notify: notify:
- restart keycloak - restart keycloak
@@ -27,7 +33,7 @@
dest: /etc/systemd/system/keycloak.service dest: /etc/systemd/system/keycloak.service
owner: root owner: root
group: root group: root
mode: '0644' mode: 0644
become: true become: true
register: systemdunit register: systemdunit
notify: notify:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,8 +13,7 @@ keycloak:
service_name: "{{ keycloak_service_name }}" service_name: "{{ keycloak_service_name }}"
health_url: "{{ keycloak_management_url }}/health" health_url: "{{ keycloak_management_url }}/health"
cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh" cli_path: "{{ keycloak_jboss_home }}/bin/jboss-cli.sh"
config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 \ config_template_source: "{{ keycloak_config_override_template if keycloak_config_override_template | length > 0 else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}"
else 'standalone-ha.xml.j2' if keycloak_remote_cache_enabled else 'standalone.xml.j2' }}"
features: "{{ keycloak_features }}" features: "{{ keycloak_features }}"
# database # database
@@ -27,8 +26,7 @@ keycloak_jdbc:
driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/postgresql/main" driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/postgresql/main"
driver_version: "{{ keycloak_jdbc_driver_version }}" driver_version: "{{ keycloak_jdbc_driver_version }}"
driver_jar_filename: "postgresql-{{ keycloak_jdbc_driver_version }}.jar" driver_jar_filename: "postgresql-{{ keycloak_jdbc_driver_version }}.jar"
driver_jar_url: > driver_jar_url: "https://repo.maven.apache.org/maven2/org/postgresql/postgresql/{{ keycloak_jdbc_driver_version }}/postgresql-{{ keycloak_jdbc_driver_version }}.jar"
{{ keycloak_maven_central }}org/postgresql/postgresql/{{ keycloak_jdbc_driver_version }}/postgresql-{{ keycloak_jdbc_driver_version }}.jar
connection_url: "{{ keycloak_jdbc_url }}" connection_url: "{{ keycloak_jdbc_url }}"
db_user: "{{ keycloak_db_user }}" db_user: "{{ keycloak_db_user }}"
db_password: "{{ keycloak_db_pass }}" db_password: "{{ keycloak_db_pass }}"
@@ -48,8 +46,7 @@ keycloak_jdbc:
driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/mariadb/main" driver_module_dir: "{{ keycloak_jboss_home }}/modules/org/mariadb/main"
driver_version: "{{ keycloak_jdbc_driver_version }}" driver_version: "{{ keycloak_jdbc_driver_version }}"
driver_jar_filename: "mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar" driver_jar_filename: "mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar"
driver_jar_url: > driver_jar_url: "https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/{{ keycloak_jdbc_driver_version }}/mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar"
{{ keycloak_maven_central }}org/mariadb/jdbc/mariadb-java-client/{{ keycloak_jdbc_driver_version }}/mariadb-java-client-{{ keycloak_jdbc_driver_version }}.jar
connection_url: "{{ keycloak_jdbc_url }}" connection_url: "{{ keycloak_jdbc_url }}"
db_user: "{{ keycloak_db_user }}" db_user: "{{ keycloak_db_user }}"
db_password: "{{ keycloak_db_pass }}" db_password: "{{ keycloak_db_pass }}"
@@ -70,8 +67,7 @@ keycloak_jdbc:
driver_module_dir: "{{ keycloak_jboss_home }}/modules/com/microsoft/sqlserver/main" driver_module_dir: "{{ keycloak_jboss_home }}/modules/com/microsoft/sqlserver/main"
driver_version: "{{ keycloak_jdbc_driver_version }}" driver_version: "{{ keycloak_jdbc_driver_version }}"
driver_jar_filename: "mssql-java-client-{{ keycloak_jdbc_driver_version }}.jar" driver_jar_filename: "mssql-java-client-{{ keycloak_jdbc_driver_version }}.jar"
driver_jar_url: > driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar" # e.g., https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar
{{ keycloak_maven_central }}com/microsoft/sqlserver/mssql-jdbc/{{ keycloak_jdbc_driver_version }}.jre11/mssql-jdbc-{{ keycloak_jdbc_driver_version }}.jre11.jar
connection_url: "{{ keycloak_jdbc_url }}" connection_url: "{{ keycloak_jdbc_url }}"
db_user: "{{ keycloak_db_user }}" db_user: "{{ keycloak_db_user }}"
db_password: "{{ keycloak_db_pass }}" db_password: "{{ keycloak_db_pass }}"
@@ -106,5 +102,3 @@ keycloak_remotecache:
use_ssl: "{{ keycloak_infinispan_use_ssl }}" use_ssl: "{{ keycloak_infinispan_use_ssl }}"
trust_store_path: "{{ keycloak_infinispan_trust_store_path }}" trust_store_path: "{{ keycloak_infinispan_trust_store_path }}"
trust_store_password: "{{ keycloak_infinispan_trust_store_password }}" trust_store_password: "{{ keycloak_infinispan_trust_store_password }}"
keycloak_maven_central: https://repo1.maven.org/maven2/

View File

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

View File

@@ -1,49 +1,26 @@
keycloak_quarkus keycloak_quarkus
================ ================
<!--start description -->
Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations. Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations.
<!--end description -->
Requirements
------------
This role requires the `python3-netaddr` and `lxml` library installed on the controller node.
* to install via yum/dnf: `dnf install python3-netaddr python3-lxml`
* to install via apt: `apt install python3-netaddr python3-lxml`
* or via the collection: `pip install -r requirements.txt`
Dependencies
------------
The roles depends on:
* [middleware_automation.common](https://github.com/ansible-middleware/common)
* [ansible-posix](https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html)
To install all the dependencies via galaxy:
ansible-galaxy collection install -r requirements.yml
Role Defaults Role Defaults
------------- -------------
#### Installation options * Installation options
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
|`keycloak_quarkus_version`| keycloak.org package version | `24.0.4` | |`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` |
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` |
|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` |
|`keycloak_quarkus_download_path`| Path local to controller for offline/download of install archives | `{{ lookup('env', 'PWD') }}` |
#### Service configuration * Service configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` |
|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` |
|`keycloak_quarkus_admin_user`| Administration console user account | `admin` | |`keycloak_quarkus_admin_user`| Administration console user account | `admin` |
|`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` | |`keycloak_quarkus_bind_address`| Address for binding service ports | `0.0.0.0` |
|`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` | |`keycloak_quarkus_host`| Hostname for the Keycloak server | `localhost` |
@@ -52,65 +29,32 @@ Role Defaults
|`keycloak_quarkus_http_port`| HTTP listening port | `8080` | |`keycloak_quarkus_http_port`| HTTP listening port | `8080` |
|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` | |`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` |
|`keycloak_quarkus_ajp_port`| AJP port | `8009` | |`keycloak_quarkus_ajp_port`| AJP port | `8009` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|`keycloak_quarkus_service_user`| Posix account username | `keycloak` | |`keycloak_quarkus_service_user`| Posix account username | `keycloak` |
|`keycloak_quarkus_service_group`| Posix account group | `keycloak` | |`keycloak_quarkus_service_group`| Posix account group | `keycloak` |
|`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` | |`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` |
|`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` | |`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` |
|`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` | |`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` |
|`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` |
|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` | |`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` |
|`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` | |`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` |
|`keycloak_quarkus_java_heap_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` | |`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak |
|`keycloak_quarkus_java_opts`| JVM arguments; if overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` |
|`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file | `[]` |
|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | | |`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | |
|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | | |`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | |
|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` | |`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` |
|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` | |`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` |
|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; scheme, host and keycloak_quarkus_http_relative_path will be prepended automatically | `realms/master/.well-known/openid-configuration` |
|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` | |`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` |
|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` | |`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `{{ keycloak.home }}/conf/server.key.pem` |
|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` | |`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_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` |
|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`|
|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` |
|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` |
|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` | |`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` |
|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. || |`keycloak_quarkus_key_store_file`| The file pat to the key store | `{{ keycloak.home }}/conf/key_store.p12` |
|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.|| |`keycloak_quarkus_key_store_password`| Password for the key store | `""` |
|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` | |`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` |
|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` | |`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` | |`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` |
|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` |
|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` |
|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_keystore_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_keystore_password != ''`, else `''` |
|`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` |
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
|`keycloak_quarkus_configure_iptables` | Ensure iptables is configured for keycloak ports | `False` |
#### High-availability * Hostname configuration
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `TCPPING` |
|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` |
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` |
|`keycloak_quarkus_systemd_wait_for_port_number`| Which port the systemd unit should wait for | `{{ keycloak_quarkus_https_port }}` |
|`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` |
|`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` |
|`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` |
|`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` |
|`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `true` |
|`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` |
|`keycloak_quarkus_restart_health_check_reries`| Number of attempts for successful health check before failing | `25` |
|`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` |
#### Hostname configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -119,7 +63,7 @@ Role Defaults
|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | |`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` |
#### Database configuration * Database configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -130,7 +74,7 @@ Role Defaults
|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | |`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` |
#### Remote caches configuration * Remote caches configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -143,7 +87,18 @@ Role Defaults
|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | |`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` |
#### Miscellaneous configuration * Install options
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|`keycloak_quarkus_version`| keycloak.org package version | `23.0.7` |
|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` |
|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` |
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
* Miscellaneous configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@@ -169,74 +124,6 @@ Role Defaults
|`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` | |`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_transaction_xa_enabled`| Whether to use XA transactions | `True` |
|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | |`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` |
|`keycloak_quarkus_show_deprecation_warnings`| Whether deprecation warnings should be shown | `True` |
#### Vault SPI
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_ks_vault_enabled`| Whether to enable the vault SPI | `false` |
|`keycloak_quarkus_ks_vault_file`| The keystore path for the vault SPI | `{{ keycloak_quarkus_config_dir }}/keystore.p12` |
|`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` |
#### Configuring providers
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_providers`| List of provider definitions; see below | `[]` |
Providers support different sources:
* `url`: http download for providers not requiring authentication
* `maven`: maven download for providers hosted publicly on Apache Maven Central or private Maven repositories like Github Maven requiring authentication
* `local_path`: static providers to be uploaded
Provider definition:
```yaml
keycloak_quarkus_providers:
- id: http-client # required; "{{ id }}.jar" identifies the file name on RHBK
spi: connections # required if neither url, local_path nor maven are specified; required for setting properties
default: true # optional, whether to set default for spi, default false
restart: true # optional, whether to restart, default true
url: https://.../.../custom_spi.jar # optional, url for download via http
local_path: my_theme_spi.jar # optional, path on local controller for SPI to be uploaded
maven: # optional, for download using maven
repository_url: https://maven.pkg.github.com/OWNER/REPOSITORY # optional, maven repo url
group_id: my.group # optional, maven group id
artifact_id: artifact # optional, maven artifact id
version: 24.0.4 # optional, defaults to latest
username: user # optional, cf. https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages
password: pat # optional, provide a PAT for accessing Github's Apache Maven registry
properties: # optional, list of key-values
- key: default-connection-pool-size
value: 10
```
the definition above will generate the following build command:
```
bin/kc.sh build --spi-connections-provider=http-client --spi-connections-http-client-default-connection-pool-size=10
```
#### Configuring policies
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_policies`| List of policy definitions; see below | `[]` |
Provider definition:
```yaml
keycloak_quarkus_policies:
- name: xato-net-10-million-passwords.txt # required, resulting file name
url: https://github.com/danielmiessler/SecLists/raw/master/Passwords/xato-net-10-million-passwords.txt # required, url for download
type: password-blacklists # optional, defaults to `password-blacklists`; supported values: [`password-blacklists`]
```
Role Variables Role Variables
-------------- --------------
@@ -246,26 +133,7 @@ Role Variables
|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` |
|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` |
|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` |
|`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` |
|`keycloak_quarkus_alternate_download_url`| Alternate location with optional authentication for downloading RHBK | `no` |
|`keycloak_quarkus_download_user`| Optional username for http authentication | `no*` |
|`keycloak_quarkus_download_pass`| Optional password for http authentication | `no*` |
|`keycloak_quarkus_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_alternate_download_url` | `no` |
|`keycloak_quarkus_jdbc_download_user`| Optional username for http authentication | `no*` |
|`keycloak_quarkus_jdbc_download_pass`| Optional password for http authentication | `no*` |
|`keycloak_quarkus_jdbc_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_download_validate_certs` | `no` |
`*` username/password authentication credentials must be both declared or both undefined
Role custom facts
-----------------
The role uses the following [custom facts](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html#adding-custom-facts) found in `/etc/ansible/facts.d/keycloak.fact` (and thus identified by the `ansible_local.keycloak.` prefix):
| Variable | Description |
|:---------|:------------|
|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_admin_user[_pass]` gets created |
License License
------- -------

View File

@@ -1,6 +1,6 @@
--- ---
### Configuration specific to keycloak ### Configuration specific to keycloak
keycloak_quarkus_version: 24.0.4 keycloak_quarkus_version: 23.0.7
keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip" keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip"
keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}" keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}" keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
@@ -8,24 +8,21 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q
# whether to install from local archive # whether to install from local archive
keycloak_quarkus_offline_install: false keycloak_quarkus_offline_install: false
keycloak_quarkus_show_deprecation_warnings: true
### Install location and service settings ### Install location and service settings
keycloak_quarkus_jvm_package: java-17-openjdk-headless
keycloak_quarkus_java_home: keycloak_quarkus_java_home:
keycloak_quarkus_dest: /opt/keycloak keycloak_quarkus_dest: /opt/keycloak
keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}" keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}"
keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf" keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf"
keycloak_quarkus_download_path: "{{ lookup('env', 'PWD') }}"
keycloak_quarkus_start_dev: false keycloak_quarkus_start_dev: false
keycloak_quarkus_service_user: keycloak keycloak_quarkus_service_user: keycloak
keycloak_quarkus_service_group: keycloak keycloak_quarkus_service_group: keycloak
keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_service_restart_always: false keycloak_quarkus_service_restart_always: false
keycloak_quarkus_service_restart_on_failure: false keycloak_quarkus_service_restart_on_failure: false
keycloak_quarkus_service_restartsec: "10s" keycloak_quarkus_service_restartsec: "10s"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_configure_iptables: false
### administrator console password ### administrator console password
keycloak_quarkus_admin_user: admin keycloak_quarkus_admin_user: admin
keycloak_quarkus_admin_pass: keycloak_quarkus_admin_pass:
@@ -41,44 +38,26 @@ keycloak_quarkus_http_port: 8080
keycloak_quarkus_https_port: 8443 keycloak_quarkus_https_port: 8443
keycloak_quarkus_ajp_port: 8009 keycloak_quarkus_ajp_port: 8009
keycloak_quarkus_jgroups_port: 7800 keycloak_quarkus_jgroups_port: 7800
keycloak_quarkus_java_heap_opts: "-Xms1024m -Xmx2048m" keycloak_quarkus_java_opts: "-Xms1024m -Xmx2048m"
keycloak_quarkus_java_jvm_opts: "-XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8
-Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError
-Djava.security.egd=file:/dev/urandom -XX:+UseParallelGC -XX:GCTimeRatio=4
-XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512"
keycloak_quarkus_java_opts: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}"
keycloak_quarkus_additional_env_vars: []
### TLS/HTTPS configuration ### TLS/HTTPS configuration
keycloak_quarkus_https_key_file_enabled: false keycloak_quarkus_https_key_file_enabled: false
keycloak_quarkus_key_file_copy_enabled: false keycloak_quarkus_key_file: "{{ keycloak.home }}/conf/server.key.pem"
keycloak_quarkus_key_content: "" keycloak_quarkus_cert_file: "{{ keycloak.home }}/conf/server.crt.pem"
keycloak_quarkus_key_file: "/etc/pki/tls/private/server.key.pem"
keycloak_quarkus_cert_file_copy_enabled: false
keycloak_quarkus_cert_file_src: ""
keycloak_quarkus_cert_file: "/etc/pki/tls/certs/server.crt.pem"
#### key store configuration #### key store configuration
keycloak_quarkus_https_key_store_enabled: false keycloak_quarkus_https_key_store_enabled: false
keycloak_quarkus_https_key_store_file: "{{ keycloak.home }}/conf/key_store.p12" keycloak_quarkus_key_store_file: "{{ keycloak.home }}/conf/key_store.p12"
keycloak_quarkus_https_key_store_password: '' keycloak_quarkus_key_store_password: ''
##### trust store configuration ##### trust store configuration
keycloak_quarkus_https_trust_store_enabled: false keycloak_quarkus_https_trust_store_enabled: false
keycloak_quarkus_https_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12" keycloak_quarkus_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12"
keycloak_quarkus_https_trust_store_password: '' keycloak_quarkus_trust_store_password: ''
### configuration key store configuration
keycloak_quarkus_config_key_store_file: "{{ keycloak.home }}/conf/conf_store.p12"
keycloak_quarkus_config_key_store_password: ''
### Enable configuration for database backend, clustering and remote caches on infinispan ### Enable configuration for database backend, clustering and remote caches on infinispan
keycloak_quarkus_ha_enabled: false keycloak_quarkus_ha_enabled: false
keycloak_quarkus_ha_discovery: "TCPPING" keycloak_quarkus_ha_discovery: "TCPPING"
### Enable database configuration, must be enabled when HA is configured ### Enable database configuration, must be enabled when HA is configured
keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}" keycloak_quarkus_db_enabled: "{{ True if keycloak_quarkus_ha_enabled else False }}"
keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}"
keycloak_quarkus_systemd_wait_for_port_number: "{{ keycloak_quarkus_https_port }}"
keycloak_quarkus_systemd_wait_for_log: false
keycloak_quarkus_systemd_wait_for_timeout: 60
keycloak_quarkus_systemd_wait_for_delay: 10
### keycloak frontend url ### keycloak frontend url
keycloak_quarkus_frontend_url: keycloak_quarkus_frontend_url:
@@ -95,17 +74,13 @@ keycloak_quarkus_hostname_strict: true
# If all applications use the public URL this option should be enabled. # If all applications use the public URL this option should be enabled.
keycloak_quarkus_hostname_strict_backchannel: false keycloak_quarkus_hostname_strict_backchannel: false
# The proxy headers that should be accepted by the server. ['', 'forwarded', 'xforwarded'] # proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough]
keycloak_quarkus_proxy_headers: ""
# deprecated: proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough]
keycloak_quarkus_proxy_mode: edge keycloak_quarkus_proxy_mode: edge
# disable xa transactions # disable xa transactions
keycloak_quarkus_transaction_xa_enabled: true keycloak_quarkus_transaction_xa_enabled: true
# If the route should be attached to cookies to reflect the node that owns a particular session. # If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
# If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true
keycloak_quarkus_metrics_enabled: false keycloak_quarkus_metrics_enabled: false
@@ -138,9 +113,8 @@ keycloak_quarkus_default_jdbc:
version: 2.7.4 version: 2.7.4
mssql: mssql:
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;' url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
version: 12.4.2 version: 12.2.0
driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.4.2.jre11/mssql-jdbc-12.4.2.jre11.jar" driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
# cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
### logging configuration ### logging configuration
keycloak_quarkus_log: file keycloak_quarkus_log: file
keycloak_quarkus_log_level: info keycloak_quarkus_log_level: info
@@ -150,20 +124,3 @@ keycloak_quarkus_log_target: /var/log/keycloak
keycloak_quarkus_log_max_file_size: 10M keycloak_quarkus_log_max_file_size: 10M
keycloak_quarkus_log_max_backup_index: 10 keycloak_quarkus_log_max_backup_index: 10
keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip'
# keystore-based vault
keycloak_quarkus_ks_vault_enabled: false
keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
keycloak_quarkus_ks_vault_type: PKCS12
keycloak_quarkus_ks_vault_pass:
keycloak_quarkus_providers: []
keycloak_quarkus_policies: []
keycloak_quarkus_supported_policy_types: ['password-blacklists']
# files in restart directory (one of [ 'serial', 'none', 'serial_then_parallel' ]), or path to file when providing custom strategy
keycloak_quarkus_restart_strategy: restart/serial.yml
keycloak_quarkus_restart_health_check: true
keycloak_quarkus_restart_health_check_delay: 10
keycloak_quarkus_restart_health_check_reries: 25
keycloak_quarkus_restart_pause: 15

View File

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

View File

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

View File

@@ -8,17 +8,12 @@ galaxy_info:
license: Apache License 2.0 license: Apache License 2.0
min_ansible_version: "2.15" min_ansible_version: "2.14"
platforms: platforms:
- name: EL - name: EL
versions: versions:
- "8" - "8"
- "9"
- name: Fedora
- name: Debian
- name: Ubuntu
galaxy_tags: galaxy_tags:
- keycloak - keycloak
@@ -30,4 +25,3 @@ galaxy_info:
- identity - identity
- security - security
- rhbk - rhbk
- debian

View File

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

View File

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

View File

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

View File

@@ -1,53 +0,0 @@
---
- name: Check deprecation keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store
delegate_to: localhost
run_once: true
when:
- keycloak_quarkus_https_key_store_enabled
block:
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_file`, superseded by `keycloak_quarkus_https_key_store_file`
when:
- keycloak_quarkus_key_store_file is defined
- keycloak_quarkus_key_store_file != ''
- keycloak_quarkus_https_key_store_file == keycloak.home + "/conf/key_store.p12" # default value
changed_when: keycloak_quarkus_show_deprecation_warnings
ansible.builtin.set_fact:
keycloak_quarkus_https_key_store_file: "{{ keycloak_quarkus_key_store_file }}"
deprecated_variable: "keycloak_quarkus_key_store_file" # read in deprecation handler
notify:
- print deprecation warning
- name: Flush handlers
ansible.builtin.meta: flush_handlers
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_password`, superseded by `keycloak_quarkus_https_key_store_password`
when:
- keycloak_quarkus_key_store_password is defined
- keycloak_quarkus_key_store_password != ''
- keycloak_quarkus_https_key_store_password == "" # default value
changed_when: keycloak_quarkus_show_deprecation_warnings
ansible.builtin.set_fact:
keycloak_quarkus_https_key_store_password: "{{ keycloak_quarkus_key_store_password }}"
deprecated_variable: "keycloak_quarkus_key_store_password" # read in deprecation handler
notify:
- print deprecation warning
- name: Flush handlers
ansible.builtin.meta: flush_handlers
# https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html-single/upgrading_guide/index#deprecated_literal_proxy_literal_option
- name: Check deprecation of keycloak_quarkus_proxy_mode
when:
- keycloak_quarkus_proxy_mode is defined
- keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers | length == 0
- keycloak_quarkus_version.split('.') | first | int >= 24
delegate_to: localhost
run_once: true
changed_when: keycloak_quarkus_show_deprecation_warnings
ansible.builtin.set_fact:
deprecated_variable: "keycloak_quarkus_proxy_mode" # read in deprecation handler
notify:
- print deprecation warning
- name: Flush handlers
ansible.builtin.meta: flush_handlers

View File

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

View File

@@ -8,7 +8,6 @@
- keycloak_quarkus_archive is defined - keycloak_quarkus_archive is defined
- keycloak_quarkus_download_url is defined - keycloak_quarkus_download_url is defined
- keycloak_quarkus_version is defined - keycloak_quarkus_version is defined
- local_path is defined
quiet: true quiet: true
- name: Check for an existing deployment - name: Check for an existing deployment
@@ -23,7 +22,7 @@
name: "{{ keycloak.service_user }}" name: "{{ keycloak.service_user }}"
home: /opt/keycloak home: /opt/keycloak
system: true system: true
create_home: false create_home: no
- name: "Create {{ keycloak.service_name }} install location" - name: "Create {{ keycloak.service_name }} install location"
become: true become: true
@@ -32,14 +31,7 @@
state: directory state: directory
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0750' mode: 0750
- name: Create directory for ansible custom facts
become: true
ansible.builtin.file:
state: directory
recurse: true
path: /etc/ansible/facts.d
## check remote archive ## check remote archive
- name: Set download archive path - name: Set download archive path
@@ -53,13 +45,18 @@
register: archive_path register: archive_path
## download to controller ## download to controller
- name: Check local download archive path
ansible.builtin.stat:
path: "{{ lookup('env', 'PWD') }}"
register: local_path
delegate_to: localhost
- name: Download keycloak archive - name: Download keycloak archive
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_quarkus_download_url }}" url: "{{ keycloak_quarkus_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0640' mode: 0640
delegate_to: localhost delegate_to: localhost
become: false
run_once: true run_once: true
when: when:
- archive_path is defined - archive_path is defined
@@ -102,38 +99,15 @@
client_secret: "{{ rhn_password }}" client_secret: "{{ rhn_password }}"
product_id: "{{ (rhn_filtered_products | first).id }}" product_id: "{{ (rhn_filtered_products | first).id }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0640'
no_log: "{{ omit_rhn_output | default(true) }}" no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost delegate_to: localhost
run_once: true run_once: true
become: false
- name: Perform download of RHBK from alternate download location
delegate_to: localhost
run_once: true
become: false
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
- keycloak_quarkus_alternate_download_url is defined
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_quarkus_alternate_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0640'
url_username: "{{ keycloak_quarkus_download_user | default(omit) }}"
url_password: "{{ keycloak_quarkus_download_pass | default(omit) }}"
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
- name: Check downloaded archive - name: Check downloaded archive
ansible.builtin.stat: ansible.builtin.stat:
path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}" path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
register: local_archive_path register: local_archive_path
delegate_to: localhost delegate_to: localhost
become: false
run_once: true
## copy and unpack ## copy and unpack
- name: Copy archive to target nodes - name: Copy archive to target nodes
@@ -142,7 +116,7 @@
dest: "{{ archive }}" dest: "{{ archive }}"
owner: "{{ keycloak.service_user }}" owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}" group: "{{ keycloak.service_group }}"
mode: '0640' mode: 0640
register: new_version_downloaded register: new_version_downloaded
when: when:
- not archive_path.stat.exists - not archive_path.stat.exists
@@ -156,7 +130,7 @@
register: path_to_workdir register: path_to_workdir
become: true become: true
- name: "Extract Keycloak archive on target" # noqa no-handler need to run this here - name: "Extract Keycloak archive on target"
ansible.builtin.unarchive: ansible.builtin.unarchive:
remote_src: true remote_src: true
src: "{{ archive }}" src: "{{ archive }}"
@@ -176,108 +150,8 @@
when: when:
- (not new_version_downloaded.changed) and path_to_workdir.stat.exists - (not new_version_downloaded.changed) and path_to_workdir.stat.exists
- name: "Copy private key to target"
ansible.builtin.copy:
content: "{{ keycloak_quarkus_key_content }}"
dest: "{{ keycloak_quarkus_key_file }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
when:
- keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled
- keycloak_quarkus_key_file_copy_enabled is defined and keycloak_quarkus_key_file_copy_enabled
- keycloak_quarkus_key_content | length > 0
- name: "Copy certificate to target"
ansible.builtin.copy:
src: "{{ keycloak_quarkus_cert_file_src }}"
dest: "{{ keycloak_quarkus_cert_file }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0644'
become: true
when:
- keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled
- keycloak_quarkus_cert_file_copy_enabled is defined and keycloak_quarkus_cert_file_copy_enabled
- keycloak_quarkus_cert_file_src | length > 0
- name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver" - name: "Install {{ keycloak_quarkus_jdbc_engine }} JDBC driver"
ansible.builtin.include_tasks: jdbc_driver.yml ansible.builtin.include_tasks: jdbc_driver.yml
when: when:
- rhbk_enable is defined and rhbk_enable - rhbk_enable is defined and rhbk_enable
- keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined - keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].driver_jar_url is defined
- name: "Download custom providers via http"
ansible.builtin.get_url:
url: "{{ item.url }}"
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
loop: "{{ keycloak_quarkus_providers }}"
when: item.url is defined and item.url | length > 0
notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}"
# this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts
- name: "Download custom providers to localhost using maven"
middleware_automation.common.maven_artifact:
repository_url: "{{ item.maven.repository_url }}"
group_id: "{{ item.maven.group_id }}"
artifact_id: "{{ item.maven.artifact_id }}"
version: "{{ item.maven.version | default(omit) }}"
username: "{{ item.maven.username | default(omit) }}"
password: "{{ item.maven.password | default(omit) }}"
dest: "{{ local_path.stat.path }}/{{ item.id }}.jar"
delegate_to: "localhost"
run_once: true
loop: "{{ keycloak_quarkus_providers }}"
when: item.maven is defined
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
notify: "{{ ['rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or not item.restart else [] }}"
- name: "Copy maven providers"
ansible.builtin.copy:
src: "{{ local_path.stat.path }}/{{ item.id }}.jar"
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
loop: "{{ keycloak_quarkus_providers }}"
when: item.maven is defined
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
- name: "Copy providers"
ansible.builtin.copy:
src: "{{ item.local_path }}"
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
loop: "{{ keycloak_quarkus_providers }}"
when: item.local_path is defined
- name: Ensure required folder structure for policies exists
ansible.builtin.file:
path: "{{ keycloak.home }}/data/{{ item | lower }}"
state: directory
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0750'
become: true
loop: "{{ keycloak_quarkus_supported_policy_types }}"
- name: "Install custom policies"
ansible.builtin.get_url:
url: "{{ item.url }}"
dest: "{{ keycloak.home }}/data/{{ item.type | default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
become: true
loop: "{{ keycloak_quarkus_policies }}"
when: item.url is defined and item.url | length > 0
notify: "restart keycloak"

View File

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

View File

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

View File

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

View File

@@ -4,139 +4,31 @@
that: that:
- keycloak_quarkus_admin_pass | length > 12 - keycloak_quarkus_admin_pass | length > 12
quiet: true quiet: true
fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass to a 12+ char long string" fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_admin_pass variable to a 12+ char long string"
success_msg: "{{ 'Console administrator password OK' }}" success_msg: "{{ 'Console administrator password OK' }}"
- name: Validate relative path - name: Validate relative path
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- keycloak_quarkus_http_relative_path is regex('^/.*') - keycloak_quarkus_http_relative_path is regex('^/.*')
quiet: true quiet: true
fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /" fail_msg: "the relative path must begin with /"
success_msg: "{{ 'Relative path OK' }}" success_msg: "{{ 'relative path OK' }}"
- name: Validate configuration - name: Validate configuration
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or - (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
(not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
(not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
quiet: true quiet: true
fail_msg: "HA setup requires a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled" fail_msg: "Cannot install HA setup without a backend database service. Check keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled"
success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}" success_msg: "{{ 'Configuring HA' if keycloak_quarkus_ha_enabled else 'Configuring standalone' }}"
- name: Validate OS family
ansible.builtin.assert:
that:
- ansible_os_family in ["RedHat", "Debian"]
quiet: true
fail_msg: "Can only install on RedHat or Debian OS families; found {{ ansible_os_family }}"
success_msg: "Installing on {{ ansible_os_family }}"
- name: Load OS specific variables
ansible.builtin.include_vars: "vars/{{ ansible_os_family | lower }}.yml"
tags:
- always
- name: Ensure required packages are installed - name: Ensure required packages are installed
ansible.builtin.include_tasks: fastpackages.yml ansible.builtin.include_tasks: fastpackages.yml
vars: vars:
packages_list: "{{ keycloak_quarkus_prereq_package_list }}" packages_list:
- "{{ keycloak_quarkus_jvm_package }}"
- name: Check local download archive path - unzip
ansible.builtin.stat: - procps-ng
path: "{{ keycloak_quarkus_download_path }}" - initscripts
register: local_path - tzdata-java
delegate_to: localhost
run_once: true
become: false
- name: Validate local download path
ansible.builtin.assert:
that:
- local_path.stat.exists
- local_path.stat.readable
- keycloak_quarkus_offline_install or local_path.stat.writeable
quiet: true
fail_msg: "Defined controller path for downloading resources is incorrect or unreadable: {{ keycloak_quarkus_download_path }}"
success_msg: "Will download resource to controller path: {{ keycloak_quarkus_download_path }}"
delegate_to: localhost
run_once: true
- name: Check downloaded archive if offline
ansible.builtin.stat:
path: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
when: keycloak_quarkus_offline_install
register: local_archive_path_check
delegate_to: localhost
run_once: true
- name: Validate local downloaded archive if offline
ansible.builtin.assert:
that:
- local_archive_path_check.stat.exists
- local_archive_path_check.stat.readable
quiet: true
fail_msg: "Configured for offline install but install archive not found at: {{ local_path.stat.path }}/{{ keycloak.bundle }}"
success_msg: "Will install offline with expected archive: {{ local_path.stat.path }}/{{ keycloak.bundle }}"
when: keycloak_quarkus_offline_install
delegate_to: localhost
run_once: true
- name: "Validate keytool"
when: keycloak_quarkus_config_key_store_password | length > 0
block:
- name: "Check run keytool"
changed_when: false
ansible.builtin.command: keytool -help
register: keytool_check
ignore_errors: true
- name: "Fail when no keytool found"
when: keytool_check.rc != 0
ansible.builtin.fail:
msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store"
- name: "Validate providers"
ansible.builtin.assert:
that: >
item.id is defined and item.id | length > 0 and
( (item.spi is defined and item.spi | length > 0) or
(item.url is defined and item.url | length > 0) or
( item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and
item.maven.group_id is defined and item.maven.group_id | length > 0 and
item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) or
(item.local_path is defined and item.local_path | length > 0)
)
quiet: true
fail_msg: >
Providers definition incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property
loop: "{{ keycloak_quarkus_providers }}"
- name: "Validate policies"
ansible.builtin.assert:
that:
- item.name is defined and item.name | length > 0
- item.url is defined and item.url | length > 0
- item.type is not defined or item.type | lower in keycloak_quarkus_supported_policy_types
quiet: true
fail_msg: >
Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}.
loop: "{{ keycloak_quarkus_policies }}"
- name: "Validate additional env variables"
ansible.builtin.assert:
that:
- item.key is defined and item.key | length > 0
- item.value is defined and item.value | length > 0
quiet: true
fail_msg: "Additional env variable definition is incorrect: `key` and `value` are mandatory."
no_log: true
loop: "{{ keycloak_quarkus_additional_env_vars }}"
- name: "Validate proxy-headers"
ansible.builtin.assert:
that:
- keycloak_quarkus_proxy_headers | lower in ['', 'forwarded', 'xforwarded']
quiet: true
fail_msg: "keycloak_quarkus_proxy_headers must be either '', 'forwarded' or 'xforwarded'"

View File

@@ -1,10 +1,7 @@
--- ---
# cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup # cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup
- name: "Rebuild {{ keycloak.service_name }} config" - name: "Rebuild {{ keycloak.service_name }} config"
ansible.builtin.shell: | # noqa blocked_modules shell is necessary here ansible.builtin.shell: |
{{ keycloak.home }}/bin/kc.sh build {{ keycloak.home }}/bin/kc.sh build
environment:
PATH: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
JAVA_HOME: "{{ keycloak_quarkus_java_home | default(keycloak_quarkus_pkg_java_home, true) }}"
become: true become: true
changed_when: true changed_when: true

View File

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

View File

@@ -1,23 +1,8 @@
--- ---
- name: "Restart and enable {{ keycloak.service_name }} service" - name: "Restart and enable {{ keycloak.service_name }} service"
ansible.builtin.systemd: ansible.builtin.systemd:
name: "{{ keycloak.service_name }}" name: keycloak
enabled: true enabled: true
state: restarted state: restarted
daemon_reload: true daemon_reload: true
become: true become: true
- name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}"
ansible.builtin.uri:
url: "{{ keycloak.health_url }}"
register: keycloak_status
until: keycloak_status.status == 200
retries: "{{ keycloak_quarkus_restart_health_check_reries }}"
delay: "{{ keycloak_quarkus_restart_health_check_delay }}"
when: internal_force_health_check | default(keycloak_quarkus_restart_health_check)
- name: Wait to give distributed ispn caches time to (re-)replicate back onto first host
ansible.builtin.pause:
seconds: "{{ keycloak_quarkus_restart_pause }}"
when:
- keycloak_quarkus_ha_enabled

View File

@@ -1,4 +0,0 @@
---
- name: "Display message"
ansible.builtin.debug:
msg: "keycloak_quarkus_restart_strategy is none, skipping restart"

View File

@@ -1,11 +0,0 @@
---
- name: "Restart services in serial, with optional healtch check (keycloak_quarkus_restart_health_check)"
throttle: 1
block:
- name: "Restart and enable {{ keycloak.service_name }} service on {{ item }}"
ansible.builtin.include_tasks:
file: restart.yml
apply:
delegate_to: "{{ item }}"
run_once: true
loop: "{{ ansible_play_hosts }}"

View File

@@ -1,20 +0,0 @@
---
- name: Verify first restarted service with health URL, then rest restart in parallel
block:
- name: "Restart and enable {{ keycloak.service_name }} service on initial host"
ansible.builtin.include_tasks:
file: restart.yml
apply:
delegate_to: "{{ ansible_play_hosts | first }}"
run_once: true
vars:
internal_force_health_check: true
- name: "Restart and enable {{ keycloak.service_name }} service on other hosts"
ansible.builtin.systemd:
name: "{{ keycloak.service_name }}"
enabled: true
state: restarted
daemon_reload: true
become: true
when: inventory_hostname != ansible_play_hosts | first

Some files were not shown because too many files have changed in this diff Show More