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
76 changed files with 408 additions and 759 deletions

View File

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

View File

@@ -2,27 +2,20 @@
name: Release collection
on:
workflow_dispatch:
inputs:
release_summary:
description: 'Optional release summary for changelogs'
required: false
jobs:
release:
uses: ansible-middleware/github-actions/.github/workflows/release.yml@main
with:
collection_fqcn: 'middleware_automation.keycloak'
downstream_name: 'rhbk'
release_summary: "${{ github.event.inputs.release_summary }}"
secrets:
galaxy_token: ${{ secrets.ANSIBLE_GALAXY_API_KEY }}
jira_webhook: ${{ secrets.JIRA_WEBHOOK_CREATE_VERSION }}
dispatch:
needs: release
strategy:
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
steps:
- name: Repository Dispatch

View File

@@ -6,27 +6,6 @@ middleware\_automation.keycloak Release Notes
This changelog describes changes after version 0.2.6.
v2.1.2
======
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
======

View File

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

View File

@@ -419,40 +419,3 @@ releases:
- 167.yaml
- 171.yaml
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:
release_date: '2024-04-17'

View File

@@ -24,15 +24,14 @@
<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>
<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/keycloak/main/">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/jws/main/">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_streams/main/">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/main/">Red Hat CSP Download</a></li>
<li class="toctree-l1"><a class="reference internal" href="https://ansible-middleware.github.io/ansible_collections_jcliff/main/">JCliff</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/">Keycloak / Red Hat Single Sign-On</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/">Tomcat / Red Hat JWS</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/">Kafka / Red Hat AMQ Streams</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/ansible_collections_jcliff/">JCliff</a></li>
</ul>
</div>
</div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
---
- name: Converge
hosts: all
vars:
vars:
keycloak_admin_password: "remembertochangeme"
keycloak_config_override_template: custom.xml.j2
keycloak_http_port: 8081
@@ -9,3 +9,47 @@
keycloak_service_runas: True
roles:
- 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'?>
<!-- this is a custom file -->
<!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
@@ -44,7 +44,7 @@
</audit-log>
<management-interfaces>
<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"/>
</http-interface>
</management-interfaces>
@@ -481,8 +481,8 @@
<default-provider>default</default-provider>
<provider name="default" enabled="true">
<properties>
<property name="frontendUrl" value="${keycloak.frontendUrl:}"/>
<property name="forceBackendUrlToFrontendUrl" value="false"/>
<property name="frontendUrl" value="{{ keycloak_modcluster.frontend_url }}"/>
<property name="forceBackendUrlToFrontendUrl" value="true"/>
</properties>
</provider>
</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}}">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
<http-listener name="default" socket-binding="http"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker http-authentication-factory="application-http-authentication"/>
@@ -534,25 +533,20 @@
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
<application-security-domains>
<application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
</subsystem>
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
</profile>
<interfaces>
<interface name="management">
<inet-address value="127.0.0.1"/>
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="127.0.0.1"/>
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="http" port="8081"/>
<socket-binding name="https" port="8443"/>
<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-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">

View File

@@ -1,10 +1,6 @@
---
- name: Verify
hosts: all
vars:
keycloak_uri: "http://localhost:8081"
keycloak_management_port: "http://localhost:19990"
keycloak_admin_password: "remembertochangeme"
tasks:
- name: Populate service facts
ansible.builtin.service_facts:
@@ -13,20 +9,3 @@
that:
- ansible_facts.services["keycloak.service"]["state"] == "running"
- 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:
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)."
ansible.builtin.yum:
name: "{{ sudo_pkg_name }}"
state: present
when:
- ansible_user_id == 'root'
- name: Gather the package facts
ansible.builtin.package_facts:
manager: auto
- name: "Check if sudo is installed."
- name: "Check if {{ sudo_pkg_name }} is installed."
ansible.builtin.assert:
that:
- sudo_pkg_name in ansible_facts.packages
fail_msg: "sudo is not installed on target system"
- name: "Install iproute"
become: true
- name: Install sudo
become: yes
ansible.builtin.yum:
name:
- sudo
- iproute
state: present
- name: "Retrieve assets server from env"
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"
when:
- assets_server is defined
- assets_server | length > 0
- assets is defined
- assets | length > 0
block:
- name: "Set offline when assets server from env is defined"
ansible.builtin.set_fact:
@@ -51,7 +46,6 @@
url: "{{ asset }}"
dest: "{{ lookup('env', 'PWD') }}"
validate_certs: no
mode: '0644'
delegate_to: localhost
loop: "{{ assets }}"
loop_control:

View File

@@ -1,39 +1,14 @@
---
- name: Prepare
hosts: all
become: yes
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: Install JDK17
become: yes
ansible.builtin.yum:
name:
- sudo
- java-17-openjdk-headless
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
ansible.builtin.file:
@@ -41,8 +16,6 @@
src: /usr/lib/jvm/jre-17-openjdk
dest: /opt/openjdk
force: true
when:
- ansible_facts.os_family == "RedHat"
- name: "Display hera_home if defined."
ansible.builtin.set_fact:

View File

@@ -2,20 +2,22 @@
- name: Prepare
hosts: all
tasks:
- name: Install sudo
become: yes
ansible.builtin.yum:
name: sudo
state: present
- 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 key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=instance'
delegate_to: localhost
changed_when: False
- name: Create conf directory # risky-file-permissions in test user account does not exist yet
become: yes
ansible.builtin.file:
state: directory
path: "/opt/keycloak/certs/"

View File

@@ -49,9 +49,8 @@
- keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk
- name: Check log file
become: yes
ansible.builtin.stat:
path: "/tmp/keycloak/keycloak.log"
register: keycloak_log_file
@@ -63,7 +62,6 @@
- not keycloak_log_file.stat.isdir
- name: Check default log folder
become: yes
ansible.builtin.stat:
path: "/var/log/keycloak"
register: keycloak_default_log_folder

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,7 +10,6 @@ Requirements
This role requires the `python3-netaddr` library installed on the controller node.
* 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 the collection: `pip install -r requirements.txt`

View File

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

View File

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

View File

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

View File

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

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

View File

@@ -36,20 +36,12 @@
success_msg: "Configuring JDBC persistence using {{ keycloak_jdbc_engine }} database"
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
ansible.builtin.include_tasks: fastpackages.yml
vars:
packages_list: "{{ keycloak_prereq_package_list }}"
packages_list:
- "{{ keycloak_jvm_package }}"
- unzip
- procps-ng
- initscripts
- tzdata-java

View File

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

View File

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

View File

@@ -10,14 +10,20 @@
notify:
- 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"
become: true
ansible.builtin.template:
src: keycloak-sysconfig.j2
dest: "{{ keycloak_sysconf_file }}"
dest: /etc/sysconfig/keycloak
owner: root
group: root
mode: 0644
vars:
keycloak_rpm_java_home: "{{ rpm_java_home }}"
notify:
- restart keycloak

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
{{ ansible_managed | comment }}
# {{ ansible_managed }}
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 }}
KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }}
KEYCLOAK_HTTP_PORT={{ keycloak_http_port }}

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
{{ ansible_managed | comment('xml') }}
<!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
@@ -539,7 +539,7 @@
</mail-session>
</subsystem>
<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">
<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>
@@ -547,7 +547,7 @@
</dynamic-load-provider>
</proxy>
</subsystem>
{% endif %}
{% endif %}
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
@@ -621,6 +621,6 @@
<remote-destination host="{{ modcluster.host }}" port="{{ modcluster.port }}"/>
</outbound-socket-binding>
{% endfor %}
{% endif %}
{% endif %}
</socket-binding-group>
</server>

View File

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

View File

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

View File

@@ -38,9 +38,7 @@ Role Defaults
|`keycloak_quarkus_service_pidfile`| Pid file path for service | `/run/keycloak.pid` |
|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-17-openjdk-headless` |
|`keycloak_quarkus_java_home`| JAVA_HOME of installed JRE, leave empty for using specified keycloak_quarkus_jvm_package RPM path | `None` |
|`keycloak_quarkus_java_opts`| Heap memory JVM setting | `-Xms1024m -Xmx2048m` |
|`keycloak_quarkus_java_jvm_opts`| Other JVM settings | same as keycloak |
|`keycloak_quarkus_java_opts`| JVM arguments; if overriden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` |
|`keycloak_quarkus_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_quarkus_frontend_url`| Set the base URL for frontend URLs, including scheme, host, port and path | |
|`keycloak_quarkus_admin_url`| Set the base URL for accessing the administration console, including scheme, host, port and path | |
|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` |
@@ -54,7 +52,7 @@ Role Defaults
|`keycloak_quarkus_https_trust_store_enabled`| Enalbe confiugration of a trust store | `False` |
|`keycloak_quarkus_trust_store_file`| The file pat to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|`keycloak_quarkus_trust_store_password`| Password for the trust store | `""` |
|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwardedPassword`) | `""` |
* Hostname configuration

View File

@@ -9,6 +9,7 @@ keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_q
keycloak_quarkus_offline_install: false
### Install location and service settings
keycloak_quarkus_jvm_package: java-17-openjdk-headless
keycloak_quarkus_java_home:
keycloak_quarkus_dest: /opt/keycloak
keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}"
@@ -17,13 +18,11 @@ keycloak_quarkus_start_dev: false
keycloak_quarkus_service_user: keycloak
keycloak_quarkus_service_group: keycloak
keycloak_quarkus_service_pidfile: "/run/keycloak/keycloak.pid"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_service_restart_always: false
keycloak_quarkus_service_restart_on_failure: false
keycloak_quarkus_service_restartsec: "10s"
keycloak_quarkus_configure_firewalld: false
keycloak_quarkus_configure_iptables: false
### administrator console password
keycloak_quarkus_admin_user: admin
keycloak_quarkus_admin_pass:
@@ -39,12 +38,7 @@ keycloak_quarkus_http_port: 8080
keycloak_quarkus_https_port: 8443
keycloak_quarkus_ajp_port: 8009
keycloak_quarkus_jgroups_port: 7800
keycloak_quarkus_java_heap_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_java_opts: "-Xms1024m -Xmx2048m"
### TLS/HTTPS configuration
keycloak_quarkus_https_key_file_enabled: false
@@ -86,8 +80,7 @@ keycloak_quarkus_proxy_mode: edge
# disable xa transactions
keycloak_quarkus_transaction_xa_enabled: true
# If the route should be attached to cookies to reflect the node that owns a particular session.
# If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
# If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true
keycloak_quarkus_metrics_enabled: false
@@ -121,8 +114,7 @@ keycloak_quarkus_default_jdbc:
mssql:
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
version: 12.2.0
driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar"
# cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/12.2.0.jre11/mssql-jdbc-12.2.0.jre11.jar" # cf. https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/22.0/html/server_guide/db-#db-installing-the-microsoft-sql-server-driver
### logging configuration
keycloak_quarkus_log: file
keycloak_quarkus_log_level: info

View File

@@ -5,4 +5,4 @@
listen: "rebuild keycloak config"
- name: "Restart {{ keycloak.service_name }}"
ansible.builtin.include_tasks: restart.yml
listen: "restart keycloak"
listen: "restart keycloak"

View File

@@ -2,26 +2,32 @@ argument_specs:
main:
options:
keycloak_quarkus_version:
default: "23.0.7"
# line 3 of defaults/main.yml
default: "17.0.1"
description: "keycloak.org package version"
type: "str"
keycloak_quarkus_archive:
# line 4 of defaults/main.yml
default: "keycloak-{{ keycloak_quarkus_version }}.zip"
description: "keycloak install archive filename"
type: "str"
keycloak_quarkus_download_url:
# line 5 of defaults/main.yml
default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
description: "Download URL for keycloak"
type: "str"
keycloak_quarkus_installdir:
# line 6 of defaults/main.yml
default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
description: "Installation path"
type: "str"
keycloak_quarkus_offline_install:
# line 9 of defaults/main.yml
default: false
description: "Perform an offline install"
type: "bool"
keycloak_quarkus_jvm_package:
# line 12 of defaults/main.yml
default: "java-11-openjdk-headless"
description: "RHEL java package runtime"
type: "str"
@@ -29,34 +35,37 @@ argument_specs:
description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path"
type: "str"
keycloak_quarkus_dest:
# line 13 of defaults/main.yml
default: "/opt/keycloak"
description: "Installation root path"
type: "str"
keycloak_quarkus_home:
# line 14 of defaults/main.yml
default: "{{ keycloak_quarkus_installdir }}"
description: "Installation work directory"
type: "str"
keycloak_quarkus_config_dir:
# line 15 of defaults/main.yml
default: "{{ keycloak_quarkus_home }}/conf"
description: "Path for configuration"
type: "str"
keycloak_quarkus_service_user:
# line 16 of defaults/main.yml
default: "keycloak"
description: "Posix account username"
type: "str"
keycloak_quarkus_service_group:
# line 17 of defaults/main.yml
default: "keycloak"
description: "Posix account group"
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:
default: false
description: "Ensure firewalld is running and configure keycloak ports"
type: "bool"
keycloak_quarkus_configure_iptables:
# line 19 of defaults/main.yml
default: false
description: "Ensure firewalld is running and configure keycloak ports"
type: "bool"
@@ -81,10 +90,12 @@ argument_specs:
description: "Password of console admin account"
type: "str"
keycloak_quarkus_master_realm:
# line 24 of defaults/main.yml
default: "master"
description: "Name for rest authentication realm"
type: "str"
keycloak_quarkus_bind_address:
# line 27 of defaults/main.yml
default: "0.0.0.0"
description: "Address for binding service ports"
type: "str"
@@ -105,6 +116,7 @@ argument_specs:
description: "Enable listener on HTTP port"
type: "bool"
keycloak_quarkus_http_port:
# line 29 of defaults/main.yml
default: 8080
description: "HTTP port"
type: "int"
@@ -145,33 +157,27 @@ argument_specs:
description: "Password for the trust store"
type: "str"
keycloak_quarkus_https_port:
# line 30 of defaults/main.yml
default: 8443
description: "HTTPS port"
type: "int"
keycloak_quarkus_ajp_port:
# line 31 of defaults/main.yml
default: 8009
description: "AJP port"
type: "int"
keycloak_quarkus_jgroups_port:
# line 32 of defaults/main.yml
default: 7800
description: "jgroups cluster tcp port"
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:
default: "{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}"
description: "JVM arguments, by default heap_opts + jvm_opts, if overriden it takes precedence over them"
# line 33 of defaults/main.yml
default: "-Xms1024m -Xmx2048m"
description: "Additional JVM options"
type: "str"
keycloak_quarkus_ha_enabled:
# line 36 of defaults/main.yml
default: false
description: "Enable auto configuration for database backend, clustering and remote caches on infinispan"
type: "bool"
@@ -180,6 +186,7 @@ argument_specs:
description: "Discovery protocol for HA cluster members"
type: "str"
keycloak_quarkus_db_enabled:
# line 38 of defaults/main.yml
default: "{{ True if keycloak_quarkus_ha_enabled else False }}"
description: "Enable auto configuration for database backend"
type: "str"
@@ -197,6 +204,7 @@ argument_specs:
description: "Service URL for the admin console"
type: "str"
keycloak_quarkus_metrics_enabled:
# line 43 of defaults/main.yml
default: false
description: "Whether to enable metrics"
type: "bool"
@@ -205,50 +213,62 @@ argument_specs:
description: "If the server should expose health check endpoints"
type: "bool"
keycloak_quarkus_ispn_user:
# line 46 of defaults/main.yml
default: "supervisor"
description: "Username for connecting to infinispan"
type: "str"
keycloak_quarkus_ispn_pass:
# line 47 of defaults/main.yml
default: "supervisor"
description: "Password for connecting to infinispan"
type: "str"
keycloak_quarkus_ispn_hosts:
# line 48 of defaults/main.yml
default: "localhost:11222"
description: "host name/port for connecting to infinispan, eg. host1:11222;host2:11222"
type: "str"
keycloak_quarkus_ispn_sasl_mechanism:
# line 49 of defaults/main.yml
default: "SCRAM-SHA-512"
description: "Infinispan auth mechanism"
type: "str"
keycloak_quarkus_ispn_use_ssl:
# line 50 of defaults/main.yml
default: false
description: "Whether infinispan uses TLS connection"
type: "bool"
keycloak_quarkus_ispn_trust_store_path:
# line 52 of defaults/main.yml
default: "/etc/pki/java/cacerts"
description: "Path to infinispan server trust certificate"
type: "str"
keycloak_quarkus_ispn_trust_store_password:
# line 53 of defaults/main.yml
default: "changeit"
description: "Password for infinispan certificate keystore"
type: "str"
keycloak_quarkus_jdbc_engine:
# line 56 of defaults/main.yml
default: "postgres"
description: "Database engine [mariadb,postres,mssql]"
type: "str"
keycloak_quarkus_db_user:
# line 58 of defaults/main.yml
default: "keycloak-user"
description: "User for database connection"
type: "str"
keycloak_quarkus_db_pass:
# line 59 of defaults/main.yml
default: "keycloak-pass"
description: "Password for database connection"
type: "str"
keycloak_quarkus_jdbc_url:
# line 60 of defaults/main.yml
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].url }}"
description: "JDBC URL for connecting to database"
type: "str"
keycloak_quarkus_jdbc_driver_version:
# line 61 of defaults/main.yml
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_jdbc_engine].version }}"
description: "Version for JDBC driver"
type: "str"
@@ -275,9 +295,7 @@ argument_specs:
keycloak_quarkus_log_max_file_size:
default: 10M
type: "str"
description: >
Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular
expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes.
description: "Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes."
keycloak_quarkus_log_max_backup_index:
default: 10
type: "str"
@@ -285,17 +303,11 @@ argument_specs:
keycloak_quarkus_log_file_suffix:
default: '.yyyy-MM-dd.zip'
type: "str"
description: >
Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix. Note: If the suffix ends
with .zip or .gz, the rotation file will also be compressed.
description: "Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with .zip or .gz, the rotation file will also be compressed."
keycloak_quarkus_proxy_mode:
default: 'edge'
type: "str"
description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' if not using a proxy"
keycloak_quarkus_proxy_headers:
default: ""
type: "str"
description: "Parse reverse proxy headers (`forwarded` or `xforwardedPassword`), overrides the deprecated keycloak_quarkus_proxy_mode argument"
keycloak_quarkus_start_dev:
default: false
type: "bool"
@@ -307,25 +319,19 @@ argument_specs:
keycloak_quarkus_hostname_strict:
default: true
type: "bool"
description: >
Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless
proxy verifies the Host header.
description: "Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless proxy verifies the Host header."
keycloak_quarkus_hostname_strict_backchannel:
default: false
type: "bool"
description: >
By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all
applications use the public URL this option should be enabled.
description: "By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled."
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route:
default: true
type: "bool"
description: >
If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies
and we rely on the session affinity capabilities from reverse proxy
description: "If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy"
downstream:
options:
rhbk_version:
default: "22.0.10"
default: "22.0.6"
description: "Red Hat Build of Keycloak version"
type: "str"
rhbk_archive:
@@ -347,7 +353,7 @@ argument_specs:
rhbk_enable:
default: true
description: "Enable Red Hat Build of Keycloak installation"
type: "bool"
type: "str"
rhbk_offline_install:
default: false
description: "Perform an offline install"

View File

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

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

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

View File

@@ -22,7 +22,7 @@
name: "{{ keycloak.service_user }}"
home: /opt/keycloak
system: true
create_home: false
create_home: no
- name: "Create {{ keycloak.service_name }} install location"
become: true
@@ -31,7 +31,7 @@
state: directory
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0750'
mode: 0750
## check remote archive
- name: Set download archive path
@@ -50,15 +50,13 @@
path: "{{ lookup('env', 'PWD') }}"
register: local_path
delegate_to: localhost
become: false
- name: Download keycloak archive
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
url: "{{ keycloak_quarkus_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
mode: '0640'
mode: 0640
delegate_to: localhost
become: false
run_once: true
when:
- archive_path is defined
@@ -118,7 +116,7 @@
dest: "{{ archive }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
mode: 0640
register: new_version_downloaded
when:
- not archive_path.stat.exists
@@ -132,7 +130,7 @@
register: path_to_workdir
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:
remote_src: true
src: "{{ archive }}"

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

View File

@@ -4,12 +4,12 @@
ansible.builtin.include_tasks: prereqs.yml
tags:
- prereqs
- always
- name: Distro specific tasks
ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml"
- name: Include firewall config tasks
ansible.builtin.include_tasks: firewalld.yml
when: keycloak_quarkus_configure_firewalld
tags:
- unbound
- firewall
- name: Include install tasks
ansible.builtin.include_tasks: install.yml
@@ -27,7 +27,7 @@
dest: "{{ keycloak.home }}/conf/keycloak.conf"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
mode: 0644
become: true
notify:
- rebuild keycloak config
@@ -39,7 +39,7 @@
dest: "{{ keycloak.home }}/conf/quarkus.properties"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
mode: 0644
become: true
notify:
- restart keycloak
@@ -64,7 +64,7 @@
dest: "{{ keycloak.home }}/conf/cache-ispn.xml"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0640'
mode: 0644
become: true
notify:
- rebuild keycloak config
@@ -73,10 +73,10 @@
- name: Ensure logdirectory exists
ansible.builtin.file:
state: directory
path: "{{ keycloak.log.file | dirname }}"
path: "{{ keycloak.log.file | dirname }}"
owner: "{{ keycloak.service_user }}"
group: "{{ keycloak.service_group }}"
mode: '0775'
mode: 0775
become: true
- name: Flush pending handlers

