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: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - name: Checkout code
uses: actions/checkout@v2
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v1 uses: actions/setup-python@v1
with: with:
@ -36,3 +37,17 @@ jobs:
ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }} ANSIBLE_GALAXY_API_KEY: ${{ secrets.ANSIBLE_GALAXY_API_KEY }}
run: | 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)}} }'

1
.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 - 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 ### Install Playbook
`playbooks/keycloak.yml` installs the upstream(Keycloak) based on the defined variables. * [`playbooks/keycloak.yml`](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/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)
``` The general flag `keycloak_rhsso_enable` controls what to install between upstream(Keycloak, when `False`) or Red Hat Single Sign-On (when `True`).
keycloak_admin_password: "<changeme>" 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
``` #### Install upstream (Keycloak) from keycloak releases
keycloak_admin_password: "<changeme>"
zip_file_local_path: <keycloak zip file on Ansible control node local path>
```
#### 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_username: '<customer_portal_username>'
rhn_password: '<customer_portal_password>' 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 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:
``` ```yaml
keycloak_admin_password: "<changeme>" keycloak_rhsso_enable: False
keycloak_rhsso_enable: True keycloak_download_url: "https://<internal-nexus.private.net>/<path>/<to>/keycloak-x.y.zip"
zip_file_local_path: <rhsso zip file on Ansible control node local path>
``` ```
### 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 ### Example installation command
@ -100,21 +127,20 @@ ansible-playbook -i <ansible_hosts> -e @rhn-creds.yml playbooks/keycloak.yml -e
localhost ansible_connection=local localhost ansible_connection=local
``` ```
## Configuration ## Configuration
### Config Playbook ### 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 ### Example configuration command
Execute the following command from the source root directory 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 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 localhost ansible_connection=local
``` ```
For configuration details, refer to the [keycloak_realm role README](roles/keycloak_realm/README.md).
## License ## License
Apache License v2.0 or later 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 namespace: middleware_automation
name: keycloak name: keycloak
version: "0.1.9" version: "0.2.0"
readme: README.md readme: README.md
authors: authors:
- Romain Pelisse <rpelisse@redhat.com> - 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` * to install via yum/dnf: `dnf install python3-netaddr`
* or via pip: `pip install netaddr==0.8.0` * or via pip: `pip install netaddr==0.8.0`
* or via the collection: `pip install -r requirements.txt`
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 Versions
@ -24,9 +34,10 @@ Versions
Role Defaults Role Defaults
------------- -------------
* Service configuration
| Variable | Description | Default | | 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_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_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` | |`keycloak_admin_user`| Administration console user account | `admin` |
@ -34,13 +45,32 @@ Role Defaults
|`keycloak_host`| hostname | `localhost` | |`keycloak_host`| hostname | `localhost` |
|`keycloak_http_port`| HTTP port | `8080` | |`keycloak_http_port`| HTTP port | `8080` |
|`keycloak_https_port`| TLS HTTP port | `8443` | |`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_http_port`| Management port | `9990` |
|`keycloak_management_https_port`| TLS management port | `9993` | |`keycloak_management_https_port`| TLS management port | `9993` |
|`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` | |`keycloak_java_opts`| Additional JVM options | `-Xms1024m -Xmx2048m` |
|`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` | |`keycloak_prefer_ipv4`| Prefer IPv4 stack and addresses for port binding | `True` |
|`keycloak_config_standalone_xml`| filename for configuration | `keycloak.xml` |
|`keycloak_service_user`| posix account username | `keycloak` |
|`keycloak_service_group`| posix account group | `keycloak` |
|`keycloak_service_pidfile`| pid file path for service | `/run/keycloak.pid` |
|`jvm_package`| RHEL java package runtime | `java-1.8.0-openjdk-devel` | |`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 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_user` | username for connecting to postgres | `keycloak-user` |
|`keycloak_db_pass` | password for connecting to postgres | `keycloak-pass` | |`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. Example Playbooks
| 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` |
Dependencies _NOTE_: use ansible vaults or other security systems for storing credentials.
------------
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
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 ```yaml
--- ---
@ -113,23 +128,7 @@ The following is an example playbook that makes use of the role to install keycl
keycloak_admin_password: "changeme" 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 * The following is an example playbook that makes use of the role to install Red Hat Single Sign-On from RHN:
```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
```yaml ```yaml
--- ---
@ -146,9 +145,30 @@ The following is an example playbook that makes use of the role to install Red H
vars: vars:
keycloak_admin_password: "changeme" keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True 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 ```yaml
--- ---
@ -162,10 +182,12 @@ The following is an example playbook that makes use of the role to install Red H
vars: vars:
keycloak_admin_password: "changeme" keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True 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 ```yaml
--- ---
@ -179,7 +201,8 @@ The following is an example playbook that makes use of the role to install Red H
vars: vars:
keycloak_admin_password: "changeme" keycloak_admin_password: "changeme"
keycloak_rhsso_enable: True 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 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 }}" keycloak_installdir: "{{ keycloak_dest }}/keycloak-{{ keycloak_version }}"
### Configuration specific to Red Hat Single Sing-On ### Configuration specific to Red Hat Single Sing-On
keycloak_rhsso_enable: False keycloak_rhsso_version: 7.5.0
keycloak_rhsso_version: 7.5 rhsso_rhn_id: "{{ rhsso_rhn_ids[keycloak_rhsso_version] }}"
keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip" keycloak_rhsso_archive: "rh-sso-{{ keycloak_rhsso_version }}-server-dist.zip"
keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version }}" keycloak_rhsso_installdir: "{{ keycloak_dest }}/rh-sso-{{ keycloak_rhsso_version | regex_replace('^([0-9])\\.([0-9]*).*', '\\1.\\2') }}"
keycloak_rhsso_base_url: 'https://access.redhat.com/jbossnetwork/restricted/softwareDownload.html?softwareId=' 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 ### Install location and service settings
jvm_package: java-1.8.0-openjdk-devel jvm_package: java-1.8.0-openjdk-devel
keycloak_dest: /opt/keycloak keycloak_dest: /opt/keycloak
keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}" keycloak_jboss_home: "{{ keycloak_rhsso_installdir if keycloak_rhsso_enable else keycloak_installdir }}"
keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration" keycloak_config_dir: "{{ keycloak_jboss_home }}/standalone/configuration"
keycloak_config_standalone_xml: "keycloak.xml" keycloak_config_standalone_xml: "keycloak.xml"
keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}" keycloak_config_path_to_standalone_xml: "{{ keycloak_jboss_home }}/standalone/configuration/{{ keycloak_config_standalone_xml }}"
keycloak_service_user: keycloak keycloak_service_user: keycloak
keycloak_service_group: keycloak keycloak_service_group: keycloak
keycloak_service_pidfile: "/run/keycloak.pid" 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_bind_address: 0.0.0.0
keycloak_host: localhost keycloak_host: localhost
keycloak_http_port: 8080 keycloak_http_port: 8080
keycloak_https_port: 8443 keycloak_https_port: 8443
keycloak_ajp_port: 8009
keycloak_jgroups_port: 7600
keycloak_management_http_port: 9990 keycloak_management_http_port: 9990
keycloak_management_https_port: 9993 keycloak_management_https_port: 9993
keycloak_java_opts: "-Xms1024m -Xmx2048m" keycloak_java_opts: "-Xms1024m -Xmx2048m"

View File

@ -24,5 +24,5 @@
- "{{ keycloak_https_port }}/tcp" - "{{ keycloak_https_port }}/tcp"
- "{{ keycloak_management_http_port }}/tcp" - "{{ keycloak_management_http_port }}/tcp"
- "{{ keycloak_management_https_port }}/tcp" - "{{ keycloak_management_https_port }}/tcp"
- "7600/tcp" - "{{ keycloak_jgroups_port }}/tcp"
- "8009/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: that:
- keycloak_jboss_home is defined - keycloak_jboss_home is defined
- keycloak_service_user is defined - keycloak_service_user is defined
@ -9,25 +10,20 @@
- keycloak_version is defined - keycloak_version is defined
quiet: true quiet: true
- set_fact: - name: Check for an existing deployment
keycloak_service_group: "{{ keycloak_service_user }}"
when:
- not keycloak_service_group is defined
- name: check for an existing deployment
become: yes become: yes
stat: stat:
path: "{{ keycloak_jboss_home }}" path: "{{ keycloak_jboss_home }}"
register: existing_deploy register: existing_deploy
- block: - block:
- name: stop the old keycloak service - name: Stop the old keycloak service
become: yes become: yes
ignore_errors: yes ignore_errors: yes
systemd: systemd:
name: keycloak name: keycloak
state: stopped state: stopped
- name: remove the old Keycloak deployment - name: Remove the old Keycloak deployment
become: yes become: yes
file: file:
path: "{{ keycloak_jboss_home }}" path: "{{ keycloak_jboss_home }}"
@ -56,75 +52,111 @@
group: "{{ keycloak_service_group }}" group: "{{ keycloak_service_group }}"
mode: 0750 mode: 0750
- block: ## check remote archive
- set_fact: - name: Set download archive path
archive: "{{ keycloak_dest }}/{{ keycloak_archive }}" set_fact:
- name: "Check archive directory {{ archive }}" archive: "{{ keycloak_dest }}/{{ keycloak.bundle }}"
stat:
path: "{{ archive }}"
register: archive_path
- name: download Keycloak archive to target - name: Check download archive path
get_url: stat:
url: "{{ keycloak_download_url }}" path: "{{ archive }}"
dest: "{{ keycloak_dest }}" register: archive_path
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: "Copy zipfile from local source: {{ zip_file_local_path }}" ## download to controller
ansible.builtin.copy: - name: Check load download archive path
src: "{{ zip_file_local_path }}" stat:
dest: "{{ keycloak_dest }}" path: "{{ lookup('env', 'PWD') }}"
owner: "{{ keycloak_service_user }}" register: local_path
group: "{{ keycloak_service_group }}" delegate_to: localhost
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
- name: extract Keycloak archive on target - name: Download keycloak archive
unarchive: get_url:
remote_src: yes url: "{{ keycloak_download_url }}"
src: "{{ archive }}" dest: "{{ local_path.stat.path }}/{{ keycloak.bundle }}"
dest: "{{ keycloak_dest }}" delegate_to: localhost
creates: "{{ keycloak_jboss_home }}" when:
owner: "{{ keycloak_service_user }}" - archive_path is defined
group: "{{ keycloak_service_group }}" - archive_path.stat is defined
notify: - not archive_path.stat.exists
- restart keycloak - 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 become: yes
when: not keycloak_rhsso_enable
- block: - name: "Check target directory: {{ keycloak.home }}"
- assert: stat:
that: path: "{{ keycloak.home }}"
- rhsso_rhn_id is defined or zip_file_local_path is defined register: path_to_workdir
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 }}"
become: yes 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" - name: "Install {{ keycloak_jdbc_engine }} driver"
include_role: include_role:
name: wildfly_driver name: wildfly_driver
@ -139,7 +171,7 @@
jdbc_driver_module_name: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}" jdbc_driver_module_name: "{{ keycloak_jdbc[keycloak_jdbc_engine].driver_module_name }}"
when: keycloak_jdbc[keycloak_jdbc_engine].enabled 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 become: yes
template: template:
src: templates/standalone.xml.j2 src: templates/standalone.xml.j2
@ -151,7 +183,7 @@
- restart keycloak - restart keycloak
when: not keycloak_remotecache.enabled 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 become: yes
template: template:
src: templates/standalone-infinispan.xml.j2 src: templates/standalone-infinispan.xml.j2

View File

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

View File

@ -10,11 +10,11 @@
- name: Validate credentials - name: Validate credentials
assert: assert:
that: that:
- (rhn_username 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 rhsso_rhn_id is defined) or rhsso_rhn_id is not defined - (rhn_password is defined and keycloak_rhsso_enable) or not keycloak_rhsso_enable or keycloak_offline_install
quiet: True quiet: True
fail_msg: "Cannot install Red Hat SSO without RHN credentials. Check rhn_username and rhn_password are defined" 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 - name: Set required packages facts
set_fact: set_fact:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<!-- {{ ansible_managed }} -->
<server xmlns="urn:jboss:domain:16.0"> <server xmlns="urn:jboss:domain:16.0">
<extensions> <extensions>
<extension module="org.jboss.as.clustering.infinispan"/> <extension module="org.jboss.as.clustering.infinispan"/>
@ -139,14 +139,32 @@
</security> </security>
</datasource> </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}}"> <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> <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
<driver>h2</driver> <driver>h2</driver>
<security> <security>
<user-name>sa</user-name> <user-name>sa</user-name>
<password>sa</password> <password>sa</password>
</security> </security>
{% endif %}
</datasource> </datasource>
<drivers> <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"> <driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver> </driver>
@ -621,11 +639,11 @@
</interface> </interface>
</interfaces> </interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/> <socket-binding name="ajp" port="{{ keycloak_ajp_port }}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/> <socket-binding name="http" port="{{ keycloak_http_port }}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/> <socket-binding name="https" port="{{ keycloak_https_port }}"/>
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> <socket-binding name="management-http" interface="management" port="{{ keycloak_management_http_port }}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/> <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="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-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/> <socket-binding name="txn-status-manager" port="4713"/>

View File

@ -4,11 +4,22 @@
keycloak_admin_password: keycloak_admin_password:
# internal variables below # internal variables below
rhsso_rhn_ids:
'7.5.0': '101971'
'7.5.1': '103836'
# locations # locations
keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}" keycloak_url: "http://{{ keycloak_host }}:{{ keycloak_http_port }}"
keycloak_management_url: "http://{{ keycloak_host }}:{{ keycloak_management_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 # database
keycloak_jdbc: keycloak_jdbc:
postgres: postgres: