Vendor middleware_automation.keycloak collection
Needed for keycloak_authentication_v2, to manage Keycloak authentication flows (e.g. the CCCHH browser flow) as YAML. Chosen over community.general's own copy of the module (deprecated in favor of this collection, and limited to 4 sub-flow levels there vs. 10 here).
This commit is contained in:
parent
4540dc5516
commit
4832e5da5d
159 changed files with 34399 additions and 0 deletions
|
|
@ -0,0 +1,314 @@
|
|||
keycloak_quarkus
|
||||
================
|
||||
<!--start description -->
|
||||
Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurations.
|
||||
<!--end description -->
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
This role requires the `python3-netaddr` and `lxml` library installed on the controller node.
|
||||
|
||||
* to install via yum/dnf: `dnf install python3-netaddr python3-lxml`
|
||||
* to install via apt: `apt install python3-netaddr python3-lxml`
|
||||
* or via the collection: `pip install -r requirements.txt`
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The roles depends on:
|
||||
|
||||
* [middleware_automation.common](https://github.com/ansible-middleware/common)
|
||||
* [ansible-posix](https://docs.ansible.com/ansible/latest/collections/ansible/posix/index.html)
|
||||
|
||||
To install all the dependencies via galaxy:
|
||||
|
||||
ansible-galaxy collection install -r requirements.yml
|
||||
|
||||
Role Defaults
|
||||
-------------
|
||||
|
||||
#### Installation options
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_version`| keycloak.org package version | `26.6.2` |
|
||||
|`keycloak_quarkus_offline_install` | Perform an offline install | `False`|
|
||||
|`keycloak_quarkus_dest`| Installation root path | `/opt/keycloak` |
|
||||
|`keycloak_quarkus_download_url` | Download URL for keycloak | `https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}` |
|
||||
|`keycloak_quarkus_download_path`| Path local to controller for offline/download of install archives | `{{ lookup('env', 'PWD') }}` |
|
||||
|
||||
|
||||
#### Service configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_bootstrap_admin_user`| Administration console user account | `admin` |
|
||||
|`keycloak_quarkus_admin_user`| Deprecated, use `keycloak_quarkus_bootstrap_admin_user` instead. | |
|
||||
|`keycloak_quarkus_bind_address`| Deprecated, use `keycloak_quarkus_http_host` instead | `0.0.0.0` |
|
||||
|`keycloak_quarkus_host`| Deprecated, use `keycloak_quarkus_hostname` instead. | |
|
||||
|`keycloak_quarkus_port`| Deprecated, use `keycloak_quarkus_hostname` instead. | |
|
||||
|`keycloak_quarkus_path`| Deprecated, use `keycloak_quarkus_hostname` instead. | |
|
||||
|`keycloak_quarkus_service_user`| Posix account username | `keycloak` |
|
||||
|`keycloak_quarkus_service_group`| Posix account group | `keycloak` |
|
||||
|`keycloak_quarkus_service_restart_always`| systemd restart always behavior activation | `False` |
|
||||
|`keycloak_quarkus_service_restart_on_failure`| systemd restart on-failure behavior activation | `False` |
|
||||
|`keycloak_quarkus_service_restartsec`| systemd RestartSec | `10s` |
|
||||
|`keycloak_quarkus_jvm_package`| RHEL java package runtime | `java-21-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_heap_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 overridden, it takes precedence over `keycloak_quarkus_java_*` | `{{ keycloak_quarkus_java_heap_opts + ' ' + keycloak_quarkus_java_jvm_opts }}` |
|
||||
|`keycloak_quarkus_additional_env_vars` | List of additional env variables of { key: str, value: str} to be put in sysconfig file, see https://www.keycloak.org/server/all-config | `[]` |
|
||||
|`keycloak_quarkus_frontend_url`| Deprecated, use `keycloak_quarkus_hostname` instead. | |
|
||||
|`keycloak_quarkus_admin_url`| Deprecated, use `keycloak_quarkus_hostname_admin` instead. | |
|
||||
|`keycloak_quarkus_health_check_url`| Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default | `{{ keycloak_quarkus_hostname ~ keycloak_quarkus_http_relative_path.rstrip('/') ~ '/' ~ keycloak_quarkus_health_check_url_path }}` |
|
||||
|`keycloak_quarkus_health_check_url_path`| Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property | `realms/{{ keycloak_quarkus_master_realm }}/.well-known/openid-configuration` |
|
||||
|`keycloak_quarkus_proxy_headers`| Parse reverse proxy headers (`forwarded` or `xforwarded`) | `""` |
|
||||
|`keycloak_quarkus_config_key_store_file`| Path to the configuration key store; only used if `keycloak_quarkus_config_key_store_password` is not empty | `{{ keycloak.home }}/conf/conf_store.p12` if `keycloak_quarkus_config_key_store_password != ''`, else `''` |
|
||||
|`keycloak_quarkus_config_key_store_password`| Password of the configuration keystore; if non-empty, `keycloak_quarkus_db_pass` will be saved to the keystore at `keycloak_quarkus_config_key_store_file` instead of being written to the configuration file in clear text | `""` |
|
||||
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
|
||||
|`keycloak_quarkus_configure_iptables` | Ensure iptables is configured for keycloak ports | `False` |
|
||||
|
||||
|
||||
#### High-availability
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_ha_enabled`| Enable auto configuration for database backend, clustering and remote caches on infinispan | `False` |
|
||||
|`keycloak_quarkus_ha_discovery`| Discovery protocol for HA cluster members | `JDBCPING` |
|
||||
|`keycloak_quarkus_db_enabled`| Enable auto configuration for database backend | `True` if `keycloak_quarkus_ha_enabled` is True, else `False` |
|
||||
|`keycloak_quarkus_jgroups_ip`| Host jgroups IP. If changing this variable you must make sure it is always set for all hosts in your cluster. | `{{ ansible_default_ipv4.address }}` |
|
||||
|`keycloak_quarkus_jgroups_port`| jgroups cluster tcp port | `7800` |
|
||||
|`keycloak_quarkus_systemd_wait_for_port` | Whether systemd unit should wait for keycloak port before returning | `{{ keycloak_quarkus_ha_enabled }}` |
|
||||
|`keycloak_quarkus_systemd_wait_for_port_number`| Which port the systemd unit should wait for | `{{ keycloak_quarkus_https_port }}` |
|
||||
|`keycloak_quarkus_systemd_wait_for_log` | Whether systemd unit should wait for service to be up in logs | `false` |
|
||||
|`keycloak_quarkus_systemd_wait_for_timeout`| How long to wait for service to be alive (seconds) | `60` |
|
||||
|`keycloak_quarkus_systemd_wait_for_delay`| Activation delay for service systemd unit (seconds) | `10` |
|
||||
|`keycloak_quarkus_restart_strategy`| Strategy task file for restarting in HA (one of provided restart/['serial.yml','none.yml','serial_then_parallel.yml']) or path to file when providing custom strategy | `restart/serial.yml` |
|
||||
|`keycloak_quarkus_restart_health_check`| Whether to wait for successful health check after restart | `true` |
|
||||
|`keycloak_quarkus_restart_health_check_delay`| Seconds to let pass before starting healch checks | `10` |
|
||||
|`keycloak_quarkus_restart_health_check_retries`| Number of attempts for successful health check before failing | `25` |
|
||||
|`keycloak_quarkus_validate_certs`| Whether to validate SSL certificates when performing health checks | `true` |
|
||||
|`keycloak_quarkus_restart_pause`| Seconds to wait between restarts in HA strategy | `15` |
|
||||
|
||||
|
||||
#### Hostname configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_hostname`| Address at which is the server exposed. Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request. | |
|
||||
|`keycloak_quarkus_hostname_admin`| Set the base URL for accessing the administration console, including scheme, host, port and path | `` |
|
||||
|`keycloak_quarkus_hostname_strict`| Disables dynamically resolving the hostname from request headers | `true` |
|
||||
|`keycloak_quarkus_hostname_backchannel_dynamic`| Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path. Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL. | `false` |
|
||||
|`keycloak_quarkus_hostname_strict_backchannel`| Deprecated, use (the inverted!)`keycloak_quarkus_hostname_backchannel_dynamic` instead. | |
|
||||
|
||||
|
||||
#### HTTP(S) configuration
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_http_relative_path`| Set the path relative to / for serving resources. The path must start with a / | `/` |
|
||||
|`keycloak_quarkus_http_host`| The http host, ie. the address used to bind the service | `0.0.0.0` |
|
||||
|`keycloak_quarkus_http_port`| HTTP listening port | `8080` |
|
||||
|`keycloak_quarkus_https_port`| TLS HTTP listening port | `8443` |
|
||||
|`keycloak_quarkus_http_management_port`| Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details. | `9000` |
|
||||
|`keycloak_quarkus_https_key_store_file`| The file path to the key store | `{{ keycloak.home }}/conf/key_store.p12` |
|
||||
|`keycloak_quarkus_https_key_store_password`| Password for the key store | `""` |
|
||||
|`keycloak_quarkus_https_trust_store_enabled`| Enable configuration of the https trust store | `False` |
|
||||
|`keycloak_quarkus_https_trust_store_file`| The file path to the trust store | `{{ keycloak.home }}/conf/trust_store.p12` |
|
||||
|`keycloak_quarkus_https_trust_store_password`| Password for the trust store | `""` |
|
||||
|`keycloak_quarkus_https_key_file_enabled`| Enable listener on HTTPS port | `False` |
|
||||
|`keycloak_quarkus_key_file_copy_enabled`| Enable copy of key file to target host | `False` |
|
||||
|`keycloak_quarkus_key_content`| Content of the TLS private key. Use `"{{ lookup('file', 'server.key.pem') }}"` to lookup a file. | `""` |
|
||||
|`keycloak_quarkus_key_file`| The file path to a private key in PEM format | `/etc/pki/tls/private/server.key.pem` |
|
||||
|`keycloak_quarkus_cert_file_copy_enabled`| Enable copy of cert file to target host | `False`|
|
||||
|`keycloak_quarkus_cert_file_src`| Set the source file path | `""` |
|
||||
|`keycloak_quarkus_cert_file`| The file path to a server certificate or certificate chain in PEM format | `/etc/pki/tls/certs/server.crt.pem` |
|
||||
|`keycloak_quarkus_https_key_store_enabled`| Enable configuration of HTTPS via a key store | `False` |
|
||||
|`keycloak_quarkus_key_store_file`| Deprecated, use `keycloak_quarkus_https_key_store_file` instead. ||
|
||||
|`keycloak_quarkus_key_store_password`| Deprecated, use `keycloak_quarkus_https_key_store_password` instead.||
|
||||
|`keycloak_quarkus_http_relative_path` | Set the path relative to / for serving resources. The path must start with a / | `/` |
|
||||
|`keycloak_quarkus_http_management_relative_path` | Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details. | `/` |
|
||||
|`keycloak_quarkus_http_enabled`| Enable listener on HTTP port | `True` |
|
||||
|
||||
|
||||
#### Infinispan configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
| :------------------------------------------------- | :------------------------------ | :----------------------------------------------------------- |
|
||||
| `keycloak_quarkus_cache_managed_infinispan_config` | Manage infinispan configuration | `"{{ keycloak_quarkus_version is version('26.4.0', '<') }}"` |
|
||||
| `keycloak_quarkus_cache_infinispan_template` | Infinispan cache template file | `cache-ispn.xml` |
|
||||
|
||||
As explained in the [official documentation](https://www.keycloak.org/server/caching#_modifying_cache_configuration_defaults), since version 26.4, it is recommended not to modify the XML configuration file but rather to configure the cache via the keycloak.properties file. By default, the role will no longer automatically deploy this file for versions higher than 26.4.
|
||||
|
||||
For earlier versions, it is possible to override the given template to customize the cache using the `keycloak_quarkus_cache_infinispan_template` variable.
|
||||
|
||||
#### Database configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_db_engine` | Database engine [mariadb,postres,mssql] | `postgres` |
|
||||
|`keycloak_quarkus_db_user` | User for database connection | `keycloak-user` |
|
||||
|`keycloak_quarkus_db_pass` | Password for database connection | `keycloak-pass` |
|
||||
|`keycloak_quarkus_db_url` | JDBC URL for connecting to database | `jdbc:postgresql://localhost:5432/keycloak` |
|
||||
|`keycloak_quarkus_db_driver_version` | Version for JDBC engine driver | `9.4.1212` |
|
||||
|
||||
|
||||
#### Cache configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_cache_remote` | Whether to connect to remote cache infinispan server | `false` |
|
||||
|`keycloak_quarkus_cache_remote_username` | Username for connecting to infinispan | `supervisor` |
|
||||
|`keycloak_quarkus_cache_remote_password` | Password for connecting to infinispan | `supervisor` |
|
||||
|`keycloak_quarkus_cache_remote_host` | Hostname for connecting to infinispan | `localhost` |
|
||||
|`keycloak_quarkus_cache_remote_port`| Port for connecting to infinispan | `11222` |
|
||||
|`keycloak_quarkus_cache_remote_sasl_mechanism` | Infinispan auth mechanism | `SCRAM-SHA-512` |
|
||||
|`keycloak_quarkus_cache_remote_tls_enabled` | Whether infinispan uses TLS connection | `false` |
|
||||
|`keycloak_quarkus_cache_embedded_properties` | Embedded cache properties | `` |
|
||||
|
||||
|
||||
#### Logging configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_log`| Enable one or more log handlers in a comma-separated list | `file` |
|
||||
|`keycloak_quarkus_log_level`| The log level of the root category or a comma-separated list of individual categories and their levels | `info` |
|
||||
|`keycloak_quarkus_log_file`| Set the log file path and filename relative to keycloak home | `data/log/keycloak.log` |
|
||||
|`keycloak_quarkus_log_format`| Set a format specific to file log entries | `%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n` |
|
||||
|`keycloak_quarkus_log_target`| Set the destination of the keycloak log folder link | `/var/log/keycloak` |
|
||||
|`keycloak_quarkus_log_max_file_size`| Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular expression): `[0-9]+[KkMmGgTtPpEeZzYy]?`. If no suffix is given, assume bytes. | `10M` |
|
||||
|`keycloak_quarkus_log_max_backup_index`| Set the maximum number of archived log files to keep | `10` |
|
||||
|`keycloak_quarkus_log_file_suffix`| Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix; Note: If the suffix ends with `.zip` or `.gz`, the rotation file will also be compressed. | `.yyyy-MM-dd.zip` |
|
||||
|
||||
|
||||
#### Miscellaneous configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_metrics_enabled`| Whether to enable metrics | `False` |
|
||||
|`keycloak_quarkus_health_enabled`| If the server should expose health check endpoints on the management interface | `True` |
|
||||
|`keycloak_quarkus_archive` | keycloak install archive filename | `keycloak-{{ keycloak_quarkus_version }}.zip` |
|
||||
|`keycloak_quarkus_installdir` | Installation path | `{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}` |
|
||||
|`keycloak_quarkus_home` | Installation work directory | `{{ keycloak_quarkus_installdir }}` |
|
||||
|`keycloak_quarkus_config_dir` | Path for configuration | `{{ keycloak_quarkus_home }}/conf` |
|
||||
|`keycloak_quarkus_master_realm` | Name for rest authentication realm | `master` |
|
||||
|`keycloak_auth_client` | Authentication client for configuration REST calls | `admin-cli` |
|
||||
|`keycloak_quarkus_force_install` | Remove pre-existing versions of service | `False` |
|
||||
|`keycloak_quarkus_proxy_mode`| The proxy address forwarding mode if the server is behind a reverse proxy (deprecated) | `none` |
|
||||
|`keycloak_quarkus_start_dev`| Whether to start the service in development mode (start-dev) | `False` |
|
||||
|`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` |
|
||||
|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` |
|
||||
|`keycloak_quarkus_show_deprecation_warnings`| Whether deprecation warnings should be shown | `True` |
|
||||
|
||||
|
||||
#### Vault configuration
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_ks_vault_enabled`| Whether to enable the vault SPI | `false` |
|
||||
|`keycloak_quarkus_ks_vault_file`| The keystore path for the vault SPI | `{{ keycloak_quarkus_config_dir }}/keystore.p12` |
|
||||
|`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` |
|
||||
|
||||
|
||||
#### Configuring providers
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_providers`| List of provider definitions; see below | `[]` |
|
||||
|
||||
Providers support different sources:
|
||||
|
||||
* `url`: http download for providers not requiring authentication
|
||||
* `maven`: maven download for providers hosted publicly on Apache Maven Central or private Maven repositories like Github Maven requiring authentication
|
||||
* `local_path`: static providers to be uploaded
|
||||
|
||||
Provider definition:
|
||||
|
||||
```yaml
|
||||
keycloak_quarkus_providers:
|
||||
- id: http-client # required; "{{ id }}.jar" identifies the file name on RHBK
|
||||
spi: connections # required if neither url, local_path nor maven are specified; required for setting properties
|
||||
default: true # optional, whether to set default for spi, default false
|
||||
restart: true # optional, whether to rebuild config and restart the service after deploying, default true
|
||||
url: https://.../.../custom_spi.jar # optional, url for download via http
|
||||
local_path: my_theme_spi.jar # optional, path on local controller for SPI to be uploaded
|
||||
remote: true # optional, whether to copy from localhost or remotely, see https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html#parameter-remote_src, default false
|
||||
maven: # optional, for download using maven
|
||||
repository_url: https://maven.pkg.github.com/OWNER/REPOSITORY # optional, maven repo url
|
||||
group_id: my.group # optional, maven group id
|
||||
artifact_id: artifact # optional, maven artifact id
|
||||
version: 24.0.5 # optional, defaults to latest
|
||||
username: user # optional, cf. https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages
|
||||
password: pat # optional, provide a PAT for accessing Github's Apache Maven registry
|
||||
properties: # optional, list of key-values
|
||||
- key: default-connection-pool-size
|
||||
value: 10
|
||||
checksum: sha256:D98291AC[...]B6DC7B97 # optional, checksum used to verify integrity:
|
||||
# for `url` SPIs, use format: <algorithm>:<checksum|url>, cf. <https://docs.ansible.com/ansible/latest/collections/ansible/builtin/get_url_module.html#parameter-checksum>;
|
||||
# for `local_path` SPIs, use SHA1 format <https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html#parameter-checksum>
|
||||
# for `maven` SPIs, this field is ignored since maven has integrity verification methods enabled by default
|
||||
```
|
||||
|
||||
the definition above will generate the following build command:
|
||||
|
||||
```
|
||||
bin/kc.sh build --spi-connections-provider=http-client --spi-connections-http-client-default-connection-pool-size=10
|
||||
```
|
||||
|
||||
|
||||
#### Configuring policies
|
||||
|
||||
| Variable | Description | Default |
|
||||
|:---------|:------------|:--------|
|
||||
|`keycloak_quarkus_policies`| List of policy definitions; see below | `[]` |
|
||||
|
||||
Provider definition:
|
||||
|
||||
```yaml
|
||||
keycloak_quarkus_policies:
|
||||
- name: john-the-ripper.txt # required, resulting file name
|
||||
url: https://github.com/danielmiessler/SecLists/raw/master/Passwords/Software/john-the-ripper.txt # required, url for download
|
||||
type: password-blacklists # optional, defaults to `password-blacklists`; supported values: [`password-blacklists`]
|
||||
```
|
||||
|
||||
|
||||
Role Variables
|
||||
--------------
|
||||
|
||||
| Variable | Description | Required |
|
||||
|:---------|:------------|----------|
|
||||
|`keycloak_quarkus_bootstrap_admin_password`| Password of console admin account | `yes` |
|
||||
|`keycloak_quarkus_admin_pass`| Deprecated, use `keycloak_quarkus_bootstrap_admin_password` instead. | |
|
||||
|`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` |
|
||||
|`keycloak_quarkus_alternate_download_url`| Alternate location with optional authentication for downloading RHBK | `no` |
|
||||
|`keycloak_quarkus_download_user`| Optional username for http authentication | `no*` |
|
||||
|`keycloak_quarkus_download_pass`| Optional password for http authentication | `no*` |
|
||||
|`keycloak_quarkus_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_alternate_download_url` | `no` |
|
||||
|`keycloak_quarkus_jdbc_download_user`| Optional username for http authentication | `no*` |
|
||||
|`keycloak_quarkus_jdbc_download_pass`| Optional password for http authentication | `no*` |
|
||||
|`keycloak_quarkus_jdbc_download_validate_certs`| Whether to validate certs for URL `keycloak_quarkus_download_validate_certs` | `no` |
|
||||
|
||||
`*` username/password authentication credentials must be both declared or both undefined
|
||||
|
||||
|
||||
Role custom facts
|
||||
-----------------
|
||||
|
||||
The role uses the following [custom facts](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html#adding-custom-facts) found in `/etc/ansible/facts.d/keycloak.fact` (and thus identified by the `ansible_local.keycloak.` prefix):
|
||||
|
||||
| Variable | Description |
|
||||
|:---------|:------------|
|
||||
|`general.bootstrapped` | A custom fact indicating whether this role has been used for bootstrapping keycloak on the respective host before; set to `false` (e.g., when starting off with a new, empty database) ensures that the initial admin user as defined by `keycloak_quarkus_bootstrap_admin_user[_password]` gets created |
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Apache License 2.0
|
||||
|
||||
|
||||
Author Information
|
||||
------------------
|
||||
|
||||
* [Guido Grazioli](https://github.com/guidograzioli)
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
---
|
||||
### Configuration specific to keycloak
|
||||
keycloak_quarkus_version: 26.6.2
|
||||
keycloak_quarkus_archive: "keycloak-{{ keycloak_quarkus_version }}.zip"
|
||||
keycloak_quarkus_download_url: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
|
||||
keycloak_quarkus_installdir: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
|
||||
|
||||
# Authentication for Keycloak binary download (e.g. from internal artifact repository)
|
||||
keycloak_quarkus_binary_download_user:
|
||||
keycloak_quarkus_binary_download_pass:
|
||||
|
||||
# whether to install from local archive
|
||||
keycloak_quarkus_offline_install: false
|
||||
|
||||
keycloak_quarkus_show_deprecation_warnings: true
|
||||
|
||||
### Install location and service settings
|
||||
keycloak_quarkus_java_home:
|
||||
keycloak_quarkus_dest: /opt/keycloak
|
||||
keycloak_quarkus_home: "{{ keycloak_quarkus_installdir }}"
|
||||
keycloak_quarkus_config_dir: "{{ keycloak_quarkus_home }}/conf"
|
||||
keycloak_quarkus_download_path: "{{ lookup('env', 'PWD') }}"
|
||||
keycloak_quarkus_start_dev: false
|
||||
keycloak_quarkus_service_user: keycloak
|
||||
keycloak_quarkus_service_group: keycloak
|
||||
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_bootstrap_admin_user: admin
|
||||
keycloak_quarkus_bootstrap_admin_password:
|
||||
keycloak_quarkus_master_realm: master
|
||||
|
||||
### Configuration settings
|
||||
keycloak_quarkus_bind_address: 0.0.0.0 # deprecated use keycloak_quarkus_http_host
|
||||
keycloak_quarkus_http_host: 0.0.0.0
|
||||
keycloak_quarkus_http_enabled: true
|
||||
keycloak_quarkus_http_port: 8080
|
||||
keycloak_quarkus_https_port: 8443
|
||||
keycloak_quarkus_http_management_port: 9000
|
||||
keycloak_quarkus_jgroups_port: 7800
|
||||
keycloak_quarkus_jgroups_bind_address: "{{ ansible_default_ipv4.address }}"
|
||||
keycloak_quarkus_jgroups_external_addr: "{{ keycloak_quarkus_jgroups_bind_address }}"
|
||||
keycloak_quarkus_jgroups_external_port: "{{ keycloak_quarkus_jgroups_port }}"
|
||||
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_jgroups_opts: >
|
||||
-Djgroups.bind.address={{ keycloak_quarkus_jgroups_bind_address }}
|
||||
-Djgroups.external_port={{ keycloak_quarkus_jgroups_external_port }}
|
||||
-Djgroups.external_addr={{ keycloak_quarkus_jgroups_external_addr }}
|
||||
keycloak_quarkus_java_opts: "{{ ' '.join((keycloak_quarkus_jgroups_opts, keycloak_quarkus_java_heap_opts, keycloak_quarkus_java_jvm_opts)) }}"
|
||||
keycloak_quarkus_additional_env_vars: []
|
||||
|
||||
### TLS/HTTPS configuration
|
||||
keycloak_quarkus_https_key_file_enabled: false
|
||||
keycloak_quarkus_key_file_copy_enabled: false
|
||||
keycloak_quarkus_key_content: ""
|
||||
keycloak_quarkus_key_file: "/etc/pki/tls/private/server.key.pem"
|
||||
keycloak_quarkus_cert_file_copy_enabled: false
|
||||
keycloak_quarkus_cert_file_src: ""
|
||||
keycloak_quarkus_cert_file: "/etc/pki/tls/certs/server.crt.pem"
|
||||
#### key store configuration
|
||||
keycloak_quarkus_https_key_store_enabled: false
|
||||
keycloak_quarkus_https_key_store_file: "{{ keycloak.home }}/conf/key_store.p12"
|
||||
keycloak_quarkus_https_key_store_password: ''
|
||||
##### trust store configuration
|
||||
keycloak_quarkus_https_trust_store_enabled: false
|
||||
keycloak_quarkus_https_trust_store_file: "{{ keycloak.home }}/conf/trust_store.p12"
|
||||
keycloak_quarkus_https_trust_store_password: ''
|
||||
### configuration key store configuration
|
||||
keycloak_quarkus_config_key_store_file: "{{ keycloak.home }}/conf/conf_store.p12"
|
||||
keycloak_quarkus_config_key_store_password: ''
|
||||
|
||||
### Enable configuration for database backend, clustering and remote caches on infinispan
|
||||
keycloak_quarkus_ha_enabled: false
|
||||
keycloak_quarkus_ha_discovery: "JDBCPING"
|
||||
### Enable database configuration, must be enabled when HA is configured
|
||||
keycloak_quarkus_db_enabled: "{{ keycloak_quarkus_ha_enabled }}"
|
||||
keycloak_quarkus_systemd_wait_for_port: "{{ keycloak_quarkus_ha_enabled }}"
|
||||
keycloak_quarkus_systemd_wait_for_port_number: "{{ keycloak_quarkus_https_port }}"
|
||||
keycloak_quarkus_systemd_wait_for_log: false
|
||||
keycloak_quarkus_systemd_wait_for_timeout: 60
|
||||
keycloak_quarkus_systemd_wait_for_delay: 10
|
||||
|
||||
### keycloak frontend url
|
||||
keycloak_quarkus_hostname:
|
||||
keycloak_quarkus_hostname_admin: ""
|
||||
|
||||
### Set the path relative to / for serving resources. The path must start with a /
|
||||
### (set to `/auth` for retrocompatibility with pre-quarkus releases)
|
||||
keycloak_quarkus_http_relative_path: /
|
||||
|
||||
# Disables dynamically resolving the hostname from request headers.
|
||||
# Should always be set to true in production, unless proxy verifies the Host header.
|
||||
keycloak_quarkus_hostname_strict: true
|
||||
# Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path.
|
||||
# Set to true if your application accesses Keycloak via a private network. If set to true, keycloak_quarkus_hostname option needs to be specified as a full URL.
|
||||
keycloak_quarkus_hostname_backchannel_dynamic: false
|
||||
|
||||
# The proxy headers that should be accepted by the server. ['', 'forwarded', 'xforwarded']
|
||||
keycloak_quarkus_proxy_headers: ""
|
||||
|
||||
# deprecated: proxy address forwarding mode if the server is behind a reverse proxy. [none, edge, reencrypt, passthrough]
|
||||
keycloak_quarkus_proxy_mode: none
|
||||
|
||||
# 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
|
||||
keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route: true
|
||||
|
||||
keycloak_quarkus_metrics_enabled: false
|
||||
keycloak_quarkus_health_enabled: true
|
||||
|
||||
### infinispan; must read: https://forum.keycloak.org/t/keycloak-26-4-7-ha/31202
|
||||
keycloak_quarkus_cache_managed_infinispan_config: "{{ keycloak_quarkus_version is version('26.4.0', '<') }}"
|
||||
keycloak_quarkus_cache_infinispan_template: cache-ispn.xml
|
||||
|
||||
### caches; must read: https://www.keycloak.org/2024/12/storing-sessions-in-kc26
|
||||
### embedded caches
|
||||
# https://www.keycloak.org/server/caching
|
||||
keycloak_quarkus_cache_embedded_properties: ""
|
||||
|
||||
### infinispan remote caches access (hotrod)
|
||||
# https://www.keycloak.org/server/caching#_remote_cache
|
||||
keycloak_quarkus_cache_remote: false
|
||||
keycloak_quarkus_cache_remote_username: supervisor
|
||||
keycloak_quarkus_cache_remote_password: supervisor
|
||||
keycloak_quarkus_cache_remote_host: localhost
|
||||
keycloak_quarkus_cache_remote_port: 11222
|
||||
keycloak_quarkus_cache_remote_tls_enabled: false
|
||||
keycloak_quarkus_cache_remote_sasl_mechanism: SCRAM-SHA-512
|
||||
|
||||
|
||||
### database backend engine: values [ 'postgres', 'mariadb' ]
|
||||
keycloak_quarkus_db_engine: postgres
|
||||
### database backend credentials
|
||||
keycloak_quarkus_db_user: keycloak-user
|
||||
keycloak_quarkus_db_pass: keycloak-pass
|
||||
keycloak_quarkus_db_url: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}"
|
||||
keycloak_quarkus_db_driver_version: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}"
|
||||
# override the variables above, following defaults show recommended version as per
|
||||
# https://access.redhat.com/articles/7033107
|
||||
keycloak_quarkus_default_jdbc:
|
||||
postgres:
|
||||
url: 'jdbc:postgresql://localhost:5432/keycloak'
|
||||
version: 42.7.7
|
||||
mariadb:
|
||||
url: 'jdbc:mariadb://localhost:3306/keycloak'
|
||||
version: 3.5.2
|
||||
mssql:
|
||||
url: 'jdbc:sqlserver://localhost:1433;databaseName=keycloak;'
|
||||
version: 13.2.0
|
||||
driver_jar_url: "https://repo1.maven.org/maven2/com/microsoft/sqlserver/mssql-jdbc/13.2.0.jre11/mssql-jdbc-13.2.0.jre11.jar"
|
||||
### logging configuration
|
||||
keycloak_quarkus_log: file
|
||||
keycloak_quarkus_log_level: info
|
||||
keycloak_quarkus_log_file: data/log/keycloak.log
|
||||
keycloak_quarkus_log_format: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n'
|
||||
keycloak_quarkus_log_target: /var/log/keycloak
|
||||
keycloak_quarkus_log_max_file_size: 10M
|
||||
keycloak_quarkus_log_max_backup_index: 10
|
||||
keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip'
|
||||
|
||||
# keystore-based vault
|
||||
keycloak_quarkus_ks_vault_enabled: false
|
||||
keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
|
||||
keycloak_quarkus_ks_vault_type: PKCS12
|
||||
keycloak_quarkus_ks_vault_pass:
|
||||
|
||||
keycloak_quarkus_providers: []
|
||||
keycloak_quarkus_policies: []
|
||||
keycloak_quarkus_supported_policy_types: ['password-blacklists']
|
||||
|
||||
# files in restart directory (one of [ 'serial', 'none', 'serial_then_parallel' ]), or path to file when providing custom strategy
|
||||
keycloak_quarkus_restart_strategy: restart/serial.yml
|
||||
keycloak_quarkus_restart_health_check: true
|
||||
keycloak_quarkus_restart_health_check_delay: 10
|
||||
keycloak_quarkus_restart_health_check_retries: 25
|
||||
keycloak_quarkus_validate_certs: true
|
||||
keycloak_quarkus_health_check_url_path: "realms/{{ keycloak_quarkus_master_realm }}/.well-known/openid-configuration"
|
||||
keycloak_quarkus_health_check_url: "{{ keycloak_quarkus_hostname ~ keycloak_quarkus_http_relative_path.rstrip('/') ~ '/' ~ keycloak_quarkus_health_check_url_path }}"
|
||||
keycloak_quarkus_restart_pause: 15
|
||||
|
||||
keycloak_quarkus_force_install: false
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
- name: "Invalidate theme cache: {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks: invalidate_theme_cache.yml
|
||||
listen: "invalidate keycloak theme cache"
|
||||
# handler should be invoked anytime a [build configuration](https://www.keycloak.org/server/all-config?f=build) changes
|
||||
- name: "Rebuild config: {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks: rebuild_config.yml
|
||||
listen: "rebuild keycloak config"
|
||||
- name: "Bootstrapped"
|
||||
ansible.builtin.include_tasks: bootstrapped.yml
|
||||
listen: bootstrapped
|
||||
- name: "Restart {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks:
|
||||
file: "{{ keycloak_quarkus_restart_strategy if keycloak_quarkus_ha_enabled else 'restart.yml' }}"
|
||||
listen: "restart keycloak"
|
||||
- name: "Display deprecation warning"
|
||||
ansible.builtin.fail:
|
||||
msg: "Deprecation warning: you are using the deprecated variable '{{ keycloak_quarkus_deprecated_variable | d('NotSet') }}', check docs on how to upgrade."
|
||||
failed_when: false
|
||||
changed_when: true
|
||||
listen: "print deprecation warning"
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
argument_specs:
|
||||
main:
|
||||
options:
|
||||
keycloak_quarkus_version:
|
||||
default: "26.6.2"
|
||||
description: "keycloak.org package version"
|
||||
type: "str"
|
||||
keycloak_quarkus_archive:
|
||||
default: "keycloak-{{ keycloak_quarkus_version }}.zip"
|
||||
description: "keycloak install archive filename"
|
||||
type: "str"
|
||||
keycloak_quarkus_download_url:
|
||||
default: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_quarkus_version }}/{{ keycloak_quarkus_archive }}"
|
||||
description: "Download URL for keycloak"
|
||||
type: "str"
|
||||
keycloak_quarkus_installdir:
|
||||
default: "{{ keycloak_quarkus_dest }}/keycloak-{{ keycloak_quarkus_version }}"
|
||||
description: "Installation path"
|
||||
type: "str"
|
||||
keycloak_quarkus_offline_install:
|
||||
default: false
|
||||
description: "Perform an offline install"
|
||||
type: "bool"
|
||||
keycloak_quarkus_jvm_package:
|
||||
default: "java-21-openjdk-headless"
|
||||
description: "RHEL java package runtime"
|
||||
type: "str"
|
||||
keycloak_quarkus_java_home:
|
||||
description: "JAVA_HOME of installed JRE, leave empty for using specified keycloak_jvm_package RPM path"
|
||||
type: "str"
|
||||
keycloak_quarkus_dest:
|
||||
default: "/opt/keycloak"
|
||||
description: "Installation root path"
|
||||
type: "str"
|
||||
keycloak_quarkus_home:
|
||||
default: "{{ keycloak_quarkus_installdir }}"
|
||||
description: "Installation work directory"
|
||||
type: "str"
|
||||
keycloak_quarkus_config_dir:
|
||||
default: "{{ keycloak_quarkus_home }}/conf"
|
||||
description: "Path for configuration"
|
||||
type: "str"
|
||||
keycloak_quarkus_service_user:
|
||||
default: "keycloak"
|
||||
description: "Posix account username"
|
||||
type: "str"
|
||||
keycloak_quarkus_service_group:
|
||||
default: "keycloak"
|
||||
description: "Posix account group"
|
||||
type: "str"
|
||||
keycloak_quarkus_configure_firewalld:
|
||||
default: false
|
||||
description: "Ensure firewalld is running and configure keycloak ports"
|
||||
type: "bool"
|
||||
keycloak_quarkus_configure_iptables:
|
||||
default: false
|
||||
description: "Ensure firewalld is running and configure keycloak ports"
|
||||
type: "bool"
|
||||
keycloak_quarkus_service_restart_always:
|
||||
default: false
|
||||
description: "systemd restart always behavior of service; takes precedence over keycloak_service_restart_on_failure if true"
|
||||
type: "bool"
|
||||
keycloak_quarkus_service_restart_on_failure:
|
||||
default: false
|
||||
description: "systemd restart on-failure behavior of service"
|
||||
type: "bool"
|
||||
keycloak_quarkus_service_restartsec:
|
||||
default: "10s"
|
||||
description: "systemd RestartSec for service"
|
||||
type: "str"
|
||||
keycloak_quarkus_bootstrap_admin_user:
|
||||
default: "admin"
|
||||
description: "Administration user account, only for bootstrapping"
|
||||
type: "str"
|
||||
keycloak_quarkus_force_install:
|
||||
default: false
|
||||
description: "Remove pre-existing versions of service"
|
||||
type: "bool"
|
||||
keycloak_quarkus_bootstrap_admin_password:
|
||||
required: true
|
||||
description: "Password of admin account, only for bootstrapping"
|
||||
type: "str"
|
||||
keycloak_quarkus_master_realm:
|
||||
default: "master"
|
||||
description: "Name for rest authentication realm"
|
||||
type: "str"
|
||||
keycloak_quarkus_bind_address:
|
||||
default: "0.0.0.0"
|
||||
description: "Deprecated, use `keycloak_quarkus_http_host`"
|
||||
type: "str"
|
||||
keycloak_quarkus_hostname:
|
||||
description: >-
|
||||
Address at which is the server exposed.
|
||||
Can be a full URL, or just a hostname. When only hostname is provided, scheme, port and context path are resolved from the request.
|
||||
type: "str"
|
||||
keycloak_quarkus_host:
|
||||
description: "Deprecated in v26, use keycloak_quarkus_hostname instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_port:
|
||||
description: "Deprecated in v26, use keycloak_quarkus_hostname instead."
|
||||
type: "int"
|
||||
keycloak_quarkus_path:
|
||||
description: "Deprecated in v26, use keycloak_quarkus_hostname instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_http_enabled:
|
||||
default: true
|
||||
description: "Enable listener on HTTP port"
|
||||
type: "bool"
|
||||
keycloak_quarkus_http_host:
|
||||
default: '0.0.0.0'
|
||||
description: "HTTP host, address for binding service ports"
|
||||
type: "str"
|
||||
keycloak_quarkus_http_port:
|
||||
default: 8080
|
||||
description: "HTTP port"
|
||||
type: "int"
|
||||
keycloak_quarkus_health_check_url:
|
||||
default: "{{ keycloak_quarkus_hostname ~ keycloak_quarkus_http_relative_path.rstrip('/') ~ '/' ~ keycloak_quarkus_health_check_url_path }}"
|
||||
description: "Full URL (including scheme, host, path, fragment etc.) used for health check endpoint; keycloak_quarkus_hostname will NOT be prepended; helpful when health checks should happen against http port, but keycloak_quarkus_hostname uses https scheme per default"
|
||||
type: "str"
|
||||
keycloak_quarkus_health_check_url_path:
|
||||
default: "realms/{{ keycloak_quarkus_master_realm }}/.well-known/openid-configuration"
|
||||
description: "Path to the health check endpoint; keycloak_quarkus_hostname will be prepended automatically; Note that keycloak_quarkus_health_check_url takes precedence over this property"
|
||||
type: "str"
|
||||
keycloak_quarkus_https_key_file_enabled:
|
||||
default: false
|
||||
description: "Enable configuration of HTTPS via files in PEM format"
|
||||
type: "bool"
|
||||
keycloak_quarkus_key_file_copy_enabled:
|
||||
default: false
|
||||
description: "Enable copy of key file to target host"
|
||||
type: "bool"
|
||||
keycloak_quarkus_key_content:
|
||||
default: ""
|
||||
description: "Content of the TLS private key"
|
||||
type: "str"
|
||||
keycloak_quarkus_key_file:
|
||||
default: "/etc/pki/tls/private/server.key.pem"
|
||||
description: "The file path to a private key in PEM format"
|
||||
type: "str"
|
||||
keycloak_quarkus_cert_file_copy_enabled:
|
||||
default: false
|
||||
description: "Enable copy of cert file to target host"
|
||||
type: "bool"
|
||||
keycloak_quarkus_cert_file_src:
|
||||
default: ""
|
||||
description: "Set the source file path"
|
||||
type: "str"
|
||||
keycloak_quarkus_cert_file:
|
||||
default: "/etc/pki/tls/certs/server.crt.pem"
|
||||
description: "The file path to a server certificate or certificate chain in PEM format"
|
||||
type: "str"
|
||||
keycloak_quarkus_https_key_store_enabled:
|
||||
default: false
|
||||
description: "Enable configuration of HTTPS via a key store"
|
||||
type: "bool"
|
||||
keycloak_quarkus_key_store_file:
|
||||
default: ""
|
||||
description: "Deprecated, use `keycloak_quarkus_https_key_store_file` instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_key_store_password:
|
||||
default: ""
|
||||
description: "Deprecated, use `keycloak_quarkus_https_key_store_password` instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_https_key_store_file:
|
||||
default: "{{ keycloak.home }}/conf/key_store.p12"
|
||||
description: "The file path to the key store"
|
||||
type: "str"
|
||||
keycloak_quarkus_https_key_store_password:
|
||||
default: ""
|
||||
description: "Password for the key store"
|
||||
type: "str"
|
||||
keycloak_quarkus_https_trust_store_enabled:
|
||||
default: false
|
||||
description: "Enable configuration of the https trust store"
|
||||
type: "bool"
|
||||
keycloak_quarkus_https_trust_store_file:
|
||||
default: "{{ keycloak.home }}/conf/trust_store.p12"
|
||||
description: "The file path to the trust store"
|
||||
type: "str"
|
||||
keycloak_quarkus_https_trust_store_password:
|
||||
default: ""
|
||||
description: "Password for the trust store"
|
||||
type: "str"
|
||||
keycloak_quarkus_config_key_store_file:
|
||||
default: "{{ keycloak.home }}/conf/conf_store.p12"
|
||||
description: "Path to the configuration key store; only used if `keycloak_quarkus_config_key_store_password` is not empty"
|
||||
type: "str"
|
||||
keycloak_quarkus_config_key_store_password:
|
||||
default: ""
|
||||
description: >
|
||||
Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store
|
||||
at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text)
|
||||
type: "str"
|
||||
keycloak_quarkus_https_port:
|
||||
default: 8443
|
||||
description: "HTTPS port"
|
||||
type: "int"
|
||||
keycloak_quarkus_http_management_port:
|
||||
default: 9000
|
||||
description: "Port of the management interface. Relevant only when something is exposed on the management interface - see the guide for details."
|
||||
type: "int"
|
||||
keycloak_quarkus_jgroups_port:
|
||||
description: 'jgroups bind port'
|
||||
default: 7800
|
||||
type: "int"
|
||||
keycloak_quarkus_jgroups_bind_address:
|
||||
description: 'jgroups bind address'
|
||||
default: "{{ ansible_default_ipv4.address }}"
|
||||
type: "str"
|
||||
keycloak_quarkus_jgroups_external_addr:
|
||||
description: 'IP address that other instances in the Keycloak should use to contact this node'
|
||||
default: "{{ keycloak_quarkus_jgroups_bind_address }}"
|
||||
type: "str"
|
||||
keycloak_quarkus_jgroups_external_port:
|
||||
description: 'Port that other instances in the Keycloak cluster should use to contact this node'
|
||||
default: "{{ keycloak_quarkus_jgroups_port }}"
|
||||
type: "int"
|
||||
keycloak_quarkus_jgroups_opts:
|
||||
description: "JVM arguments for jgroups configuration"
|
||||
default: "-Djgroups.bind.address={{ keycloak_quarkus_jgroups_bind_address }} -Djgroups.external_port={{ keycloak_quarkus_jgroups_external_port }} -Djgroups.external_addr={{ keycloak_quarkus_jgroups_external_addr }}"
|
||||
type: "str"
|
||||
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: "{{ ' '.join((keycloak_quarkus_jgroups_opts, 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"
|
||||
type: "str"
|
||||
keycloak_quarkus_additional_env_vars:
|
||||
default: "[]"
|
||||
description: "List of additional env variables of { key: str, value: str} to be put in sysconfig file"
|
||||
type: "list"
|
||||
keycloak_quarkus_ha_enabled:
|
||||
default: false
|
||||
description: "Enable auto configuration for database backend, clustering and remote caches on infinispan"
|
||||
type: "bool"
|
||||
keycloak_quarkus_ha_discovery:
|
||||
default: "TCPPING"
|
||||
description: "Discovery protocol for HA cluster members"
|
||||
type: "str"
|
||||
keycloak_quarkus_db_enabled:
|
||||
default: "{{ True if keycloak_quarkus_ha_enabled else False }}"
|
||||
description: "Enable auto configuration for database backend"
|
||||
type: "str"
|
||||
keycloak_quarkus_http_relative_path:
|
||||
required: false
|
||||
default: /
|
||||
description: "Set the path relative to / for serving resources. The path must start with a /"
|
||||
type: "str"
|
||||
keycloak_quarkus_http_management_relative_path:
|
||||
required: false
|
||||
description: "Set the path relative to / for serving resources from management interface. The path must start with a /. If not given, the value is inherited from HTTP options. Relevant only when something is exposed on the management interface - see the guide for details."
|
||||
type: "str"
|
||||
keycloak_quarkus_frontend_url:
|
||||
required: false
|
||||
description: "Deprecated in v26, use keycloak_quarkus_hostname instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_hostname_admin:
|
||||
required: false
|
||||
description: "Service URL for the admin console"
|
||||
type: "str"
|
||||
keycloak_quarkus_admin_url:
|
||||
required: false
|
||||
description: "Deprecated in v26, use keycloak_quarkus_hostname_admin instead."
|
||||
type: "str"
|
||||
keycloak_quarkus_metrics_enabled:
|
||||
default: false
|
||||
description: "Whether to enable metrics"
|
||||
type: "bool"
|
||||
keycloak_quarkus_health_enabled:
|
||||
default: true
|
||||
description: "If the server should expose health check endpoints on the management interface"
|
||||
type: "bool"
|
||||
keycloak_quarkus_cache_remote:
|
||||
description: "Whether to connect to remote cache infinispan server"
|
||||
default: false
|
||||
type: 'bool'
|
||||
keycloak_quarkus_cache_remote_username:
|
||||
default: "supervisor"
|
||||
description: "Username for connecting to infinispan"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_remote_password:
|
||||
default: "supervisor"
|
||||
description: "Password for connecting to infinispan"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_remote_host:
|
||||
default: "localhost"
|
||||
description: "Hostname for connecting to infinispan"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_remote_port:
|
||||
default: "11222"
|
||||
description: "Port for connecting to infinispan"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_remote_sasl_mechanism:
|
||||
default: "SCRAM-SHA-512"
|
||||
description: "Infinispan auth mechanism"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_remote_tls_enabled:
|
||||
default: false
|
||||
description: "Whether infinispan uses TLS connection"
|
||||
type: "bool"
|
||||
keycloak_quarkus_db_engine:
|
||||
default: "postgres"
|
||||
description: "Database engine [mariadb,postres,mssql]"
|
||||
type: "str"
|
||||
keycloak_quarkus_db_user:
|
||||
default: "keycloak-user"
|
||||
description: "User for database connection"
|
||||
type: "str"
|
||||
keycloak_quarkus_db_pass:
|
||||
default: "keycloak-pass"
|
||||
description: "Password for database connection"
|
||||
type: "str"
|
||||
keycloak_quarkus_db_url:
|
||||
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].url }}"
|
||||
description: "JDBC URL for connecting to database"
|
||||
type: "str"
|
||||
keycloak_quarkus_db_driver_version:
|
||||
default: "{{ keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].version }}"
|
||||
description: "Version for JDBC driver"
|
||||
type: "str"
|
||||
keycloak_quarkus_log:
|
||||
default: "file"
|
||||
type: "str"
|
||||
description: "Enable one or more log handlers in a comma-separated list"
|
||||
keycloak_quarkus_log_level:
|
||||
default: "info"
|
||||
type: "str"
|
||||
description: "The log level of the root category or a comma-separated list of individual categories and their levels"
|
||||
keycloak_quarkus_log_file:
|
||||
default: "data/log/keycloak.log"
|
||||
type: "str"
|
||||
description: "Set the log file path and filename relative to keycloak home"
|
||||
keycloak_quarkus_log_format:
|
||||
default: '%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n'
|
||||
type: "str"
|
||||
description: "Set a format specific to file log entries"
|
||||
keycloak_quarkus_log_target:
|
||||
default: '/var/log/keycloak'
|
||||
type: "str"
|
||||
description: "Set the destination of the keycloak log folder link"
|
||||
keycloak_quarkus_log_max_file_size:
|
||||
default: 10M
|
||||
type: "str"
|
||||
description: >
|
||||
Set the maximum log file size before a log rotation happens; A size configuration option recognises string in this format (shown as a regular
|
||||
expression): [0-9]+[KkMmGgTtPpEeZzYy]?. If no suffix is given, assume bytes.
|
||||
keycloak_quarkus_log_max_backup_index:
|
||||
default: 10
|
||||
type: "str"
|
||||
description: "Set the maximum number of archived log files to keep"
|
||||
keycloak_quarkus_log_file_suffix:
|
||||
default: '.yyyy-MM-dd.zip'
|
||||
type: "str"
|
||||
description: >
|
||||
Set the log file handler rotation file suffix. When used, the file will be rotated based on its suffix. Note: If the suffix ends
|
||||
with .zip or .gz, the rotation file will also be compressed.
|
||||
keycloak_quarkus_proxy_mode:
|
||||
default: 'none'
|
||||
type: "str"
|
||||
description: "The proxy address forwarding mode if the server is behind a reverse proxy. Set to 'none' as it is deprecated according to Keycloak documentation"
|
||||
keycloak_quarkus_proxy_headers:
|
||||
default: ""
|
||||
type: "str"
|
||||
description: "Parse reverse proxy headers (`forwarded` or `xforwarded`), overrides the deprecated keycloak_quarkus_proxy_mode argument"
|
||||
keycloak_quarkus_start_dev:
|
||||
default: false
|
||||
type: "bool"
|
||||
description: "Whether to start the service in development mode (start-dev)"
|
||||
keycloak_quarkus_transaction_xa_enabled:
|
||||
default: true
|
||||
type: "bool"
|
||||
description: "Enable or disable XA transactions which may not be supported by some DBMS"
|
||||
keycloak_quarkus_hostname_strict:
|
||||
default: true
|
||||
type: "bool"
|
||||
description: >
|
||||
Disables dynamically resolving the hostname from request headers. Should always be set to true in production, unless
|
||||
proxy verifies the Host header.
|
||||
keycloak_quarkus_hostname_backchannel_dynamic:
|
||||
default: false
|
||||
type: "bool"
|
||||
description: >
|
||||
Enables dynamic resolving of backchannel URLs, including hostname, scheme, port and context path.
|
||||
Set to true if your application accesses Keycloak via a private network. If set to true, hostname option needs to be specified as a full URL.
|
||||
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
|
||||
keycloak_quarkus_ks_vault_enabled:
|
||||
default: false
|
||||
type: "bool"
|
||||
description: "Whether to enable vault SPI"
|
||||
keycloak_quarkus_ks_vault_file:
|
||||
default: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
|
||||
type: "str"
|
||||
description: "The keystore path for the vault SPI"
|
||||
keycloak_quarkus_ks_vault_type:
|
||||
default: "PKCS12"
|
||||
type: "str"
|
||||
description: "Type of the keystore used for the vault SPI"
|
||||
keycloak_quarkus_ks_vault_pass:
|
||||
required: false
|
||||
type: "str"
|
||||
description: "The password for accessing the keystore vault SPI"
|
||||
keycloak_quarkus_systemd_wait_for_port:
|
||||
description: 'Whether systemd unit should wait for keycloak port before returning'
|
||||
default: "{{ keycloak_quarkus_ha_enabled }}"
|
||||
type: "bool"
|
||||
keycloak_quarkus_systemd_wait_for_port_number:
|
||||
default: "{{ keycloak_quarkus_https_port }}"
|
||||
description: "The port the systemd unit should wait for, by default the https port"
|
||||
type: "int"
|
||||
keycloak_quarkus_systemd_wait_for_log:
|
||||
description: 'Whether systemd unit should wait for service to be up in logs'
|
||||
default: false
|
||||
type: "bool"
|
||||
keycloak_quarkus_systemd_wait_for_timeout:
|
||||
description: "How long to wait for service to be alive (seconds)"
|
||||
default: 60
|
||||
type: 'int'
|
||||
keycloak_quarkus_systemd_wait_for_delay:
|
||||
description: "Activation delay for service systemd unit (seconds)"
|
||||
default: 10
|
||||
type: 'int'
|
||||
keycloak_quarkus_providers:
|
||||
description: >
|
||||
List of provider definition dicts: { 'id': str, 'spi': str, 'url': str, 'local_path': str,
|
||||
'maven': {
|
||||
'repository_url': str, 'group_id': str, 'artifact_id': str, 'version': str, 'username': str, optional, 'password': str, optional
|
||||
},
|
||||
'default': bool,
|
||||
'properties': list of key/value }
|
||||
default: []
|
||||
type: "list"
|
||||
keycloak_quarkus_supported_policy_types:
|
||||
description: "List of str of supported policy types"
|
||||
default: ['password-blacklists']
|
||||
type: "list"
|
||||
keycloak_quarkus_policies:
|
||||
description: "List of policy definition dicts: { 'name': str, 'url': str, 'type': str }"
|
||||
default: []
|
||||
type: "list"
|
||||
keycloak_quarkus_jdbc_download_url:
|
||||
description: "Override the default Maven Central download URL for the JDBC driver"
|
||||
type: "str"
|
||||
keycloak_quarkus_jdbc_download_user:
|
||||
description: "Set a username with which to authenticate when downloading JDBC drivers from an alternative location"
|
||||
type: "str"
|
||||
keycloak_quarkus_jdbc_download_pass:
|
||||
description: >
|
||||
Set a password with which to authenticate when downloading JDBC drivers from an alternative location
|
||||
(requires `keycloak_quarkus_jdbc_download_user``)
|
||||
type: "str"
|
||||
keycloak_quarkus_jdbc_download_validate_certs:
|
||||
default: true
|
||||
description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL"
|
||||
type: "bool"
|
||||
keycloak_quarkus_restart_health_check:
|
||||
default: true
|
||||
description: "Whether to wait for successful health check after restart"
|
||||
type: "bool"
|
||||
keycloak_quarkus_restart_strategy:
|
||||
description: >
|
||||
Strategy task file for restarting in HA, one of restart/[ 'serial', 'none', 'serial_then_parallel' ].yml, or path to
|
||||
file when providing custom strategy; when keycloak_quarkus_ha_enabled and keycloak_quarkus_restart_health_check == true
|
||||
default: "restart/serial.yml"
|
||||
type: "str"
|
||||
keycloak_quarkus_restart_pause:
|
||||
description: "Seconds to wait between restarts in HA strategy"
|
||||
default: 15
|
||||
type: int
|
||||
keycloak_quarkus_restart_health_check_delay:
|
||||
description: "Seconds to let pass before starting healch checks"
|
||||
default: 10
|
||||
type: 'int'
|
||||
keycloak_quarkus_restart_health_check_retries:
|
||||
description: "Number of attempts for successful health check before failing"
|
||||
default: 25
|
||||
type: 'int'
|
||||
keycloak_quarkus_validate_certs:
|
||||
description: "Whether to validate SSL certificates when performing health checks"
|
||||
default: true
|
||||
type: "bool"
|
||||
keycloak_quarkus_show_deprecation_warnings:
|
||||
default: true
|
||||
description: "Whether or not deprecation warnings should be shown"
|
||||
type: "bool"
|
||||
keycloak_quarkus_download_path:
|
||||
description: "Path local to controller for offline/download of install archives"
|
||||
default: "{{ lookup('env', 'PWD') }}"
|
||||
type: "str"
|
||||
keycloak_quarkus_cache_managed_infinispan_config:
|
||||
description: "Manage infinispan configuration"
|
||||
default: "{{ keycloak_quarkus_version is version('26.4.0', '<') }}"
|
||||
type: bool
|
||||
keycloak_quarkus_cache_infinispan_template:
|
||||
description: "Infinispan cache template file"
|
||||
default: "cache-ispn.xml"
|
||||
type: str
|
||||
keycloak_quarkus_cache_embedded_properties:
|
||||
description: Embedded cache properties
|
||||
default: ""
|
||||
type: str
|
||||
keycloak_quarkus_binary_download_user:
|
||||
description: "Username for HTTP Basic Auth when downloading Keycloak binary"
|
||||
type: "str"
|
||||
required: false
|
||||
keycloak_quarkus_binary_download_pass:
|
||||
description: "Password for HTTP Basic Auth when downloading Keycloak binary"
|
||||
type: "str"
|
||||
required: false
|
||||
downstream:
|
||||
options:
|
||||
rhbk_version:
|
||||
default: "26.4.11"
|
||||
description: "Red Hat Build of Keycloak version"
|
||||
type: "str"
|
||||
rhbk_archive:
|
||||
default: "rhbk-{{ rhbk_version }}.zip"
|
||||
description: "Red Hat Build of Keycloak install archive filename"
|
||||
type: "str"
|
||||
rhbk_dest:
|
||||
default: "/opt/rhbk"
|
||||
description: "Root installation directory"
|
||||
type: "str"
|
||||
rhbk_installdir:
|
||||
default: "{{ rhbk_dest }}/rhbk-{{ rhbk_version }}"
|
||||
description: "Installation path for Red Hat Build of Keycloak"
|
||||
type: "str"
|
||||
rhbk_apply_patches:
|
||||
default: false
|
||||
description: "Install Red Hat Build of Keycloak most recent cumulative patch"
|
||||
type: "bool"
|
||||
rhbk_enable:
|
||||
default: true
|
||||
description: "Enable Red Hat Build of Keycloak installation"
|
||||
type: "bool"
|
||||
rhbk_offline_install:
|
||||
default: false
|
||||
description: "Perform an offline install"
|
||||
type: "bool"
|
||||
rhbk_service_name:
|
||||
default: "rhbk"
|
||||
description: "systemd service name for Red Hat Build of Keycloak"
|
||||
type: "str"
|
||||
rhbk_service_desc:
|
||||
default: "Red Hat Build of Keycloak"
|
||||
description: "systemd description for Red Hat Build of Keycloak"
|
||||
type: "str"
|
||||
rhbk_patch_version:
|
||||
required: false
|
||||
description: "Red Hat Build of Keycloak latest cumulative patch version to apply; defaults to latest version when rhbk_apply_patches is True"
|
||||
type: "str"
|
||||
rhbk_patch_bundle:
|
||||
default: "rhbk-{{ rhbk_patch_version | default('[0-9]+[.][0-9]+[.][0-9]+') }}-patch.zip"
|
||||
description: "Red Hat Build of Keycloak patch archive filename"
|
||||
type: "str"
|
||||
rhbk_product_category:
|
||||
default: "RHBK"
|
||||
description: "Unified Downloads API category for Red Hat Build of Keycloak"
|
||||
type: "str"
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
galaxy_info:
|
||||
role_name: keycloak_quarkus
|
||||
namespace: middleware_automation
|
||||
author: Guido Grazioli
|
||||
description: Install keycloak on quarkus server configurations
|
||||
company: Red Hat, Inc.
|
||||
|
||||
license: Apache License 2.0
|
||||
|
||||
min_ansible_version: "2.16"
|
||||
|
||||
platforms:
|
||||
- name: EL
|
||||
versions:
|
||||
- "8"
|
||||
- "9"
|
||||
- name: Fedora
|
||||
- name: Debian
|
||||
- name: Ubuntu
|
||||
|
||||
|
||||
galaxy_tags:
|
||||
- keycloak
|
||||
- quarkus
|
||||
- redhat
|
||||
- rhel
|
||||
- sso
|
||||
- authentication
|
||||
- identity
|
||||
- security
|
||||
- rhbk
|
||||
- debian
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
- name: Save ansible custom facts
|
||||
become: "{{ keycloak_quarkus_bootstrapped_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.template:
|
||||
src: keycloak.fact.j2
|
||||
dest: /etc/ansible/facts.d/keycloak.fact
|
||||
mode: '0644'
|
||||
vars:
|
||||
bootstrapped: true
|
||||
|
||||
- name: Refresh custom facts
|
||||
ansible.builtin.setup:
|
||||
filter: ansible_local
|
||||
|
||||
- name: Ensure that `KEYCLOAK_ADMIN[_PASSWORD]` get purged
|
||||
ansible.builtin.include_tasks: systemd.yml
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
- name: "Initialize configuration key store variables to be written"
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_store_items:
|
||||
- key: "kc.db-password"
|
||||
value: "{{ keycloak_quarkus_db_pass }}"
|
||||
|
||||
- name: "Initialize empty configuration key store"
|
||||
become: "{{ keycloak_quarkus_config_store_require_privilege_escalation | default(true) }}"
|
||||
# keytool doesn't allow creating an empty key store, so this is a hacky way around it
|
||||
ansible.builtin.shell: | # noqa blocked_modules shell is necessary here
|
||||
set -o nounset # abort on unbound variable
|
||||
set -o pipefail # do not hide errors within pipes
|
||||
set -o errexit # abort on nonzero exit status
|
||||
|
||||
echo dummy | keytool -noprompt -importpass -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12
|
||||
keytool -delete -alias dummy -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
|
||||
args:
|
||||
creates: "{{ keycloak_quarkus_config_key_store_file }}"
|
||||
|
||||
- name: "Set configuration key store using keytool"
|
||||
ansible.builtin.shell: | # noqa blocked_modules shell is necessary here
|
||||
set -o nounset # abort on unbound variable
|
||||
set -o pipefail # do not hide errors within pipes
|
||||
|
||||
keytool -list -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
|
||||
retVal=$?
|
||||
|
||||
set -o errexit # abort on nonzero exit status
|
||||
|
||||
if [ $retVal -eq 0 ]; then
|
||||
# value is already in keystore, but keytool has no replace function: delete and re-create instead
|
||||
# note that we can not read whether the value has changed either[^1], so we need to override it
|
||||
# [^1]: https://stackoverflow.com/a/37491400
|
||||
keytool -delete -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }}
|
||||
fi
|
||||
|
||||
echo {{ item.value | quote }} | keytool -noprompt -importpass -alias {{ item.key | quote }} -keystore {{ keycloak_quarkus_config_key_store_file | quote }} -storepass {{ keycloak_quarkus_config_key_store_password | quote }} -storetype PKCS12
|
||||
loop: "{{ keycloak_quarkus_store_items }}"
|
||||
no_log: true
|
||||
become: "{{ keycloak_quarkus_config_store_require_privilege_escalation | default(true) }}"
|
||||
changed_when: true
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
||||
- name: "Set owner of configuration key store {{ keycloak_quarkus_config_key_store_file }}"
|
||||
ansible.builtin.file:
|
||||
path: "{{ keycloak_quarkus_config_key_store_file }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0400'
|
||||
become: "{{ keycloak_quarkus_config_store_require_privilege_escalation | default(true) }}"
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- name: Include firewall config tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: iptables.yml
|
||||
apply:
|
||||
tags:
|
||||
- firewall
|
||||
when: keycloak_quarkus_configure_iptables
|
||||
tags:
|
||||
- firewall
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
---
|
||||
- name: Check deprecation keycloak_quarkus_key_store -> keycloak_quarkus_http_key_store
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
when:
|
||||
- keycloak_quarkus_https_key_store_enabled
|
||||
block:
|
||||
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_file`, superseded by `keycloak_quarkus_https_key_store_file`
|
||||
when:
|
||||
- keycloak_quarkus_key_store_file is defined
|
||||
- keycloak_quarkus_key_store_file != ''
|
||||
- keycloak_quarkus_https_key_store_file == keycloak.home + "/conf/key_store.p12" # default value
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_https_key_store_file: "{{ keycloak_quarkus_key_store_file }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_key_store_file" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Ensure backward compatibility for `keycloak_quarkus_key_store_password`, superseded by `keycloak_quarkus_https_key_store_password`
|
||||
when:
|
||||
- keycloak_quarkus_key_store_password is defined
|
||||
- keycloak_quarkus_key_store_password != ''
|
||||
- keycloak_quarkus_https_key_store_password == "" # default value
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_https_key_store_password: "{{ keycloak_quarkus_key_store_password }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_key_store_password" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
# https://access.redhat.com/documentation/en-us/red_hat_build_of_keycloak/24.0/html-single/upgrading_guide/index#deprecated_literal_proxy_literal_option
|
||||
- name: Check deprecation of keycloak_quarkus_proxy_mode
|
||||
when:
|
||||
- keycloak_quarkus_proxy_mode is defined
|
||||
- keycloak_quarkus_proxy_headers is defined and keycloak_quarkus_proxy_headers | length == 0
|
||||
- keycloak_quarkus_version.split('.') | first | int >= 24
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_proxy_mode" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options
|
||||
- name: Check deprecation of keycloak_quarkus_frontend_url -> keycloak_quarkus_hostname
|
||||
when:
|
||||
- keycloak_quarkus_hostname is not defined
|
||||
- keycloak_quarkus_frontend_url is defined
|
||||
- keycloak_quarkus_frontend_url != ''
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_hostname: "{{ keycloak_quarkus_frontend_url }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_frontend_url" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options
|
||||
- name: Check deprecation of keycloak_quarkus_hostname_strict_https + keycloak_quarkus_host + keycloak_quarkus_port + keycloak_quarkus_path -> keycloak_quarkus_hostname
|
||||
when:
|
||||
- keycloak_quarkus_hostname is not defined
|
||||
- keycloak_quarkus_hostname_strict_https is defined or keycloak_quarkus_frontend_url is defined or keycloak_quarkus_port is defined or keycloak_quarkus_path is defined
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_hostname: >-
|
||||
{% set protocol = '' %}
|
||||
{% if keycloak_quarkus_hostname_strict_https %}
|
||||
{% set protocol = 'https://' %}
|
||||
{% elif keycloak_quarkus_hostname_strict_https is defined and keycloak_quarkus_hostname_strict_https is False %}
|
||||
{% set protocol = 'http://' %}
|
||||
{% endif %}
|
||||
{{ protocol }}{{ keycloak_quarkus_host }}:{{ keycloak_quarkus_port }}/{{ keycloak_quarkus_path }}
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_hostname_strict_https or keycloak_quarkus_frontend_url or keycloak_quarkus_frontend_url or keycloak_quarkus_hostname" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options
|
||||
- name: Check deprecation of keycloak_quarkus_admin_url -> keycloak_quarkus_hostname_admin
|
||||
when:
|
||||
- keycloak_quarkus_hostname_admin is not defined
|
||||
- keycloak_quarkus_admin_url is defined
|
||||
- keycloak_quarkus_admin_url != ''
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_hostname_admin: "{{ keycloak_quarkus_admin_url }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_admin_url" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/26.0/html-single/upgrading_guide/index#new_hostname_options
|
||||
- name: Check deprecation of keycloak_quarkus_hostname_strict_backchannel -> keycloak_quarkus_hostname_backchannel_dynamic
|
||||
when:
|
||||
- keycloak_quarkus_hostname_backchannel_dynamic is not defined
|
||||
- keycloak_quarkus_hostname_strict_backchannel is defined
|
||||
- keycloak_quarkus_hostname_strict_backchannel != ''
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_hostname_backchannel_dynamic: "{{ keycloak_quarkus_hostname_strict_backchannel == False }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_hostname_backchannel_dynamic" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://github.com/keycloak/keycloak/issues/30009
|
||||
- name: Check deprecation of keycloak_quarkus_admin_user -> keycloak_quarkus_bootstrap_admin_user
|
||||
when:
|
||||
- keycloak_quarkus_bootstrap_admin_user is not defined
|
||||
- keycloak_quarkus_admin_user is defined
|
||||
- keycloak_quarkus_admin_user != ''
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_user }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_admin_user" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
# https://github.com/keycloak/keycloak/issues/30009
|
||||
- name: Check deprecation of keycloak_quarkus_admin_pass -> keycloak_quarkus_bootstrap_admin_password
|
||||
when:
|
||||
- keycloak_quarkus_bootstrap_admin_password is not defined
|
||||
- keycloak_quarkus_admin_pass is defined
|
||||
- keycloak_quarkus_admin_pass != ''
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_bootstrap_admin_user: "{{ keycloak_quarkus_admin_pass }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_admin_pass" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
- name: Check deprecation of keycloak_quarkus_bind_address -> keycloak_quarkus_http_host
|
||||
when:
|
||||
- keycloak_quarkus_bind_address is defined
|
||||
- keycloak_quarkus_bind_address != '0.0.0.0'
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
changed_when: keycloak_quarkus_show_deprecation_warnings
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_http_host: "{{ keycloak_quarkus_bind_address }}"
|
||||
keycloak_quarkus_deprecated_variable: "keycloak_quarkus_bind_address" # read in deprecation handler
|
||||
notify:
|
||||
- print deprecation warning
|
||||
|
||||
- name: Flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
- name: "Check if packages are already installed" # noqa command-instead-of-module this runs faster
|
||||
ansible.builtin.command: "rpm -q {{ packages_list | join(' ') }}"
|
||||
register: keycloak_quarkus_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:
|
||||
keycloak_quarkus_packages_to_install: "{{ keycloak_quarkus_packages_to_install | default([]) + keycloak_quarkus_rpm_info.stdout_lines | \
|
||||
map('regex_findall', 'package (.+) is not installed$') | default([]) | flatten }}"
|
||||
when: ansible_facts.os_family == "RedHat"
|
||||
|
||||
- name: "Install packages: {{ keycloak_quarkus_packages_to_install }}"
|
||||
become: "{{ keycloak_quarkus_fastpackages_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.dnf:
|
||||
name: "{{ keycloak_quarkus_packages_to_install }}"
|
||||
state: present
|
||||
when:
|
||||
- keycloak_quarkus_packages_to_install | default([]) | length > 0
|
||||
- ansible_facts.os_family == "RedHat"
|
||||
|
||||
- name: "Install packages: {{ packages_list }}"
|
||||
become: "{{ keycloak_quarkus_fastpackages_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.package:
|
||||
name: "{{ packages_list }}"
|
||||
state: present
|
||||
when:
|
||||
- packages_list | default([]) | length > 0
|
||||
- ansible_facts.os_family == "Debian"
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
- name: Ensure required package firewalld are installed
|
||||
ansible.builtin.include_tasks: fastpackages.yml
|
||||
vars:
|
||||
packages_list:
|
||||
- firewalld
|
||||
|
||||
- name: Enable and start the firewalld service
|
||||
become: "{{ keycloak_quarkus_firewalld_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.systemd:
|
||||
name: firewalld
|
||||
enabled: true
|
||||
state: started
|
||||
|
||||
- name: "Configure firewall for http port: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_firewalld_require_privilege_escalation | default(true) }}"
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
immediate: true
|
||||
loop:
|
||||
- "{{ keycloak_quarkus_http_port }}/tcp"
|
||||
when: keycloak_quarkus_http_enabled | bool
|
||||
|
||||
- name: "Configure firewall for ports: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_firewalld_require_privilege_escalation | default(true) }}"
|
||||
ansible.posix.firewalld:
|
||||
port: "{{ item }}"
|
||||
permanent: true
|
||||
state: enabled
|
||||
immediate: true
|
||||
loop:
|
||||
- "{{ keycloak_quarkus_https_port }}/tcp"
|
||||
- "{{ keycloak_quarkus_http_management_port }}/tcp"
|
||||
- "{{ keycloak_quarkus_jgroups_port }}/tcp"
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
---
|
||||
- name: Validate parameters
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak.home is defined
|
||||
- keycloak_quarkus_service_user is defined
|
||||
- keycloak_quarkus_dest is defined
|
||||
- keycloak_quarkus_archive is defined
|
||||
- keycloak_quarkus_download_url is defined
|
||||
- keycloak_quarkus_version is defined
|
||||
- keycloak_quarkus_local_path is defined
|
||||
quiet: true
|
||||
|
||||
- name: Check for an existing deployment
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak.home }}"
|
||||
register: keycloak_quarkus_existing_deploy
|
||||
|
||||
- name: Stop and restart if existing deployment exists and install forced
|
||||
when: keycloak_quarkus_existing_deploy.stat.exists and keycloak_quarkus_force_install | bool
|
||||
block:
|
||||
- name: "Stop the old service: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
failed_when: false
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
state: stopped
|
||||
- name: "Remove the old deployment: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.file:
|
||||
path: "{{ keycloak_quarkus_home }}"
|
||||
state: absent
|
||||
|
||||
- name: Check for an existing deployment after possible forced removal
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak_quarkus_home }}"
|
||||
register: keycloak_quarkus_existing_deploy
|
||||
|
||||
- name: "Create service user/group: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.user:
|
||||
name: "{{ keycloak.service_user }}"
|
||||
home: /opt/keycloak
|
||||
system: true
|
||||
create_home: false
|
||||
|
||||
- name: "Create install location: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.file:
|
||||
dest: "{{ keycloak_quarkus_dest }}"
|
||||
state: directory
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0750'
|
||||
|
||||
- name: Create directory for ansible custom facts
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
recurse: true
|
||||
path: /etc/ansible/facts.d
|
||||
|
||||
## check remote archive
|
||||
- name: Set download archive path
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_archive_full_path: "{{ keycloak_quarkus_dest }}/{{ keycloak.bundle }}"
|
||||
|
||||
- name: Check download archive path
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak_quarkus_archive_full_path }}"
|
||||
register: keycloak_quarkus_archive_path
|
||||
|
||||
## download to controller
|
||||
- name: Download keycloak archive
|
||||
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
|
||||
url: "{{ keycloak_quarkus_download_url }}"
|
||||
dest: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
mode: '0640'
|
||||
url_username: "{{ keycloak_quarkus_binary_download_user | default(omit) }}"
|
||||
url_password: "{{ keycloak_quarkus_binary_download_pass | default(omit) }}"
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
when:
|
||||
- keycloak_quarkus_archive_path is defined
|
||||
- keycloak_quarkus_archive_path.stat is defined
|
||||
- not keycloak_quarkus_archive_path.stat.exists
|
||||
- not keycloak.offline_install
|
||||
- not rhbk_enable is defined or not rhbk_enable
|
||||
|
||||
- name: Perform download from RHN using the Unified Downloads API
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
when:
|
||||
- keycloak_quarkus_archive_path is defined
|
||||
- keycloak_quarkus_archive_path.stat is defined
|
||||
- not keycloak_quarkus_archive_path.stat.exists
|
||||
- rhbk_enable is defined and rhbk_enable
|
||||
- not keycloak.offline_install
|
||||
- keycloak_quarkus_alternate_download_url is undefined
|
||||
block:
|
||||
- name: Retrieve product download using Unified Downloads API
|
||||
middleware_automation.common.product_search:
|
||||
client_id: "{{ rhn_username }}"
|
||||
client_secret: "{{ rhn_password }}"
|
||||
product_type: DISTRIBUTION
|
||||
product_version: "{{ rhbk_version }}"
|
||||
product_category: "{{ rhbk_product_category }}"
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
register: keycloak_quarkus_rhn_products
|
||||
no_log: "{{ omit_rhn_output | default(true) }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Determine install zipfile from search results
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_rhn_filtered_products: "{{ keycloak_quarkus_rhn_products.results | selectattr('file_name', 'match', '[^/]*/' + rhbk_archive + '$') }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Download Red Hat Build of Keycloak
|
||||
middleware_automation.common.product_download: # noqa risky-file-permissions delegated, uses controller host user
|
||||
client_id: "{{ rhn_username }}"
|
||||
client_secret: "{{ rhn_password }}"
|
||||
product_id: "{{ (keycloak_quarkus_rhn_filtered_products | first).id }}"
|
||||
dest: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
mode: '0640'
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
no_log: "{{ omit_rhn_output | default(true) }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
become: false
|
||||
|
||||
- name: Perform download of RHBK from alternate download location
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
become: false
|
||||
when:
|
||||
- keycloak_quarkus_archive_path is defined
|
||||
- keycloak_quarkus_archive_path.stat is defined
|
||||
- not keycloak_quarkus_archive_path.stat.exists
|
||||
- rhbk_enable is defined and rhbk_enable
|
||||
- not keycloak.offline_install
|
||||
- keycloak_quarkus_alternate_download_url is defined
|
||||
ansible.builtin.get_url: # noqa risky-file-permissions delegated, uses controller host user
|
||||
url: "{{ keycloak_quarkus_alternate_download_url }}"
|
||||
dest: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
mode: '0640'
|
||||
url_username: "{{ keycloak_quarkus_download_user | default(omit) }}"
|
||||
url_password: "{{ keycloak_quarkus_download_pass | default(omit) }}"
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
|
||||
- name: Check downloaded archive
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
register: keycloak_quarkus_local_archive_path
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
## copy and unpack
|
||||
- name: Copy archive to target nodes
|
||||
ansible.builtin.copy:
|
||||
src: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
dest: "{{ keycloak_quarkus_archive_full_path }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
register: keycloak_quarkus_new_version_downloaded
|
||||
when:
|
||||
- not keycloak_quarkus_archive_path.stat.exists
|
||||
- keycloak_quarkus_local_archive_path.stat is defined
|
||||
- keycloak_quarkus_local_archive_path.stat.exists
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: "Check target directory /bin/: {{ keycloak.home }}"
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak.home }}/bin/"
|
||||
register: keycloak_quarkus_path_to_workdir
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: "Extract Keycloak archive on target" # noqa no-handler need to run this here
|
||||
ansible.builtin.unarchive:
|
||||
remote_src: true
|
||||
src: "{{ keycloak_quarkus_archive_full_path }}"
|
||||
dest: "{{ keycloak_quarkus_dest }}"
|
||||
creates: "{{ keycloak.home }}/bin/"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
when:
|
||||
- (not keycloak_quarkus_path_to_workdir.stat.exists) or keycloak_quarkus_new_version_downloaded.changed
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
||||
- name: Inform decompression was not executed
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ keycloak.home }} already exists and version unchanged, skipping decompression"
|
||||
when:
|
||||
- (not keycloak_quarkus_new_version_downloaded.changed) and keycloak_quarkus_path_to_workdir.stat.exists
|
||||
|
||||
- name: "Copy private key to target"
|
||||
ansible.builtin.copy:
|
||||
content: "{{ keycloak_quarkus_key_content }}"
|
||||
dest: "{{ keycloak_quarkus_key_file }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
when:
|
||||
- keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled
|
||||
- keycloak_quarkus_key_file_copy_enabled is defined and keycloak_quarkus_key_file_copy_enabled
|
||||
- keycloak_quarkus_key_content | length > 0
|
||||
|
||||
- name: "Copy certificate to target"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ keycloak_quarkus_cert_file_src }}"
|
||||
dest: "{{ keycloak_quarkus_cert_file }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0644'
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
when:
|
||||
- keycloak_quarkus_https_key_file_enabled is defined and keycloak_quarkus_https_key_file_enabled
|
||||
- keycloak_quarkus_cert_file_copy_enabled is defined and keycloak_quarkus_cert_file_copy_enabled
|
||||
- keycloak_quarkus_cert_file_src | length > 0
|
||||
|
||||
- name: "Install JDBC driver: {{ keycloak_quarkus_db_engine }}"
|
||||
ansible.builtin.include_tasks: jdbc_driver.yml
|
||||
when:
|
||||
- rhbk_enable is defined and rhbk_enable
|
||||
- keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url is defined
|
||||
|
||||
- name: "Download custom providers via http"
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ item.url }}"
|
||||
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
checksum: "{{ item.checksum | default(omit) }}"
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_providers }}"
|
||||
when: item.url is defined and item.url | length > 0
|
||||
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
|
||||
notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}"
|
||||
|
||||
# this requires the `lxml` package to be installed; we redirect this step to localhost such that we do need to install it on the remote hosts
|
||||
- name: "Download custom providers to localhost using maven"
|
||||
middleware_automation.common.maven_artifact:
|
||||
repository_url: "{{ item.maven.repository_url }}"
|
||||
group_id: "{{ item.maven.group_id }}"
|
||||
artifact_id: "{{ item.maven.artifact_id }}"
|
||||
version: "{{ item.maven.version | default(omit) }}"
|
||||
username: "{{ item.maven.username | default(omit) }}"
|
||||
password: "{{ item.maven.password | default(omit) }}"
|
||||
dest: "{{ keycloak_quarkus_local_path.stat.path }}/{{ item.id }}.jar"
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
delegate_to: "localhost"
|
||||
run_once: true
|
||||
loop: "{{ keycloak_quarkus_providers }}"
|
||||
when: item.maven is defined
|
||||
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
|
||||
|
||||
- name: "Copy maven providers"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ keycloak_quarkus_local_path.stat.path }}/{{ item.id }}.jar"
|
||||
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
checksum: "{{ item.checksum | default(omit) }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_providers }}"
|
||||
when: item.maven is defined
|
||||
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
|
||||
notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}"
|
||||
|
||||
- name: "Copy local providers"
|
||||
ansible.builtin.copy:
|
||||
src: "{{ item.local_path }}"
|
||||
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
remote_src: "{{ item.remote | default(false) }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_providers }}"
|
||||
when: item.local_path is defined
|
||||
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
|
||||
notify: "{{ ['invalidate keycloak theme cache', 'rebuild keycloak config', 'restart keycloak'] if not item.restart is defined or item.restart else [] }}"
|
||||
|
||||
- name: Ensure required folder structure for policies exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ keycloak.home }}/data/{{ item | lower }}"
|
||||
state: directory
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0750'
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_supported_policy_types }}"
|
||||
|
||||
- name: "Install custom policies"
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ item.url }}"
|
||||
dest: "{{ keycloak.home }}/data/{{ item.type | default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
validate_certs: "{{ keycloak_quarkus_download_validate_certs | default(omit) }}"
|
||||
become: "{{ keycloak_quarkus_install_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_policies }}"
|
||||
when: item.url is defined and item.url | length > 0
|
||||
notify: "restart keycloak"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
# From https://docs.redhat.com/en/documentation/red_hat_build_of_keycloak/24.0/html/server_developer_guide/themes#creating_a_theme:
|
||||
# If you want to manually delete the content of the themes cache,
|
||||
# you can do so by deleting the data/tmp/kc-gzip-cache directory of the server distribution
|
||||
# It can be useful for instance if you redeployed custom providers or custom themes without
|
||||
# disabling themes caching in the previous server executions.
|
||||
- name: "Delete theme cache directory: {{ keycloak.service_name }}"
|
||||
ansible.builtin.file:
|
||||
path: "{{ keycloak.home }}/data/tmp/kc-gzip-cache"
|
||||
state: absent
|
||||
become: "{{ keycloak_quarkus_invalidate_theme_cache_require_privilege_escalation | default(true) }}"
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
- 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: "{{ keycloak_quarkus_iptables_require_privilege_escalation | default(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 }}"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
---
|
||||
- name: "Verify valid parameters for download credentials when specified"
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
When JDBC driver download credentials are set, both the username and the password MUST be set
|
||||
when: >
|
||||
(keycloak_quarkus_jdbc_download_user is undefined and keycloak_quarkus_jdbc_download_pass is not undefined) or
|
||||
(keycloak_quarkus_jdbc_download_pass is undefined and keycloak_quarkus_jdbc_download_user is not undefined)
|
||||
|
||||
- name: "Retrieve JDBC Driver from {{ keycloak_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}"
|
||||
ansible.builtin.get_url:
|
||||
url: "{{ keycloak_quarkus_jdbc_download_url | default(keycloak_quarkus_default_jdbc[keycloak_quarkus_db_engine].driver_jar_url) }}"
|
||||
dest: "{{ keycloak.home }}/providers"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
url_username: "{{ keycloak_quarkus_jdbc_download_user | default(omit) }}"
|
||||
url_password: "{{ keycloak_quarkus_jdbc_download_pass | default(omit) }}"
|
||||
validate_certs: "{{ keycloak_quarkus_jdbc_download_validate_certs | default(omit) }}"
|
||||
mode: '0640'
|
||||
become: "{{ keycloak_quarkus_jdbc_driver_require_privilege_escalation | default(true) }}"
|
||||
notify:
|
||||
- restart keycloak
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
---
|
||||
# tasks file for keycloak
|
||||
- name: Check prerequisites
|
||||
ansible.builtin.include_tasks:
|
||||
file: prereqs.yml
|
||||
apply:
|
||||
tags:
|
||||
- prereqs
|
||||
tags:
|
||||
- prereqs
|
||||
- always
|
||||
|
||||
- name: Check for deprecations
|
||||
ansible.builtin.include_tasks:
|
||||
file: deprecations.yml
|
||||
apply:
|
||||
tags:
|
||||
- always
|
||||
tags:
|
||||
- always
|
||||
|
||||
- name: Distro specific tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: "{{ ansible_os_family | lower }}.yml"
|
||||
apply:
|
||||
tags:
|
||||
- unbound
|
||||
tags:
|
||||
- unbound
|
||||
|
||||
- name: Include install tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: install.yml
|
||||
apply:
|
||||
tags:
|
||||
- install
|
||||
tags:
|
||||
- install
|
||||
|
||||
- name: Include systemd tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: systemd.yml
|
||||
apply:
|
||||
tags:
|
||||
- systemd
|
||||
tags:
|
||||
- systemd
|
||||
|
||||
- name: Include configuration key store tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: config_store.yml
|
||||
apply:
|
||||
tags:
|
||||
- install
|
||||
when: keycloak.config_key_store_enabled
|
||||
tags:
|
||||
- install
|
||||
|
||||
- name: Create tcpping cluster node list
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_cluster_nodes: >
|
||||
{{ keycloak_quarkus_cluster_nodes | default([]) + [
|
||||
{
|
||||
"name": item,
|
||||
"address": 'jgroups-' + item,
|
||||
"inventory_host": hostvars[item].keycloak_quarkus_jgroups_ip | default(item) + '[' + (keycloak_quarkus_jgroups_port | string) + ']',
|
||||
"value": hostvars[item].keycloak_quarkus_jgroups_ip | default(item)
|
||||
}
|
||||
] }}
|
||||
loop: "{{ ansible_play_batch }}"
|
||||
when: keycloak_quarkus_ha_enabled and keycloak_quarkus_ha_discovery == 'TCPPING'
|
||||
|
||||
|
||||
- name: Determine the config files
|
||||
ansible.builtin.set_fact:
|
||||
keycloak_quarkus_config_files: "{{ ['keycloak.conf', 'quarkus.properties'] + (keycloak_quarkus_cache_managed_infinispan_config | ternary([keycloak_quarkus_cache_infinispan_template], [])) }}"
|
||||
|
||||
- name: "Configure config files for keycloak service"
|
||||
ansible.builtin.template:
|
||||
src: "{{ item }}.j2"
|
||||
dest: "{{ keycloak.home }}/conf/{{ item }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0640'
|
||||
become: "{{ keycloak_quarkus_require_privilege_escalation | default(true) }}"
|
||||
loop: "{{ keycloak_quarkus_config_files }}"
|
||||
notify:
|
||||
- rebuild keycloak config
|
||||
- restart keycloak
|
||||
|
||||
- name: Ensure logdirectory exists
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ keycloak.log.file | dirname }}"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0775'
|
||||
become: "{{ keycloak_quarkus_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: Ensure tmp-directory exists
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
path: "{{ keycloak.home }}/data/tmp"
|
||||
owner: "{{ keycloak.service_user }}"
|
||||
group: "{{ keycloak.service_group }}"
|
||||
mode: '0755'
|
||||
become: "{{ keycloak_quarkus_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: Flush pending handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: "Start and wait for keycloak service"
|
||||
ansible.builtin.include_tasks: start.yml
|
||||
|
||||
- name: Link default logs directory
|
||||
ansible.builtin.file:
|
||||
state: link
|
||||
src: "{{ keycloak.log.file | dirname }}"
|
||||
dest: "{{ keycloak_quarkus_log_target }}"
|
||||
force: true
|
||||
become: "{{ keycloak_quarkus_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: Check service status
|
||||
ansible.builtin.systemd_service:
|
||||
name: "{{ keycloak.service_name }}"
|
||||
register: keycloak_quarkus_service_status
|
||||
changed_when: false
|
||||
|
||||
- name: "Notify to remove `keycloak_quarkus_bootstrap_admin_user[_password]` env vars"
|
||||
when:
|
||||
- not ansible_local.keycloak.general.bootstrapped | default(false) | bool # it was not bootstrapped prior to the current role's execution
|
||||
- keycloak_quarkus_service_status.status.ActiveState == "active" # but it is now
|
||||
ansible.builtin.assert: { that: true, quiet: true }
|
||||
changed_when: true
|
||||
notify:
|
||||
- bootstrapped
|
||||
|
||||
- name: Flush pending handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
---
|
||||
- name: Validate admin console password
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak_quarkus_bootstrap_admin_password is defined
|
||||
- keycloak_quarkus_bootstrap_admin_password is not none
|
||||
- keycloak_quarkus_bootstrap_admin_password | length > 12
|
||||
quiet: true
|
||||
fail_msg: "The console administrator password is empty or invalid. Please set the keycloak_quarkus_bootstrap_admin_password to a 12+ char long string"
|
||||
success_msg: "{{ 'Console administrator password OK' }}"
|
||||
|
||||
- name: Validate http_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' }}"
|
||||
|
||||
- name: Validate http_management_relative_path
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak_quarkus_http_management_relative_path is regex('^/.*')
|
||||
quiet: true
|
||||
fail_msg: "The relative path for keycloak_quarkus_http_management_relative_path must begin with /"
|
||||
success_msg: "{{ 'Relative mgmt path OK' }}"
|
||||
when: keycloak_quarkus_http_management_relative_path is defined
|
||||
|
||||
- name: Validate configuration
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- (keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
|
||||
(not keycloak_quarkus_ha_enabled and keycloak_quarkus_db_enabled) or
|
||||
(not keycloak_quarkus_ha_enabled and not keycloak_quarkus_db_enabled)
|
||||
quiet: true
|
||||
fail_msg: "HA setup requires 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 }}"
|
||||
|
||||
- name: Check local download archive path
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak_quarkus_download_path }}"
|
||||
register: keycloak_quarkus_local_path
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
become: false
|
||||
|
||||
- name: Validate local download path
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak_quarkus_local_path.stat.exists
|
||||
- keycloak_quarkus_local_path.stat.readable
|
||||
- keycloak_quarkus_offline_install or keycloak_quarkus_local_path.stat.writeable
|
||||
quiet: true
|
||||
fail_msg: "Defined controller path for downloading resources is incorrect or unreadable: {{ keycloak_quarkus_download_path }}"
|
||||
success_msg: "Will download resource to controller path: {{ keycloak_quarkus_download_path }}"
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Check downloaded archive if offline
|
||||
ansible.builtin.stat:
|
||||
path: "{{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
when: keycloak_quarkus_offline_install
|
||||
register: keycloak_quarkus_local_archive_path_check
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: Validate local downloaded archive if offline
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak_quarkus_local_archive_path_check.stat.exists
|
||||
- keycloak_quarkus_local_archive_path_check.stat.readable
|
||||
quiet: true
|
||||
fail_msg: "Configured for offline install but install archive not found at: {{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
success_msg: "Will install offline with expected archive: {{ keycloak_quarkus_local_path.stat.path }}/{{ keycloak.bundle }}"
|
||||
when: keycloak_quarkus_offline_install
|
||||
delegate_to: localhost
|
||||
run_once: true
|
||||
|
||||
- name: "Validate keytool"
|
||||
when: keycloak_quarkus_config_key_store_password | length > 0
|
||||
block:
|
||||
- name: "Check run keytool"
|
||||
changed_when: false
|
||||
ansible.builtin.command: keytool -help
|
||||
register: keycloak_quarkus_keytool_check
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Fail when no keytool found"
|
||||
when: keycloak_quarkus_keytool_check.rc != 0
|
||||
ansible.builtin.fail:
|
||||
msg: "keytool NOT found in the PATH, but is required for setting up the configuration key store"
|
||||
|
||||
- name: "Validate providers"
|
||||
ansible.builtin.assert:
|
||||
that: >
|
||||
item.id is defined and item.id | length > 0 and
|
||||
( (item.spi is defined and item.spi | length > 0) or
|
||||
(item.url is defined and item.url | length > 0) or
|
||||
( item.maven is defined and item.maven.repository_url is defined and item.maven.repository_url | length > 0 and
|
||||
item.maven.group_id is defined and item.maven.group_id | length > 0 and
|
||||
item.maven.artifact_id is defined and item.maven.artifact_id | length > 0) or
|
||||
(item.local_path is defined and item.local_path | length > 0)
|
||||
)
|
||||
quiet: true
|
||||
fail_msg: >
|
||||
Providers definition incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property
|
||||
loop: "{{ keycloak_quarkus_providers }}"
|
||||
no_log: "{{ item.maven.password is defined and item.maven.password | length > 0 | default(false) }}"
|
||||
|
||||
- name: "Validate policies"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item.name is defined and item.name | length > 0
|
||||
- item.url is defined and item.url | length > 0
|
||||
- item.type is not defined or item.type | lower in keycloak_quarkus_supported_policy_types
|
||||
quiet: true
|
||||
fail_msg: >
|
||||
Policy definition is incorrect: `name` and one of `url` are mandatory, `type` needs to be left empty or one of {{ keycloak_quarkus_supported_policy_types }}.
|
||||
loop: "{{ keycloak_quarkus_policies }}"
|
||||
|
||||
- name: "Validate additional env variables"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- item.key is defined and item.key | length > 0
|
||||
- item.value is defined and item.value | length > 0
|
||||
quiet: true
|
||||
fail_msg: "Additional env variable definition is incorrect: `key` and `value` are mandatory."
|
||||
no_log: true
|
||||
loop: "{{ keycloak_quarkus_additional_env_vars }}"
|
||||
|
||||
- name: "Validate proxy-headers"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- keycloak_quarkus_proxy_headers | lower in ['', 'forwarded', 'xforwarded']
|
||||
quiet: true
|
||||
fail_msg: "keycloak_quarkus_proxy_headers must be either '', 'forwarded' or 'xforwarded'"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
# cf. https://www.keycloak.org/server/configuration#_optimize_the_keycloak_startup
|
||||
- name: "Rebuild config: {{ keycloak.service_name }}"
|
||||
ansible.builtin.shell: | # noqa blocked_modules shell is necessary here
|
||||
env -i bash -c "set -a ; source {{ keycloak_quarkus_sysconf_file }} ; {{ keycloak.home }}/bin/kc.sh build "
|
||||
become: "{{ keycloak_quarkus_rebuild_config_require_privilege_escalation | default(true) }}"
|
||||
changed_when: true
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- name: Include firewall config tasks
|
||||
ansible.builtin.include_tasks:
|
||||
file: firewalld.yml
|
||||
apply:
|
||||
tags:
|
||||
- firewall
|
||||
when: keycloak_quarkus_configure_firewalld
|
||||
tags:
|
||||
- firewall
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
- name: "Restart and enable service: {{ keycloak.service_name }}"
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ keycloak.service_name }}"
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
become: "{{ keycloak_quarkus_restart_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: "Wait until service becomes active: {{ keycloak.service_name }}"
|
||||
ansible.builtin.uri:
|
||||
url: "{{ keycloak.health_url }}"
|
||||
validate_certs: "{{ keycloak_quarkus_validate_certs }}"
|
||||
register: keycloak_quarkus_status
|
||||
until: keycloak_quarkus_status.status == 200
|
||||
retries: "{{ keycloak_quarkus_restart_health_check_retries }}"
|
||||
delay: "{{ keycloak_quarkus_restart_health_check_delay }}"
|
||||
when: internal_force_health_check | default(keycloak_quarkus_restart_health_check)
|
||||
|
||||
- name: Wait to give distributed ispn caches time to (re-)replicate back onto first host
|
||||
ansible.builtin.pause:
|
||||
seconds: "{{ keycloak_quarkus_restart_pause }}"
|
||||
when:
|
||||
- keycloak_quarkus_ha_enabled
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
- name: "Display message"
|
||||
ansible.builtin.debug:
|
||||
msg: "keycloak_quarkus_restart_strategy is none, skipping restart"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
- name: "Restart services in serial, with optional healtch check (keycloak_quarkus_restart_health_check)"
|
||||
throttle: 1
|
||||
block:
|
||||
- name: "Restart and enable service: {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks:
|
||||
file: restart.yml
|
||||
apply:
|
||||
delegate_to: "{{ item }}"
|
||||
run_once: true
|
||||
loop: "{{ ansible_play_hosts }}"
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
- name: Verify first restarted service with health URL, then rest restart in parallel
|
||||
block:
|
||||
- name: "Restart and enable service on initial host: {{ keycloak.service_name }}"
|
||||
ansible.builtin.include_tasks:
|
||||
file: restart.yml
|
||||
apply:
|
||||
delegate_to: "{{ ansible_play_hosts | first }}"
|
||||
run_once: true
|
||||
vars:
|
||||
internal_force_health_check: true
|
||||
|
||||
- name: "Restart and enable service on other hosts: {{ keycloak.service_name }}"
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ keycloak.service_name }}"
|
||||
enabled: true
|
||||
state: restarted
|
||||
daemon_reload: true
|
||||
become: "{{ keycloak_quarkus_restart_require_privilege_escalation | default(true) }}"
|
||||
when: inventory_hostname != ansible_play_hosts | first
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
- name: "Start service: {{ keycloak.service_name }}"
|
||||
ansible.builtin.systemd:
|
||||
name: keycloak
|
||||
enabled: true
|
||||
state: started
|
||||
daemon_reload: true
|
||||
become: "{{ keycloak_quarkus_start_require_privilege_escalation | default(true) }}"
|
||||
|
||||
- name: "Wait until service becomes active: {{ keycloak.service_name }}"
|
||||
ansible.builtin.uri:
|
||||
url: "{{ keycloak.health_url }}"
|
||||
validate_certs: "{{ keycloak_quarkus_validate_certs }}"
|
||||
register: keycloak_quarkus_status
|
||||
until: keycloak_quarkus_status.status == 200
|
||||
retries: 25
|
||||
delay: 10
|
||||
when: internal_force_health_check | default(keycloak_quarkus_restart_health_check)
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
- name: "Configure sysconfig file for service: {{ keycloak.service_name }}"
|
||||
become: "{{ keycloak_quarkus_systemd_require_privilege_escalation | default(true) }}"
|
||||
ansible.builtin.template:
|
||||
src: keycloak-sysconfig.j2
|
||||
dest: "{{ keycloak_quarkus_sysconf_file }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0640'
|
||||
vars:
|
||||
keycloak_sys_pkg_java_home: "{{ keycloak_quarkus_pkg_java_home }}"
|
||||
notify:
|
||||
- rebuild keycloak config
|
||||
- restart keycloak
|
||||
|
||||
- name: "Configure systemd unit file for keycloak service"
|
||||
ansible.builtin.template:
|
||||
src: keycloak.service.j2
|
||||
dest: /etc/systemd/system/keycloak.service
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
become: "{{ keycloak_quarkus_systemd_require_privilege_escalation | default(true) }}"
|
||||
register: keycloak_quarkus_systemdunit
|
||||
notify:
|
||||
- rebuild keycloak config
|
||||
- restart keycloak
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
{{ ansible_managed | comment('xml') }}
|
||||
<!--
|
||||
~ Copyright 2019 Red Hat, Inc. and/or its affiliates
|
||||
~ and other contributors as indicated by the @author tags.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<infinispan
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:infinispan:config:15.0 http://www.infinispan.org/schemas/infinispan-config-15.0.xsd"
|
||||
xmlns="urn:infinispan:config:15.0">
|
||||
|
||||
{% set stack_expression='' %}
|
||||
{% if keycloak_quarkus_version is version_compare('26.2.0', '<') %}
|
||||
{% if keycloak_quarkus_ha_enabled %}
|
||||
{% if keycloak_quarkus_ha_discovery == 'TCPPING' %}
|
||||
{% set stack_expression='stack="tcpping"' %}
|
||||
<jgroups>
|
||||
<stack name="tcpping" extends="tcp">
|
||||
<!-- <TCP external_addr="${env.KC_EXTERNAL_ADDR}" bind_addr="{{ keycloak_quarkus_http_host }}" bind_port="{{ keycloak_quarkus_jgroups_port }}" /> -->
|
||||
<TCPPING
|
||||
initial_hosts="{{ keycloak_quarkus_cluster_nodes | map(attribute='inventory_host') | join (',') }}"
|
||||
port_range="0"
|
||||
stack.combine="REPLACE"
|
||||
stack.position="MPING"
|
||||
/>
|
||||
</stack>
|
||||
</jgroups>
|
||||
{% elif keycloak_quarkus_ha_discovery == 'JDBCPING' %}
|
||||
{% set stack_expression='stack="JDBC_PING2"' %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<cache-container name="keycloak">
|
||||
<transport lock-timeout="60000" {{ stack_expression }}/>
|
||||
<local-cache name="realms" simple-cache="true">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<memory max-count="10000"/>
|
||||
</local-cache>
|
||||
<local-cache name="users" simple-cache="true">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<memory max-count="10000"/>
|
||||
</local-cache>
|
||||
<distributed-cache name="sessions" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
<memory max-count="10000"/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="authenticationSessions" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="offlineSessions" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
<memory max-count="10000"/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="clientSessions" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
<memory max-count="10000"/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="offlineClientSessions" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
<memory max-count="10000"/>
|
||||
</distributed-cache>
|
||||
<distributed-cache name="loginFailures" owners="2">
|
||||
<expiration lifespan="-1"/>
|
||||
</distributed-cache>
|
||||
<local-cache name="authorization" simple-cache="true">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<memory max-count="10000"/>
|
||||
</local-cache>
|
||||
<replicated-cache name="work">
|
||||
<expiration lifespan="-1"/>
|
||||
</replicated-cache>
|
||||
<local-cache name="keys" simple-cache="true">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<expiration max-idle="3600000"/>
|
||||
<memory max-count="1000"/>
|
||||
</local-cache>
|
||||
<local-cache name="crl" simple-cache="true">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<expiration lifespan="-1"/>
|
||||
<memory max-count="1000"/>
|
||||
</local-cache>
|
||||
<distributed-cache name="actionTokens" owners="2">
|
||||
<encoding>
|
||||
<key media-type="application/x-java-object"/>
|
||||
<value media-type="application/x-java-object"/>
|
||||
</encoding>
|
||||
<expiration max-idle="-1" lifespan="-1" interval="300000"/>
|
||||
<memory max-count="-1"/>
|
||||
</distributed-cache>
|
||||
</cache-container>
|
||||
</infinispan>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{{ ansible_managed | comment }}
|
||||
{% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %}
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME={{ keycloak_quarkus_bootstrap_admin_user }}
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}'
|
||||
{% else %}
|
||||
{{ keycloak.bootstrap_mnemonic }}
|
||||
{% endif %}
|
||||
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 }}"
|
||||
|
||||
# Custom ENV variables
|
||||
{% for env in keycloak_quarkus_additional_env_vars %}
|
||||
{{ env.key }}={{ env.value }}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{{ ansible_managed | comment }}
|
||||
|
||||
{% if keycloak_quarkus_db_enabled %}
|
||||
# Database
|
||||
db={{ keycloak_quarkus_db_engine }}
|
||||
db-url={{ keycloak_quarkus_db_url }}
|
||||
db-username={{ keycloak_quarkus_db_user }}
|
||||
{% if not keycloak.config_key_store_enabled %}
|
||||
db-password={{ keycloak_quarkus_db_pass }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if keycloak.config_key_store_enabled %}
|
||||
# Config store
|
||||
config-keystore={{ keycloak_quarkus_config_key_store_file }}
|
||||
config-keystore-password={{ keycloak_quarkus_config_key_store_password }}
|
||||
{% endif %}
|
||||
|
||||
# Observability
|
||||
metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }}
|
||||
health-enabled={{ keycloak_quarkus_health_enabled | lower }}
|
||||
|
||||
# HTTP
|
||||
http-enabled={{ keycloak_quarkus_http_enabled | lower }}
|
||||
{% if keycloak_quarkus_http_enabled %}
|
||||
http-port={{ keycloak_quarkus_http_port }}
|
||||
{% endif %}
|
||||
http-relative-path={{ keycloak_quarkus_http_relative_path }}
|
||||
http-host={{ keycloak_quarkus_http_host }}
|
||||
|
||||
# Management
|
||||
http-management-port={{ keycloak_quarkus_http_management_port }}
|
||||
{% if keycloak_quarkus_http_management_relative_path is defined and keycloak_quarkus_http_management_relative_path | length > 0 %}
|
||||
http-management-relative-path={{ keycloak_quarkus_http_management_relative_path }}
|
||||
{% endif %}
|
||||
|
||||
# HTTPS
|
||||
https-port={{ keycloak_quarkus_https_port }}
|
||||
{% if keycloak_quarkus_https_key_file_enabled %}
|
||||
https-certificate-file={{ keycloak_quarkus_cert_file}}
|
||||
https-certificate-key-file={{ keycloak_quarkus_key_file }}
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_https_key_store_enabled %}
|
||||
https-key-store-file={{ keycloak_quarkus_https_key_store_file }}
|
||||
https-key-store-password={{ keycloak_quarkus_https_key_store_password }}
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_https_trust_store_enabled %}
|
||||
https-trust-store-file={{ keycloak_quarkus_https_trust_store_file }}
|
||||
https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }}
|
||||
{% endif %}
|
||||
|
||||
# Client URL configuration
|
||||
hostname={{ keycloak_quarkus_hostname }}
|
||||
hostname-admin={{ keycloak_quarkus_hostname_admin }}
|
||||
hostname-strict={{ keycloak_quarkus_hostname_strict | lower }}
|
||||
hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | lower }}
|
||||
|
||||
# Cluster
|
||||
{% if keycloak_quarkus_ha_enabled %}
|
||||
cache=ispn
|
||||
{% if keycloak_quarkus_cache_managed_infinispan_config %}
|
||||
cache-config-file=cache-ispn.xml
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_cache_remote %}
|
||||
cache-remote-username={{ keycloak_quarkus_cache_remote_username }}
|
||||
cache-remote-password={{ keycloak_quarkus_cache_remote_password }}
|
||||
cache-remote-host={{ keycloak_quarkus_cache_remote_host }}
|
||||
cache-remote-port={{ keycloak_quarkus_cache_remote_port }}
|
||||
cache-remote-tls-enabled={{ keycloak_quarkus_cache_remote_tls_enabled | lower }}
|
||||
{% endif %}
|
||||
{{ keycloak_quarkus_cache_embedded_properties }}
|
||||
{% endif %}
|
||||
|
||||
{% if keycloak_quarkus_proxy_headers | length > 0 %}
|
||||
proxy-headers={{ keycloak_quarkus_proxy_headers | lower }}
|
||||
{% elif keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %}
|
||||
# Deprecated Proxy configuration
|
||||
proxy={{ keycloak_quarkus_proxy_mode }}
|
||||
{% endif %}
|
||||
|
||||
spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }}
|
||||
|
||||
# Transaction
|
||||
transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }}
|
||||
|
||||
# Logging
|
||||
#log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n
|
||||
log={{ keycloak_quarkus_log }}
|
||||
log-level={{ keycloak.log.level }}
|
||||
log-file={{ keycloak.log.file }}
|
||||
log-file-format={{ keycloak.log.format }}
|
||||
|
||||
# Vault
|
||||
{% if keycloak_quarkus_ks_vault_enabled %}
|
||||
vault=keystore
|
||||
vault-file={{ keycloak_quarkus_ks_vault_file }}
|
||||
vault-type={{ keycloak_quarkus_ks_vault_type }}
|
||||
vault-pass={{ keycloak_quarkus_ks_vault_pass }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
# Providers
|
||||
{% for provider in keycloak_quarkus_providers %}
|
||||
{% if provider.default is defined and provider.default %}
|
||||
spi-{{ provider.spi }}-provider={{ provider.id }}
|
||||
{% endif %}
|
||||
{% if provider.properties is defined %}{% for property in provider.properties %}
|
||||
spi-{{ provider.spi }}-{{ provider.id }}-{{ property.key }}={{ property.value }}
|
||||
{% endfor %}{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[general]
|
||||
bootstrapped={{ bootstrapped | lower }}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
{{ ansible_managed | comment }}
|
||||
[Unit]
|
||||
Description=Keycloak Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }}
|
||||
{% if keycloak_quarkus_start_dev %}
|
||||
ExecStart={{ keycloak.home }}/bin/kc.sh start-dev
|
||||
{% else %}
|
||||
ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized
|
||||
{% endif %}
|
||||
User={{ keycloak.service_user }}
|
||||
Group={{ keycloak.service_group }}
|
||||
SuccessExitStatus=0 143
|
||||
{% if keycloak_quarkus_service_restart_always %}
|
||||
Restart=always
|
||||
{% elif keycloak_quarkus_service_restart_on_failure %}
|
||||
Restart=on-failure
|
||||
{% endif %}
|
||||
RestartSec={{ keycloak_quarkus_service_restartsec }}
|
||||
{% if keycloak_quarkus_http_port | int < 1024 or keycloak_quarkus_https_port | int < 1024 %}
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_systemd_wait_for_port %}
|
||||
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_systemd_wait_for_port_number }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_systemd_wait_for_port_number }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_systemd_wait_for_log %}
|
||||
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'cat {{ keycloak.log.file }} | sed "/Profile.*activated/ q" && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
|
||||
{% endif %}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{{ ansible_managed | comment }}
|
||||
{% if keycloak_quarkus_ha_enabled %}
|
||||
{% if keycloak_quarkus_version.split('.')[0] | int < 22 %}
|
||||
quarkus.infinispan-client.server-list={{ keycloak_quarkus_cache_remote_host }}:{{ keycloak_quarkus_cache_remote_port }}
|
||||
quarkus.infinispan-client.auth-username={{ keycloak_quarkus_cache_remote_username }}
|
||||
quarkus.infinispan-client.auth-password={{ keycloak_quarkus_cache_remote_password }}
|
||||
{% else %}
|
||||
quarkus.infinispan-client.hosts={{ keycloak_quarkus_cache_remote_host }}:{{ keycloak_quarkus_cache_remote_port }}
|
||||
quarkus.infinispan-client.username={{ keycloak_quarkus_cache_remote_username }}
|
||||
quarkus.infinispan-client.password={{ keycloak_quarkus_cache_remote_password }}
|
||||
{% endif %}
|
||||
quarkus.infinispan-client.client-intelligence=HASH_DISTRIBUTION_AWARE
|
||||
quarkus.infinispan-client.use-auth=true
|
||||
quarkus.infinispan-client.auth-realm=default
|
||||
quarkus.infinispan-client.auth-server-name=infinispan
|
||||
quarkus.infinispan-client.sasl-mechanism={{ keycloak_quarkus_cache_remote_sasl_mechanism }}
|
||||
{% if keycloak_quarkus_cache_remote_tls_enabled %}
|
||||
quarkus.infinispan-client.trust-store={{ keycloak_quarkus_https_trust_store_file }}
|
||||
quarkus.infinispan-client.trust-store-password={{ keycloak_quarkus_https_trust_store_password }}
|
||||
quarkus.infinispan-client.trust-store-type=jks
|
||||
{% endif %}
|
||||
#quarkus.infinispan-client.use-schema-registration=true
|
||||
{% endif %}
|
||||
quarkus.log.file.rotation.max-file-size={{ keycloak_quarkus_log_max_file_size }}
|
||||
quarkus.log.file.rotation.max-backup-index={{ keycloak_quarkus_log_max_backup_index }}
|
||||
quarkus.log.file.rotation.file-suffix={{ keycloak_quarkus_log_file_suffix }}
|
||||
{% if keycloak_quarkus_db_enabled %}
|
||||
quarkus.transaction-manager.enable-recovery=true
|
||||
{% endif %}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{{ ansible_managed | comment }}
|
||||
{% if not ansible_local.keycloak.general.bootstrapped | default(false) | bool %}
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME={{ keycloak_quarkus_bootstrap_admin_user }}
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD='{{ keycloak_quarkus_bootstrap_admin_password }}'
|
||||
{% else %}
|
||||
{{ keycloak.bootstrap_mnemonic }}
|
||||
{% endif %}
|
||||
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 }}"
|
||||
|
||||
# Custom ENV variables
|
||||
{% for env in keycloak_quarkus_additional_env_vars %}
|
||||
{{ env.key }}={{ env.value }}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
{{ ansible_managed | comment }}
|
||||
|
||||
{% if keycloak_quarkus_db_enabled %}
|
||||
# Database
|
||||
db={{ keycloak_quarkus_db_engine }}
|
||||
db-url={{ keycloak_quarkus_db_url }}
|
||||
db-username={{ keycloak_quarkus_db_user }}
|
||||
{% if not keycloak.config_key_store_enabled %}
|
||||
db-password={{ keycloak_quarkus_db_pass }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if keycloak.config_key_store_enabled %}
|
||||
# Config store
|
||||
config-keystore={{ keycloak_quarkus_config_key_store_file }}
|
||||
config-keystore-password={{ keycloak_quarkus_config_key_store_password }}
|
||||
{% endif %}
|
||||
|
||||
# Observability
|
||||
metrics-enabled={{ keycloak_quarkus_metrics_enabled | lower }}
|
||||
health-enabled={{ keycloak_quarkus_health_enabled | lower }}
|
||||
|
||||
# HTTP
|
||||
http-enabled={{ keycloak_quarkus_http_enabled | lower }}
|
||||
{% if keycloak_quarkus_http_enabled %}
|
||||
http-port={{ keycloak_quarkus_http_port }}
|
||||
{% endif %}
|
||||
http-relative-path={{ keycloak_quarkus_http_relative_path }}
|
||||
http-host={{ keycloak_quarkus_http_host }}
|
||||
|
||||
# Management
|
||||
http-management-port={{ keycloak_quarkus_http_management_port }}
|
||||
{% if keycloak_quarkus_http_management_relative_path is defined and keycloak_quarkus_http_management_relative_path | length > 0 %}
|
||||
http-management-relative-path={{ keycloak_quarkus_http_management_relative_path }}
|
||||
{% endif %}
|
||||
|
||||
# HTTPS
|
||||
https-port={{ keycloak_quarkus_https_port }}
|
||||
{% if keycloak_quarkus_https_key_file_enabled %}
|
||||
https-certificate-file={{ keycloak_quarkus_cert_file}}
|
||||
https-certificate-key-file={{ keycloak_quarkus_key_file }}
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_https_key_store_enabled %}
|
||||
https-key-store-file={{ keycloak_quarkus_https_key_store_file }}
|
||||
https-key-store-password={{ keycloak_quarkus_https_key_store_password }}
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_https_trust_store_enabled %}
|
||||
https-trust-store-file={{ keycloak_quarkus_https_trust_store_file }}
|
||||
https-trust-store-password={{ keycloak_quarkus_https_trust_store_password }}
|
||||
{% endif %}
|
||||
|
||||
# Client URL configuration
|
||||
hostname={{ keycloak_quarkus_hostname }}
|
||||
hostname-admin={{ keycloak_quarkus_hostname_admin }}
|
||||
hostname-strict={{ keycloak_quarkus_hostname_strict | lower }}
|
||||
hostname-backchannel-dynamic={{ keycloak_quarkus_hostname_backchannel_dynamic | lower }}
|
||||
|
||||
# Cluster
|
||||
{% if keycloak_quarkus_ha_enabled %}
|
||||
cache=ispn
|
||||
{% if keycloak_quarkus_cache_managed_infinispan_config %}
|
||||
cache-config-file=cache-ispn.xml
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_cache_remote %}
|
||||
cache-remote-username={{ keycloak_quarkus_cache_remote_username }}
|
||||
cache-remote-password={{ keycloak_quarkus_cache_remote_password }}
|
||||
cache-remote-host={{ keycloak_quarkus_cache_remote_host }}
|
||||
cache-remote-port={{ keycloak_quarkus_cache_remote_port }}
|
||||
cache-remote-tls-enabled={{ keycloak_quarkus_cache_remote_tls_enabled | lower }}
|
||||
{% endif %}
|
||||
{{ keycloak_quarkus_cache_embedded_properties }}
|
||||
{% endif %}
|
||||
|
||||
{% if keycloak_quarkus_proxy_headers | length > 0 %}
|
||||
proxy-headers={{ keycloak_quarkus_proxy_headers | lower }}
|
||||
{% elif keycloak_quarkus_proxy_mode is defined and keycloak_quarkus_proxy_mode != "none" %}
|
||||
# Deprecated Proxy configuration
|
||||
proxy={{ keycloak_quarkus_proxy_mode }}
|
||||
{% endif %}
|
||||
|
||||
spi-sticky-session-encoder-infinispan-should-attach-route={{ keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route | d(true) | lower }}
|
||||
|
||||
# Transaction
|
||||
transaction-xa-enabled={{ keycloak_quarkus_transaction_xa_enabled | lower }}
|
||||
|
||||
# Logging
|
||||
#log-format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n
|
||||
log={{ keycloak_quarkus_log }}
|
||||
log-level={{ keycloak.log.level }}
|
||||
log-file={{ keycloak.log.file }}
|
||||
log-file-format={{ keycloak.log.format }}
|
||||
|
||||
# Vault
|
||||
{% if keycloak_quarkus_ks_vault_enabled %}
|
||||
vault=keystore
|
||||
vault-file={{ keycloak_quarkus_ks_vault_file }}
|
||||
vault-type={{ keycloak_quarkus_ks_vault_type }}
|
||||
vault-pass={{ keycloak_quarkus_ks_vault_pass }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
# Providers
|
||||
{% for provider in keycloak_quarkus_providers %}
|
||||
{% if provider.default is defined and provider.default %}
|
||||
spi-{{ provider.spi }}-provider={{ provider.id }}
|
||||
{% endif %}
|
||||
{% if provider.properties is defined %}{% for property in provider.properties %}
|
||||
spi-{{ provider.spi }}-{{ provider.id }}-{{ property.key }}={{ property.value }}
|
||||
{% endfor %}{% endif %}
|
||||
{% endfor %}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[general]
|
||||
bootstrapped={{ bootstrapped | lower }}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
{{ ansible_managed | comment }}
|
||||
[Unit]
|
||||
Description=Keycloak Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=-{{ keycloak_quarkus_sysconf_file }}
|
||||
{% if keycloak_quarkus_start_dev %}
|
||||
ExecStart={{ keycloak.home }}/bin/kc.sh start-dev
|
||||
{% else %}
|
||||
ExecStart={{ keycloak.home }}/bin/kc.sh start --optimized
|
||||
{% endif %}
|
||||
User={{ keycloak.service_user }}
|
||||
Group={{ keycloak.service_group }}
|
||||
SuccessExitStatus=0 143
|
||||
{% if keycloak_quarkus_service_restart_always %}
|
||||
Restart=always
|
||||
{% elif keycloak_quarkus_service_restart_on_failure %}
|
||||
Restart=on-failure
|
||||
{% endif %}
|
||||
RestartSec={{ keycloak_quarkus_service_restartsec }}
|
||||
{% if keycloak_quarkus_http_port | int < 1024 or keycloak_quarkus_https_port | int < 1024 %}
|
||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_systemd_wait_for_port %}
|
||||
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'while ! ss -H -t -l -n sport = :{{ keycloak_quarkus_systemd_wait_for_port_number }} | grep -q "^LISTEN.*:{{ keycloak_quarkus_systemd_wait_for_port_number }}"; do sleep 1; done && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
|
||||
{% endif %}
|
||||
{% if keycloak_quarkus_systemd_wait_for_log %}
|
||||
ExecStartPost=/usr/bin/timeout {{ keycloak_quarkus_systemd_wait_for_timeout }} sh -c 'cat {{ keycloak.log.file }} | sed "/Profile.*activated/ q" && /bin/sleep {{ keycloak_quarkus_systemd_wait_for_delay }}'
|
||||
{% endif %}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('openjdk-21-jdk-headless') }}"
|
||||
keycloak_quarkus_prereq_package_list:
|
||||
- "{{ keycloak_quarkus_varjvm_package }}"
|
||||
- bash
|
||||
- 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' }}"
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
keycloak: # noqa var-naming this is an internal dict of interpolated values
|
||||
home: "{{ keycloak_quarkus_home }}"
|
||||
config_dir: "{{ keycloak_quarkus_config_dir }}"
|
||||
bundle: "{{ keycloak_quarkus_archive }}"
|
||||
service_name: "keycloak"
|
||||
health_url: "{{ keycloak_quarkus_health_check_url }}"
|
||||
cli_path: "{{ keycloak_quarkus_home }}/bin/kcadm.sh"
|
||||
service_user: "{{ keycloak_quarkus_service_user }}"
|
||||
service_group: "{{ keycloak_quarkus_service_group }}"
|
||||
offline_install: "{{ keycloak_quarkus_offline_install }}"
|
||||
config_key_store_enabled: "{{ keycloak_quarkus_config_key_store_password != '' }}"
|
||||
log:
|
||||
file: "{{ keycloak_quarkus_home }}/{{ keycloak_quarkus_log_file }}"
|
||||
level: "{{ keycloak_quarkus_log_level }}"
|
||||
format: "{{ keycloak_quarkus_log_format }}"
|
||||
bootstrap_mnemonic: "# ansible-middleware/keycloak: bootstrapped"
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
keycloak_quarkus_varjvm_package: "{{ keycloak_quarkus_jvm_package | default('java-21-openjdk-headless') }}"
|
||||
keycloak_quarkus_prereq_package_list:
|
||||
- "{{ keycloak_quarkus_varjvm_package }}"
|
||||
- bash
|
||||
- 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.]+') }}"
|
||||
Loading…
Reference in a new issue