View File

@@ -4,41 +4,31 @@
that:
- keycloak_quarkus_admin_pass | length > 12
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' }}"
- name: Validate relative path
ansible.builtin.assert:
that:
- keycloak_quarkus_http_relative_path is regex('^/.*')
quiet: true
fail_msg: "The relative path for keycloak_quarkus_http_relative_path must begin with /"
success_msg: "{{ 'Relative path OK' }}"
fail_msg: "the relative path must begin with /"
success_msg: "{{ 'relative path OK' }}"
- name: Validate configuration
ansible.builtin.assert:
that:
- (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
(not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
(not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
- (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or (not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
quiet: true
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' }}"
- 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
ansible.builtin.include_tasks: fastpackages.yml
vars:
packages_list: "{{ keycloak_quarkus_prereq_package_list }}"
packages_list:
- "{{ keycloak_quarkus_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_quarkus_configure_firewalld
tags:
- firewall

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
{{ ansible_managed | comment }}
# {{ ansible_managed }}
{% if keycloak_quarkus_db_enabled %}
# Database
@@ -54,14 +54,9 @@ cache-config-file=cache-ispn.xml
{% endif %}
{% if keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %}
# Deprecated Proxy configuration
# Proxy
proxy={{ keycloak_quarkus_proxy_mode }}
{% endif %}
{% if keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers != "none" %}
# Proxy
proxy-headers={{ keycloak_quarkus_proxy_headers }}
{% endif %}
spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }}
# Transaction

View File

@@ -1,11 +1,11 @@
{{ ansible_managed | comment }}
# {{ ansible_managed }}
[Unit]
Description=Keycloak Server
After=network.target
[Service]
Type=simple
EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }}
EnvironmentFile=-/etc/sysconfig/keycloak
PIDFile={{ keycloak_quarkus_service_pidfile }}
{% if keycloak_quarkus_start_dev %}
ExecStart={{ keycloak.home }}/bin/kc.sh start-dev

View File

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

View File

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

View File

@@ -1,11 +1,10 @@
---
keycloak: # noqa var-naming this is an internal dict of interpolated values
keycloak:
home: "{{ keycloak_quarkus_home }}"
config_dir: "{{ keycloak_quarkus_config_dir }}"
bundle: "{{ keycloak_quarkus_archive }}"
service_name: "keycloak"
health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' \
if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration"
health_url: "http://{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_http_port }}{{ keycloak_quarkus_http_relative_path }}{{ '/' if keycloak_quarkus_http_relative_path | length > 1 else '' }}realms/master/.well-known/openid-configuration"
cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh"
service_user: "{{ keycloak_quarkus_service_user }}"
service_group: "{{ keycloak_quarkus_service_group }}"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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