Merge pull request #9 from guidograzioli/prerelease_0.2.0

Prerelease 0.2.0
main
Guido Grazioli 2022-01-28 15:45:49 +01:00 committed by GitHub
commit 47751a2f39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 334 additions and 298 deletions

View File

@ -9,7 +9,8 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
@ -35,4 +36,18 @@ jobs:
env:
ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }}
run: |
ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY
ansible-galaxy collection publish *.tar.gz --api-key $ANSIBLE_GALAXY_API_KEY
dispatch:
needs: release
strategy:
matrix:
repo: ['ansible-middleware/cross-dc-rhsso-demo', 'ansible-middleware/flange-demo']
runs-on: ubuntu-latest
steps:
- name: Repository Dispatch
uses: peter-evans/repository-dispatch@v1
with:
token: ${{ secrets.TRIGGERING_PAT }}
repository: ${{ matrix.repo }}
event-type: "Dependency released - Keycloak"
client-payload: '{ "github": ${{toJson(github)}} }'

3
.gitignore vendored
View File

@ -1 +1,2 @@
*.tar.gz
*.tar.gz
*.zip

101
README.md
View File

@ -29,60 +29,87 @@ collections:
- name: middleware_automation.keycloak
```
The keycloak collection also depends on the following python packages to be present on the controller host:
* netaddr
A requirement file is provided to install:
pip install -r requirements.txt
### Included roles
* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service.
* [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service.
## Usage
### Install Playbook
`playbooks/keycloak.yml` installs the upstream(Keycloak) based on the defined variables.
`playbooks/rhsso.yml` installs Red Hat Single Sign-On(RHSSO) based on defined variables.
* [`playbooks/keycloak.yml`](playbooks/keycloak.yml) installs the upstream(Keycloak) based on the defined variables.
* [`playbooks/rhsso.yml`](playbooks/rhsso.yml) installs Red Hat Single Sign-On(RHSSO) based on defined variables.
### Choosing between upstream(Keycloak) project and Red Hat Single Sign-On(RHSSO)
Both playbooks include the `keycloak` role, with different settings, as described in the following sections.
The roles supports installing upstream(Keycloak) or Red Hat Single Sign-On in the following ways
For service configuration details, refer to the [keycloak role README](roles/keycloak/README.md).
#### Install upstream(Keycloak) from remote source
This is default approach, there is one required variable
### Choosing between upstream project (Keycloak) and Red Hat Single Sign-On (RHSSO)
```
keycloak_admin_password: "<changeme>"
```
The general flag `keycloak_rhsso_enable` controls what to install between upstream(Keycloak, when `False`) or Red Hat Single Sign-On (when `True`).
The default value for the flag if `True` when Red Hat Network credentials are defined, `False` otherwise.
#### Install upstream(Keycloak) from local source when the following variable is defined
```
keycloak_admin_password: "<changeme>"
zip_file_local_path: <keycloak zip file on Ansible control node local path>
```
#### Install upstream (Keycloak) from keycloak releases
#### Install RHSSO from the Red Hat Customer Support Portal, when the following variables are defined
This is the default approach when RHN credentials are not defined. Keycloak is downloaded from keycloak builds (hosted on github.com) locally, and distributed to target nodes.
```
keycloak_admin_password: "<changeme>"
#### Install RHSSO from the Red Hat Customer Support Portal
Define the credentials as follows, and the default behaviour is to download a fresh archive of RHSSO on the controller node, then distribute to target nodes.
```yaml
rhn_username: '<customer_portal_username>'
rhn_password: '<customer_portal_password>'
rhsso_rhn_id: '<sso_product_id>'
# (keycloak_rhsso_enable defaults to True)
```
where `sso_product_id` is the ID for the specific Red Hat Single Sign-On version, ie. _101971_ will install version _7.5_)
#### Install RHSSO from remote sources like Nexus etc, when the following variables are defined
#### Install from controller node (local source)
Making the keycloak zip archive (or the RHSSO zip archive), available to the playbook repository root directory, and setting `keycloak_offline_install` to `True`, allows to skip
the download tasks. The local path for the archive matches the downloaded archive path, so it is also used as a cache when multiple hosts are provisioned in a cluster.
```yaml
keycloak_offline_install: True
```
keycloak_admin_password: "<changeme>"
And depending on `keycloak_rhsso_enable`:
* `True`: install RHSSO using file rh-sso-x.y.z-server-dist.zip
* `False`: install keycloak using file keycloak-x.y.zip
#### Install from alternate sources (like corporate Nexus, artifactory, proxy, etc)
For RHSSO:
```yaml
keycloak_rhsso_enable: True
rhsso_source_download_url: '<url to download RHSSO zip file>'
keycloak_rhsso_download_url: "https://<internal-nexus.private.net>/<path>/<to>/rh-sso-x.y.z-server-dist.zip"
```
#### Install RHSSO from local source when the following variable is defined
For keycloak:
```
keycloak_admin_password: "<changeme>"
keycloak_rhsso_enable: True
zip_file_local_path: <rhsso zip file on Ansible control node local path>
```yaml
keycloak_rhsso_enable: False
keycloak_download_url: "https://<internal-nexus.private.net>/<path>/<to>/keycloak-x.y.zip"
```
### Install role
* [`keycloak`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak/README.md): role for installing the service. _Requires: python3-netaddr_
### Example installation command
@ -100,21 +127,20 @@ ansible-playbook -i <ansible_hosts> -e @rhn-creds.yml playbooks/keycloak.yml -e
localhost ansible_connection=local
```
## Configuration
### Config Playbook
`playbooks/keycloak-realm.yml` creates provided realm, user federation(s), client(s), client role(s) and client user(s) if they don't exist.
[`playbooks/keycloak-realm.yml`](playbooks/keycloak-realm.yml) creates provided realm, user federation(s), client(s), client role(s) and client user(s) if they don't exist.
### Config role
* [`keycloak_realm`](https://github.com/ansible-middleware/keycloak/blob/main/roles/keycloak_realm/README.md): role for configuring a realm, user federation(s), clients and users, in an installed service.
### Example configuration command
Execute the following command from the source root directory
```
```bash
ansible-playbook -i <ansible_hosts> playbooks/keycloak-realm.yml -e keycloak_admin_password=<changeme> -e keycloak_realm=test
```
@ -127,9 +153,12 @@ ansible-playbook -i <ansible_hosts> playbooks/keycloak-realm.yml -e keycloak_adm
localhost ansible_connection=local
```
For configuration details, refer to the [keycloak_realm role README](roles/keycloak_realm/README.md).
## License
Apache License v2.0 or later
See [LICENCE](LICENSE) to view the full text.
See [LICENSE](LICENSE) to view the full text.

View File

@ -1,6 +1,6 @@
namespace: middleware_automation
name: keycloak
version: "0.1.9"
version: "0.2.0"
readme: README.md
authors:
- Romain Pelisse <rpelisse@redhat.com>

6
requirements.txt 100644
View File

@ -0,0 +1,6 @@
#################################################
# python dependencies required to be installed
# on the controller host with:
# pip install -r requirements.txt
#
netaddr

View File

@ -11,6 +11,16 @@ This role requires the `python3-netaddr` library installed on the controller nod
* to install via yum/dnf: `dnf install python3-netaddr`
* or via pip: `pip install netaddr==0.8.0`
* or via the collection: `pip install -r requirements.txt`
Dependencies
------------
The roles depends on:
* the `redhat_csp_download` role from [middleware_automation.redhat_csp_download](https://github.com/ansible-middleware/redhat-csp-download) collection if Red Hat Single Sign-on zip have to be downloaded from RHN.
* the `wildfly_driver` role from [middleware_automation.wildfly](https://github.com/ansible-middleware/wildfly) collection
Versions
@ -24,9 +34,10 @@ Versions
Role Defaults
-------------
* Service configuration
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_rhsso_enable`| Enable Red Hat Single Sign-on installation | `False` |
|`keycloak_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|`keycloak_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_ha_enabled` is True, else `False` |
|`keycloak_admin_user`| Administration console user account | `admin` |
@ -34,13 +45,32 @@ Role Defaults
|`keycloak_host`| hostname | `localhost` |
|`keycloak_http_port`| HTTP port | `8080` |
|`keycloak_https_port`| TLS HTTP port | `8443` |
|`keycloak_ajp_port`| AJP port | `8009` |
|`keycloak_jgroups_port`| jgroups cluster tcp port | `7600` |
|`keycloak_management_http_port`| Management port | `9990` |
|`keycloak_management_https_port`| TLS management port | `9993` |
|`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` |
|`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` |
|`keycloak_service_user`| posix account username | `keycloak` |
|`keycloak_service_group`| posix account group | `keycloak` |
|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` |
|`jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` |
* Install options
| Variable | Description | Default |
|:---------|:------------|:---------|
|`keycloak_rhsso_enable`| Enable Red Hat Single Sign-on installation | `False` |
|`keycloak_offline_install` | perform an offline install | `False`|
|`keycloak_download_url`| Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/<version>/<archive>`|
|`keycloak_rhsso_download_url`| Download URL for RHSSO | `https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=<productID>`|
|`keycloak_version`| keycloak.org package version | `15.0.2` |
|`keycloak_rhsso_version`| RHSSO version | `7.5.0` |
|`keycloak_dest`| Installation root path | `/opt/keycloak` |
Role Variables
--------------
@ -76,29 +106,14 @@ The following variables are _required_ only when `keycloak_db_enabled` is True:
|`keycloak_db_user` | username for connecting to postgres | `keycloak-user` |
|`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` |
The following variable can be used to install Keycloak or Red Hat Single Sign-On from local path:
| Variable | Description | Example |
|:---------|:------------|:---------|
|`zip_file_local_path` | Full local path of upstream(Keycloak) or Red Hat Single Sign-On zip file on Ansible control plane | `tmp/rhsso/rh-sso-7.5-server-dist.zip` |
The following variable can be used to install Red Hat Single Sign-On from source via url, auth support is not added right now.
| Variable | Description | Example |
|:---------|:------------|:---------|
|`rhsso_source_download_url` | URL to download Red Hat Single Sign-On zip file from source | `http://localhost:8081/nexus/rhsso/rh-sso-7.5-server-dist.zip` |
Example Playbooks
-----------------
Dependencies
------------
The roles depends on:
* the redhat_csp_download role from [middleware_automation.redhat_csp_download](https://github.com/ansible-middleware/redhat-csp-download) collection if Red Hat Single Sign-on zip have to be downloaded from RHN.
* the wildfly_driver role from [middleware_automation.wildfly](https://github.com/ansible-middleware/wildfly) collection
_NOTE_: use ansible vaults or other security systems for storing credentials.
Example Playbook
----------------
The following is an example playbook that makes use of the role to install keycloak from remote
* The following is an example playbook that makes use of the role to install keycloak from remote:
```yaml
---
@ -113,23 +128,7 @@ The following is an example playbook that makes use of the role to install keycl
keycloak_admin_password: "changeme"
```
The following is an example playbook that makes use of the role to install keycloak from local path on Ansible node
```yaml
---
- hosts: ...
collections:
- middleware_automation.keycloak
tasks:
- name: Include keycloak role
include_role:
name: keycloak
vars:
keycloak_admin_password: "changeme"
zip_file_local_path: "/tmp/keycloak/keycloak-16.1.0.zip" # This should be local path on Ansible node of upstream(keycloak) zip file
```
The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from RHN
* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from RHN:
```yaml
---
@ -146,9 +145,30 @@ The following is an example playbook that makes use of the role to install Red H
vars:
keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True
rhn_username: '<customer portal username>'
rhn_password: '<customer portal password>'
```
The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from source url
* The following example playbook makes use of the role to install keycloak from the controller node:
```yaml
---
- hosts: ...
collections:
- middleware_automation.keycloak
tasks:
- name: Include keycloak role
include_role:
name: keycloak
vars:
keycloak_admin_password: "changeme"
keycloak_offline_install: True
# This should be the filename of keycloak archive on Ansible node: keycloak-16.1.0.zip
```
* This playbook installs Red Hat Single Sign-On from an alternate url:
```yaml
---
@ -162,10 +182,12 @@ The following is an example playbook that makes use of the role to install Red H
vars:
keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True
rhsso_source_download_url: "<REPLACE with - Source download url>" # This should be the full of remote source rhsso zip file
keycloak_rhsso_download_url: "<REPLACE with download url>"
# This should be the full of remote source rhsso zip file and can contain basic authentication credentials
```
The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from local path on Ansible node
* The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from the controller node:
```yaml
---
@ -179,7 +201,8 @@ The following is an example playbook that makes use of the role to install Red H
vars:
keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True
zip_file_local_path: "/tmp/rhsso/rh-sso-7.5-server-dist.zip" # This should be local path on Ansible node of rhsso zip file
keycloak_offline_install: True
# This should be the filename of rhsso zip file on Ansible node: rh-sso-7.5-server-dist.zip
```
License

View File

@ -7,31 +7,36 @@ keycloak_download_url_9x: "https://downloads.jboss.org/keycloak/{{ keycloak_vers
keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}"
### Configuration specific to Red Hat Single Sing-On
keycloak_rhsso_enable: False
keycloak_rhsso_version: 7.5
keycloak_rhsso_version: 7.5.0
rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version] }}"
keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip"
keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version }}"
keycloak_rhsso_base_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId='
keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}"
keycloak_rhn_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId='
keycloak_rhsso_download_url: "{{ keycloak_rhn_url }}{{ rhsso_rhn_id }}"
### keycloak/rhsso choice: by default install rhsso if rhn credentials are defined
keycloak_rhsso_enable: "{{ True if rhsso_rhn_id is defined and rhn_username is defined and rhn_password is defined else False }}"
# whether to install from local archive; filename must be keycloak_archive or keycloak_rhsso_archive depending on keycloak_rhsso_enable
keycloak_offline_install: False
### Install location and service settings
jvm_package: java-1.8.0-openjdk-devel
keycloak_dest: /opt/keycloak
keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}"
keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration"
keycloak_config_standalone_xml: "keycloak.xml"
keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}"
keycloak_service_user: keycloak
keycloak_service_group: keycloak
keycloak_service_pidfile: "/run/keycloak.pid"
keycloak_service_logfile: "{{ keycloak_dest }}/keycloak.log"
### Keycloak configuration settings
### Common configuration settings
keycloak_bind_address: 0.0.0.0
keycloak_host: localhost
keycloak_http_port: 8080
keycloak_https_port: 8443
keycloak_ajp_port: 8009
keycloak_jgroups_port: 7600
keycloak_management_http_port: 9990
keycloak_management_https_port: 9993
keycloak_java_opts: "-Xms1024m -Xmx2048m"

View File

@ -24,5 +24,5 @@
- "{{ keycloak_https_port }}/tcp"
- "{{ keycloak_management_http_port }}/tcp"
- "{{ keycloak_management_https_port }}/tcp"
- "7600/tcp"
- "8009/tcp"
- "{{ keycloak_jgroups_port }}/tcp"
- "{{ keycloak_ajp_port }}/tcp"

View File

@ -1,104 +0,0 @@
---
- assert:
that:
- zipfile_dest is defined
- keycloak_rhsso_enable
quiet: true
- set_fact:
rhn_download_url: "{{ keycloak_rhsso_base_url }}{{ rhsso_rhn_id }}"
when:
- rhsso_rhn_id is defined
- name: "Check zipfile dest directory {{ zipfile_dest }}"
stat:
path: "{{ zipfile_dest }}"
register: archive_path
- name: "Download zipfile from RHN: {{ rhn_download_url }}"
redhat_csp_download:
url: "{{ rhn_download_url }}"
dest: "{{ zipfile_dest }}"
username: "{{ rhn_username }}"
password: "{{ rhn_password }}"
no_log: "{{ omit_rhn_output | default(true) }}"
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- rhn_username is defined
- rhn_password is defined
- rhsso_rhn_id is defined
- name: "Copy zipfile from source like Nexus etc : {{ rhsso_source_download_url }}"
get_url:
url: "{{ rhsso_source_download_url }}"
dest: "{{ zipfile_dest }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- rhsso_source_download_url is defined
- name: "Copy zipfile from local source: {{ zip_file_local_path }}"
ansible.builtin.copy:
src: "{{ zip_file_local_path }}"
dest: "{{ zipfile_dest }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- zip_file_local_path is defined
- name: "Check zipfile dest directory {{ zipfile_dest }}"
stat:
path: "{{ zipfile_dest }}"
register: path_to_downloaded_artifact
- block:
- file:
path: "{{ work_dir }}"
state: directory
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
- name: "Check directory {{ target_dir }}"
stat:
path: "{{ target_dir }}"
register: target_dir_state
- assert:
that:
- target_dir_state is defined
- target_dir_state.stat is defined
fail_msg: "Directory layout for {{ target_dir }} is invalid."
quiet: true
- name: "Decompress {{ zipfile_dest }} into {{ work_dir }} (results in {{ target_dir }}."
unarchive:
src: "{{ zipfile_dest }}"
dest: "{{ work_dir }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_user }}"
remote_src: yes
creates: "{{ target_dir }}"
when:
- not target_dir_state.stat.exists
- debug:
msg: "{{ target_dir }} already exists, skipping decompressing {{ zipfile_dest }}"
when:
- target_dir_state.stat.exists
when:
- path_to_downloaded_artifact is defined
- path_to_downloaded_artifact.stat is defined
- path_to_downloaded_artifact.stat.exists
- target_dir is defined
- work_dir is defined

