mirror of
https://github.com/ansible-middleware/keycloak.git
synced 2025-07-26 14:41:31 -07:00
Add restart strategies, and allow custom task include
Co-authored-by: Helmut Wolf <hwo@world-direct.at> Co-authored-by: Guido Grazioli <ggraziol@redhat.com>
This commit is contained in:
parent
1e9a669dea
commit
2d573c2b62
9 changed files with 104 additions and 45 deletions
|
@ -153,3 +153,8 @@ keycloak_quarkus_ks_vault_pass:
|
||||||
keycloak_quarkus_providers: []
|
keycloak_quarkus_providers: []
|
||||||
keycloak_quarkus_policies: []
|
keycloak_quarkus_policies: []
|
||||||
keycloak_quarkus_supported_policy_types: ['password-blacklists']
|
keycloak_quarkus_supported_policy_types: ['password-blacklists']
|
||||||
|
|
||||||
|
# files in restart directory (one of [ 'serial', 'none', 'verify_first' ]), or path to file when providing custom strategy
|
||||||
|
keycloak_quarkus_restart_strategy: restart/serial.yml
|
||||||
|
keycloak_quarkus_restart_health_check: "{{ keycloak_quarkus_ha_enabled }}"
|
||||||
|
keycloak_quarkus_restart_pause: 15
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
ansible.builtin.include_tasks: bootstrapped.yml
|
ansible.builtin.include_tasks: bootstrapped.yml
|
||||||
listen: bootstrapped
|
listen: bootstrapped
|
||||||
- name: "Restart {{ keycloak.service_name }}"
|
- name: "Restart {{ keycloak.service_name }}"
|
||||||
ansible.builtin.include_tasks: restart.yml
|
ansible.builtin.include_tasks:
|
||||||
|
file: "{{ keycloak_quarkus_restart_strategy if keycloak_quarkus_ha_enabled else 'restart.yml' }}"
|
||||||
listen: "restart keycloak"
|
listen: "restart keycloak"
|
||||||
- name: "Print deprecation warning"
|
- name: "Print deprecation warning"
|
||||||
ansible.builtin.fail:
|
ansible.builtin.fail:
|
||||||
|
|
|
@ -399,7 +399,13 @@ argument_specs:
|
||||||
default: 10
|
default: 10
|
||||||
type: 'int'
|
type: 'int'
|
||||||
keycloak_quarkus_providers:
|
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 }"
|
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: []
|
default: []
|
||||||
type: "list"
|
type: "list"
|
||||||
keycloak_quarkus_supported_policy_types:
|
keycloak_quarkus_supported_policy_types:
|
||||||
|
@ -425,6 +431,20 @@ argument_specs:
|
||||||
default: true
|
default: true
|
||||||
description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL"
|
description: "Allow the option to ignore invalid certificates when downloading JDBC drivers from a custom URL"
|
||||||
type: "bool"
|
type: "bool"
|
||||||
|
keycloak_quarkus_restart_health_check:
|
||||||
|
default: "{{ keycloak_quarkus_ha_enabled }}"
|
||||||
|
description: "Whether to wait on successful health check after restart"
|
||||||
|
type: "bool"
|
||||||
|
keycloak_quarkus_restart_strategy:
|
||||||
|
description: >
|
||||||
|
Strategy task file for restarting in HA, one of [ 'serial', 'none', 'verify_first' ] below, or path to
|
||||||
|
file when providing custom strategy
|
||||||
|
default: "restart/serial.yml"
|
||||||
|
type: "str"
|
||||||
|
keycloak_quarkus_restart_pause:
|
||||||
|
description: "Seconds to wait between restarts in HA strategy"
|
||||||
|
default: 15
|
||||||
|
type: int
|
||||||
downstream:
|
downstream:
|
||||||
options:
|
options:
|
||||||
rhbk_version:
|
rhbk_version:
|
||||||
|
|
|
@ -258,7 +258,7 @@
|
||||||
|
|
||||||
- name: "Upload local providers"
|
- name: "Upload local providers"
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
src: "{{ item.local_path}}"
|
src: "{{ item.local_path }}"
|
||||||
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
|
dest: "{{ keycloak.home }}/providers/{{ item.id }}.jar"
|
||||||
owner: "{{ keycloak.service_user }}"
|
owner: "{{ keycloak.service_user }}"
|
||||||
group: "{{ keycloak.service_group }}"
|
group: "{{ keycloak.service_group }}"
|
||||||
|
@ -280,7 +280,7 @@
|
||||||
- name: "Install custom policies"
|
- name: "Install custom policies"
|
||||||
ansible.builtin.get_url:
|
ansible.builtin.get_url:
|
||||||
url: "{{ item.url }}"
|
url: "{{ item.url }}"
|
||||||
dest: "{{ keycloak.home }}/data/{{ item.type|default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}"
|
dest: "{{ keycloak.home }}/data/{{ item.type | default(keycloak_quarkus_supported_policy_types | first) | lower }}/{{ item.name }}"
|
||||||
owner: "{{ keycloak.service_user }}"
|
owner: "{{ keycloak.service_user }}"
|
||||||
group: "{{ keycloak.service_group }}"
|
group: "{{ keycloak.service_group }}"
|
||||||
mode: '0640'
|
mode: '0640'
|
||||||
|
|
|
@ -59,11 +59,18 @@
|
||||||
|
|
||||||
- name: "Validate providers"
|
- name: "Validate providers"
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that: >
|
||||||
- item.id is defined and item.id | length > 0
|
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)
|
( (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
|
quiet: true
|
||||||
fail_msg: "Providers definition is incorrect; `id` and one of `spi`, `url`, `local_path`, or `maven` are mandatory. `key` and `value` are mandatory for each property"
|
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 }}"
|
loop: "{{ keycloak_quarkus_providers }}"
|
||||||
|
|
||||||
- name: "Validate policies"
|
- name: "Validate policies"
|
||||||
|
@ -73,7 +80,8 @@
|
||||||
- item.url is defined and item.url | 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
|
- item.type is not defined or item.type | lower in keycloak_quarkus_supported_policy_types
|
||||||
quiet: true
|
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 }}."
|
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 }}"
|
loop: "{{ keycloak_quarkus_policies }}"
|
||||||
|
|
||||||
- name: "Validate additional env variables"
|
- name: "Validate additional env variables"
|
||||||
|
|
|
@ -1,38 +1,17 @@
|
||||||
---
|
---
|
||||||
- name: Ensure only one service at a time gets rebooted, to ensure replication of distributed ispn caches
|
- name: "Restart and enable {{ keycloak.service_name }} service"
|
||||||
throttle: 1
|
|
||||||
block:
|
|
||||||
- name: "Restart and enable {{ keycloak.service_name }} service on first host"
|
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
name: "{{ keycloak.service_name }}"
|
name: "{{ keycloak.service_name }}"
|
||||||
enabled: true
|
enabled: true
|
||||||
state: restarted
|
state: restarted
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
become: true
|
become: true
|
||||||
delegate_to: "{{ ansible_play_hosts | first }}"
|
|
||||||
run_once: true
|
|
||||||
|
|
||||||
- name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}"
|
- name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}"
|
||||||
ansible.builtin.uri:
|
ansible.builtin.uri:
|
||||||
url: "{{ keycloak.health_url }}"
|
url: "{{ keycloak.health_url }}"
|
||||||
register: keycloak_status
|
register: keycloak_status
|
||||||
until: keycloak_status.status == 200
|
until: keycloak_status.status == 200
|
||||||
retries: 25
|
retries: 25
|
||||||
delay: 10
|
delay: 10
|
||||||
delegate_to: "{{ ansible_play_hosts | first }}"
|
when: keycloak_quarkus_restart_health_check
|
||||||
run_once: true
|
|
||||||
|
|
||||||
- name: Pause to give distributed ispn caches time to (re-)replicate back onto first host
|
|
||||||
ansible.builtin.pause:
|
|
||||||
seconds: 15
|
|
||||||
when:
|
|
||||||
- keycloak_quarkus_ha_enabled
|
|
||||||
|
|
||||||
- name: "Restart and enable {{ keycloak.service_name }} service on all other hosts"
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: "{{ keycloak.service_name }}"
|
|
||||||
enabled: true
|
|
||||||
state: restarted
|
|
||||||
daemon_reload: true
|
|
||||||
become: true
|
|
||||||
when: inventory_hostname != ansible_play_hosts | first
|
|
||||||
|
|
4
roles/keycloak_quarkus/tasks/restart/none.yml
Normal file
4
roles/keycloak_quarkus/tasks/restart/none.yml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
- name: "Display message"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "keycloak_quarkus_restart_strategy is none, skipping restart"
|
8
roles/keycloak_quarkus/tasks/restart/serial.yml
Normal file
8
roles/keycloak_quarkus/tasks/restart/serial.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
- name: "Restart services in serial, with optional healtch check (keycloak_quarkus_restart_health_check)"
|
||||||
|
throttle: 1
|
||||||
|
loop: "{{ ansible_play_hosts }}"
|
||||||
|
block:
|
||||||
|
- name: "Restart and enable {{ keycloak.service_name }} service on first host"
|
||||||
|
ansible.builtin.include_tasks: ../restart.yml
|
||||||
|
delegate_to: "{{ item }}"
|
34
roles/keycloak_quarkus/tasks/restart/verify_first.yml
Normal file
34
roles/keycloak_quarkus/tasks/restart/verify_first.yml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
- name: Verify first restarted service with health URL, then rest in parallel
|
||||||
|
block:
|
||||||
|
- name: "Restart and enable {{ keycloak.service_name }} service on first host"
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ keycloak.service_name }}"
|
||||||
|
enabled: true
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
become: true
|
||||||
|
delegate_to: "{{ ansible_play_hosts | first }}"
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: "Wait until {{ keycloak.service_name }} service becomes active {{ keycloak.health_url }}"
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ keycloak.health_url }}"
|
||||||
|
register: keycloak_status
|
||||||
|
until: keycloak_status.status == 200
|
||||||
|
retries: 25
|
||||||
|
delay: 10
|
||||||
|
delegate_to: "{{ ansible_play_hosts | first }}"
|
||||||
|
run_once: true
|
||||||
|
|
||||||
|
- name: Pause 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
|
||||||
|
|
||||||
|
- name: "Restart and enable {{ keycloak.service_name }} service on other hosts"
|
||||||
|
ansible.builtin.include_tasks: ../restart.yml
|
||||||
|
delegate_to: "{{ item }}"
|
||||||
|
loop: "{{ ansible_play_hosts }}"
|
||||||
|
when: inventory_hostname != ansible_play_hosts | first
|
Loading…
Add table
Add a link
Reference in a new issue