View File

@ -1,5 +1,6 @@
---
- assert:
- name: Validate parameters
assert:
that:
- keycloak_jboss_home is defined
- keycloak_service_user is defined
@ -9,25 +10,20 @@
- keycloak_version is defined
quiet: true
- set_fact:
keycloak_service_group: "{{ keycloak_service_user }}"
when:
- not keycloak_service_group is defined
- name: check for an existing deployment
- name: Check for an existing deployment
become: yes
stat:
path: "{{ keycloak_jboss_home }}"
register: existing_deploy
- block:
- name: stop the old keycloak service
- name: Stop the old keycloak service
become: yes
ignore_errors: yes
systemd:
name: keycloak
state: stopped
- name: remove the old Keycloak deployment
- name: Remove the old Keycloak deployment
become: yes
file:
path: "{{ keycloak_jboss_home }}"
@ -56,75 +52,111 @@
group: "{{ keycloak_service_group }}"
mode: 0750
- block:
- set_fact:
archive: "{{ keycloak_dest }}/{{ keycloak_archive }}"
- name: "Check archive directory {{ archive }}"
stat:
path: "{{ archive }}"
register: archive_path
## check remote archive
- name: Set download archive path
set_fact:
archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}"
- name: download Keycloak archive to target
get_url:
url: "{{ keycloak_download_url }}"
dest: "{{ keycloak_dest }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- not keycloak_rhsso_enable and not zip_file_local_path is defined
- name: Check download archive path
stat:
path: "{{ archive }}"
register: archive_path
- name: "Copy zipfile from local source: {{ zip_file_local_path }}"
ansible.builtin.copy:
src: "{{ zip_file_local_path }}"
dest: "{{ keycloak_dest }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- not keycloak_rhsso_enable and zip_file_local_path is defined
## download to controller
- name: Check load download archive path
stat:
path: "{{ lookup('env', 'PWD') }}"
register: local_path
delegate_to: localhost
- name: extract Keycloak archive on target
unarchive:
remote_src: yes
src: "{{ archive }}"
dest: "{{ keycloak_dest }}"
creates: "{{ keycloak_jboss_home }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
notify:
- restart keycloak
- name: Download keycloak archive
get_url:
url: "{{ keycloak_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
delegate_to: localhost
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- not keycloak_rhsso_enable
- not keycloak_offline_install
- name: Performing download from RHN
redhat_csp_download:
url: "{{ keycloak_rhsso_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
username: "{{ rhn_username }}"
password: "{{ rhn_password }}"
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- keycloak_rhsso_enable
- not keycloak_offline_install
- keycloak_rhn_url in keycloak_rhsso_download_url
- name: Download rhsso archive from alternate location
get_url:
url: "{{ keycloak_rhsso_download_url }}"
dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
delegate_to: localhost
when:
- archive_path is defined
- archive_path.stat is defined
- not archive_path.stat.exists
- keycloak_rhsso_enable
- not keycloak_offline_install
- not keycloak_rhn_url in keycloak_rhsso_download_url
## copy and unpack
- name: Copy archive to target nodes
copy:
src: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
dest: "{{ archive }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
register: new_version_downloaded
become: yes
when: not keycloak_rhsso_enable
- block:
- assert:
that:
- rhsso_rhn_id is defined or zip_file_local_path is defined
quiet: true
fail_msg: "Can't install RHSSO without either RHN ID or RHSSO zip file located on Ansible node"
- name: create download directory
file:
path: /opt/apps
state: directory
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
mode: 0750
- include_tasks: get_rhsso.yml
vars:
zipfile_dest: "{{ keycloak_dest }}/{{ keycloak_rhsso_archive }}"
work_dir: "{{ keycloak_dest }}"
target_dir: "{{ keycloak_jboss_home }}"
- name: "Check target directory: {{ keycloak.home }}"
stat:
path: "{{ keycloak.home }}"
register: path_to_workdir
become: yes
when: keycloak_rhsso_enable
- name: "Extract {{ 'Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Keycloak' }} archive on target"
unarchive:
remote_src: yes
src: "{{ archive }}"
dest: "{{ keycloak_dest }}"
creates: "{{ keycloak.home }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
become: yes
when:
- new_version_downloaded.changed or not path_to_workdir.stat.exists
notify:
- restart keycloak
- name: Inform decompression was not executed
debug:
msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression"
when:
- not new_version_downloaded.changed and path_to_workdir.stat.exists
- name: "Reown installation directory to {{ keycloak_service_user }}"
file:
path: "{{ keycloak.home }}"
owner: "{{ keycloak_service_user }}"
group: "{{ keycloak_service_group }}"
recurse: true
become: yes
changed_when: false
# driver and configuration
- name: "Install {{ keycloak_jdbc_engine }} driver"
include_role:
name: wildfly_driver
@ -139,7 +171,7 @@
jdbc_driver_module_name: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}"
when: keycloak_jdbc[keycloak_jdbc_engine].enabled
- name: "Deploy Keycloak's standalone.xml"
- name: "Deploy {{ keycloak.service_name }} config to {{ keycloak_config_path_to_standalone_xml }}"
become: yes
template:
src: templates/standalone.xml.j2
@ -151,7 +183,7 @@
- restart keycloak
when: not keycloak_remotecache.enabled
- name: "Deploy Keycloak's standalone.xml with remote cache store"
- name: "Deploy {{ keycloak.service_name }} config with remote cache store to {{ keycloak_config_path_to_standalone_xml }}"
become: yes
template:
src: templates/standalone-infinispan.xml.j2

View File

@ -15,7 +15,7 @@
- name: Link default logs directory
file:
state: link
src: "{{keycloak_jboss_home}}/standalone/log"
src: "{{ keycloak_jboss_home }}/standalone/log"
dest: /var/log/keycloak
- block:
@ -30,7 +30,7 @@
retries: 2
delay: 2
rescue:
- name: create Keycloak admin user
- name: "Create {{ keycloak.service_name }} admin user"
command:
args:
argv:
@ -39,11 +39,11 @@
- "-u{{ keycloak_admin_user }}"
- "-p{{ keycloak_admin_password }}"
become: yes
- name: restart keycloak
- name: "Restart {{ keycloak.service_name }}"
include_tasks: tasks/restart_keycloak.yml
- name: "Wait until Keycloak becomes active {{ health_url }}"
- name: "Wait until {{ keycloak.service_name }} becomes active {{ keycloak.health_url }}"
uri:
url: "{{ health_url }}"
url: "{{ keycloak.health_url }}"
register: keycloak_status
until: keycloak_status.status == 200
retries: 25

View File

@ -10,11 +10,11 @@
- name: Validate credentials
assert:
that:
- (rhn_username is defined and rhsso_rhn_id is defined) or rhsso_rhn_id is not defined
- (rhn_password is defined and rhsso_rhn_id is defined) or rhsso_rhn_id is not defined
- (rhn_username is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install
- (rhn_password is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install
quiet: True
fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined"
success_msg: "{{ 'Installing Red Hat Single Sign-On' if rhsso_rhn_id is defined else 'Installing keycloak.org' }}"
success_msg: "{{ 'Installing Red Hat Single Sign-On' if keycloak_rhsso_enable else 'Installing keycloak.org' }}"
- name: Set required packages facts
set_fact:

View File

@ -38,9 +38,6 @@
daemon_reload: yes
when: systemdunit.changed
- set_fact:
health_url: "{{ keycloak_management_url }}/health"
- name: start keycloak
systemd:
name: keycloak
@ -48,20 +45,22 @@
state: started
become: yes
- command: "systemctl status keycloak"
- name: Check service status
command: "systemctl status keycloak"
register: keycloak_service_status
changed_when: False
- assert:
- name: Verify service status
assert:
that:
- keycloak_service_status is defined
- keycloak_service_status.stdout is defined
- meta: flush_handlers
- name: "Wait until Keycloak becomes active {{ health_url }}"
- name: "Wait until Keycloak becomes active {{ keycloak.health_url }}"
uri:
url: "{{ health_url }}"
url: "{{ keycloak.health_url }}"
register: keycloak_status
until: keycloak_status.status == 200
retries: 25

View File

@ -1,4 +1,5 @@
#!/bin/bash -eu
# {{ ansible_managed }}
set +u -o pipefail
@ -22,7 +23,6 @@ readonly KEYCLOAK_HTTP_PORT=${KEYCLOAK_HTTP_PORT}
readonly KEYCLOAK_HTTPS_PORT=${KEYCLOAK_HTTPS_PORT}
readonly KEYCLOAK_MANAGEMENT_HTTP_PORT=${KEYCLOAK_MANAGEMENT_HTTP_PORT}
readonly KEYCLOAK_MANAGEMENT_HTTPS_PORT=${KEYCLOAK_MANAGEMENT_HTTPS_PORT}
readonly KEYCLOAK_LOGFILE={{ keycloak_service_logfile }}
readonly KEYCLOAK_PIDFILE={{ keycloak_service_pidfile }}
set -u
@ -70,7 +70,6 @@ startKeycloak() {
checkEnvVar "${KEYCLOAK_HTTPS_PORT}" 'KEYCLOAK_HTTPS_PORT not provided' 5
checkEnvVar "${KEYCLOAK_MANAGEMENT_HTTP_PORT}" 'KEYCLOAK_MANAGEMENT_HTTP_PORT not provided' 6
checkEnvVar "${KEYCLOAK_MANAGEMENT_HTTPS_PORT}" 'KEYCLOAK_MANAGEMENT_HTTPS_PORT not provided' 7
checkEnvVar "${KEYCLOAK_LOGFILE}" 'KEYCLOAK_LOGFILE not provided' 8
if [ "$(isKeyCloakRunning)" -eq 1 ]; then
statusKeycloak

View File

@ -1,3 +1,4 @@
# {{ ansible_managed }}
JAVA_OPTS='{{ keycloak_java_opts }}'
JBOSS_HOME={{ keycloak_jboss_home }}
KEYCLOAK_BIND_ADDRESS={{ keycloak_bind_address }}

View File

@ -1,3 +1,4 @@
# {{ ansible_managed }}
[Unit]
Description=Keycloak Server
After=network.target

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
@ -738,12 +738,12 @@
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="jgroups-tcp" interface="jgroups" port="7600"/>
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
<socket-binding name="jgroups-tcp" interface="jgroups" port="{{ keycloak_jgroups_port }}"/>
<socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
@ -139,14 +139,32 @@
</security>
</datasource>
<datasource jndi-name="java:jboss/datasources/KeycloakDS" pool-name="KeycloakDS" enabled="true" use-java-context="true" statistics-enabled="${wildfly.datasources.statistics-enabled:${wildfly.statistics-enabled:false}}">
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
<connection-url>{{ keycloak_jdbc[keycloak_jdbc_engine].connection_url }}</connection-url>
<driver>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}</driver>
<pool>
<max-pool-size>20</max-pool-size>
</pool>
<security>
<user-name>{{ keycloak_jdbc[keycloak_jdbc_engine].db_user }}</user-name>
<password>{{ keycloak_jdbc[keycloak_jdbc_engine].db_password }}</password>
</security>
{% else %}
<connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
{% endif %}
</datasource>
<drivers>
{% if keycloak_jdbc[keycloak_jdbc_engine].enabled %}
<driver name="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" module="{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}">
<driver-class>{{ keycloak_jdbc[keycloak_jdbc_engine].driver_class }}</driver-class>
<xa-datasource-class>{{ keycloak_jdbc[keycloak_jdbc_engine].xa_datasource_class }}</xa-datasource-class>
</driver>
{% endif %}
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
@ -621,11 +639,11 @@
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="{{ keycloak_https_port }}"/>
<socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
<socket-binding name="management-https" interface="management" port="{{ keycloak_management_https_port }}"/>
<socket-binding name="modcluster" multicast-address="${jboss.modcluster.multicast.address:224.0.1.105}" multicast-port="23364"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>

View File

@ -4,11 +4,22 @@
keycloak_admin_password:
# internal variables below
rhsso_rhn_ids:
'7.5.0': '101971'
'7.5.1': '103836'
# locations
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_http_port }}"
keycloak:
home: "{{ keycloak_jboss_home }}"
config_dir: "{{ keycloak_config_dir }}"
bundle: "{{ keycloak_rhsso_archive if keycloak_rhsso_enable else keycloak_archive }}"
service_name: "{{ 'rhsso' if keycloak_rhsso_enable else 'keycloak' }}"
health_url: "{{ keycloak_management_url }}/health"
# database
keycloak_jdbc:
postgres: