feat: add keycloak provisioning tasks
This commit is contained in:
parent
13eb79803f
commit
3fcaebe1a8
4 changed files with 242 additions and 0 deletions
|
|
@ -33,3 +33,66 @@ keycloak_use_ssl: true
|
||||||
keycloak_log_level: "INFO"
|
keycloak_log_level: "INFO"
|
||||||
keycloak_proxy_mode: "edge"
|
keycloak_proxy_mode: "edge"
|
||||||
keycloak_gzip_enabled: false # Disable GZIP encoding to avoid MIME type issues
|
keycloak_gzip_enabled: false # Disable GZIP encoding to avoid MIME type issues
|
||||||
|
|
||||||
|
# Provisioning configuration
|
||||||
|
keycloak_provisioning_enabled: false
|
||||||
|
|
||||||
|
# Realm configuration
|
||||||
|
keycloak_realm: "default"
|
||||||
|
keycloak_realm_display_name: "Default Realm"
|
||||||
|
|
||||||
|
# Auth URL for API access (used by provisioning tasks)
|
||||||
|
keycloak_auth_url: "{{ 'https' if keycloak_use_ssl else 'http' }}://{{ keycloak_domain }}"
|
||||||
|
|
||||||
|
# Groups to provision
|
||||||
|
keycloak_groups: []
|
||||||
|
# - name: admins
|
||||||
|
# - name: users
|
||||||
|
|
||||||
|
# Local users to provision
|
||||||
|
keycloak_local_users: []
|
||||||
|
# - username: admin
|
||||||
|
# first_name: "Admin"
|
||||||
|
# last_name: "User"
|
||||||
|
# email: "admin@example.com"
|
||||||
|
# password: "changeme"
|
||||||
|
# groups:
|
||||||
|
# - name: admins
|
||||||
|
|
||||||
|
# OIDC clients to provision
|
||||||
|
keycloak_oidc_clients: []
|
||||||
|
# - client_id: nextcloud
|
||||||
|
# name: "Nextcloud"
|
||||||
|
# client_secret: "changeme"
|
||||||
|
# redirect_uris:
|
||||||
|
# - "https://nextcloud.example.com/apps/user_oidc/code"
|
||||||
|
# default_client_scopes:
|
||||||
|
# - openid
|
||||||
|
# - email
|
||||||
|
# - profile
|
||||||
|
|
||||||
|
# Identity providers (e.g., Entra ID, Google)
|
||||||
|
keycloak_identity_providers: []
|
||||||
|
# - alias: entra-id
|
||||||
|
# display_name: "Login with Microsoft"
|
||||||
|
# provider_id: oidc
|
||||||
|
# config:
|
||||||
|
# clientId: "{{ entra_client_id }}"
|
||||||
|
# clientSecret: "{{ entra_client_secret }}"
|
||||||
|
# authorizationUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
|
||||||
|
# tokenUrl: "https://login.microsoftonline.com/common/oauth2/v2.0/token"
|
||||||
|
# defaultScope: "openid profile email"
|
||||||
|
|
||||||
|
# Resources to remove from Keycloak (cleanup)
|
||||||
|
# Add names/aliases here when removing from the lists above
|
||||||
|
keycloak_removed_users: []
|
||||||
|
# - olduser
|
||||||
|
|
||||||
|
keycloak_removed_groups: []
|
||||||
|
# - oldgroup
|
||||||
|
|
||||||
|
keycloak_removed_clients: []
|
||||||
|
# - old-client
|
||||||
|
|
||||||
|
keycloak_removed_identity_providers: []
|
||||||
|
# - old-idp
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,25 @@
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ keycloak_docker_compose_dir }}"
|
project_src: "{{ keycloak_docker_compose_dir }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Wait for Keycloak health endpoint
|
||||||
|
uri:
|
||||||
|
url: "{{ keycloak_auth_url }}/health/ready"
|
||||||
|
method: GET
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: keycloak_health
|
||||||
|
until: keycloak_health.status == 200
|
||||||
|
retries: 30
|
||||||
|
delay: 10
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
when: keycloak_provisioning_enabled | bool
|
||||||
|
|
||||||
|
- name: Run Keycloak provisioning
|
||||||
|
ansible.builtin.include_tasks: provisioning.yml
|
||||||
|
args:
|
||||||
|
apply:
|
||||||
|
become: false
|
||||||
|
delegate_to: localhost
|
||||||
|
when: keycloak_provisioning_enabled | bool
|
||||||
|
|
|
||||||
156
roles/keycloak/tasks/provisioning.yml
Normal file
156
roles/keycloak/tasks/provisioning.yml
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
#SPDX-License-Identifier: MIT-0
|
||||||
|
---
|
||||||
|
# Keycloak provisioning tasks
|
||||||
|
# Create realm (if not master)
|
||||||
|
- name: Create Keycloak realm
|
||||||
|
community.general.keycloak_realm:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
display_name: "{{ keycloak_realm_display_name }}"
|
||||||
|
enabled: true
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
no_log: true
|
||||||
|
when: keycloak_realm != "master"
|
||||||
|
|
||||||
|
# Cleanup: Remove deleted identity providers
|
||||||
|
- name: Remove deleted identity providers
|
||||||
|
community.general.keycloak_identity_provider:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
alias: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_removed_identity_providers }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Cleanup: Remove deleted clients
|
||||||
|
- name: Remove deleted clients
|
||||||
|
community.general.keycloak_client:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
client_id: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_removed_clients }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Cleanup: Remove deleted users
|
||||||
|
- name: Remove deleted users
|
||||||
|
community.general.keycloak_user:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
username: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_removed_users }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Cleanup: Remove deleted groups
|
||||||
|
- name: Remove deleted groups
|
||||||
|
community.general.keycloak_group:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_removed_groups }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Create groups
|
||||||
|
- name: Create groups
|
||||||
|
community.general.keycloak_group:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_groups }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Create local users
|
||||||
|
- name: Create local users
|
||||||
|
community.general.keycloak_user:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
username: "{{ item.username }}"
|
||||||
|
first_name: "{{ item.first_name | default(omit) }}"
|
||||||
|
last_name: "{{ item.last_name | default(omit) }}"
|
||||||
|
email: "{{ item.email | default(omit) }}"
|
||||||
|
enabled: "{{ item.enabled | default(true) }}"
|
||||||
|
email_verified: "{{ item.email_verified | default(true) }}"
|
||||||
|
credentials:
|
||||||
|
- type: password
|
||||||
|
value: "{{ item.password }}"
|
||||||
|
temporary: false
|
||||||
|
groups: "{{ item.groups | default([]) }}"
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_local_users }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Create OIDC clients
|
||||||
|
- name: Create OIDC clients
|
||||||
|
community.general.keycloak_client:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
client_id: "{{ item.client_id }}"
|
||||||
|
name: "{{ item.name | default(item.client_id) }}"
|
||||||
|
enabled: true
|
||||||
|
client_authenticator_type: client-secret
|
||||||
|
secret: "{{ item.client_secret }}"
|
||||||
|
redirect_uris: "{{ item.redirect_uris | default([]) }}"
|
||||||
|
web_origins: "{{ item.web_origins | default(['+']) }}"
|
||||||
|
standard_flow_enabled: true
|
||||||
|
implicit_flow_enabled: false
|
||||||
|
direct_access_grants_enabled: "{{ item.direct_access_grants_enabled | default(false) }}"
|
||||||
|
protocol: openid-connect
|
||||||
|
default_client_scopes: "{{ item.default_client_scopes | default(['openid', 'email', 'profile']) }}"
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_oidc_clients }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
# Create identity providers
|
||||||
|
- name: Create identity providers
|
||||||
|
community.general.keycloak_identity_provider:
|
||||||
|
auth_keycloak_url: "{{ keycloak_auth_url }}"
|
||||||
|
auth_realm: master
|
||||||
|
auth_username: "{{ keycloak_admin_user }}"
|
||||||
|
auth_password: "{{ keycloak_admin_password }}"
|
||||||
|
realm: "{{ keycloak_realm }}"
|
||||||
|
alias: "{{ item.alias }}"
|
||||||
|
display_name: "{{ item.display_name | default(item.alias) }}"
|
||||||
|
provider_id: "{{ item.provider_id }}"
|
||||||
|
enabled: "{{ item.enabled | default(true) }}"
|
||||||
|
trust_email: "{{ item.trust_email | default(true) }}"
|
||||||
|
first_broker_login_flow_alias: "{{ item.first_broker_login_flow_alias | default('first broker login') }}"
|
||||||
|
config: "{{ item.config }}"
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_identity_providers }}"
|
||||||
|
no_log: true
|
||||||
|
|
@ -32,6 +32,7 @@ services:
|
||||||
KC_SPI_RESOURCE_ENCODING_GZIP_CACHE_DIR: /opt/keycloak/data/gzip-cache
|
KC_SPI_RESOURCE_ENCODING_GZIP_CACHE_DIR: /opt/keycloak/data/gzip-cache
|
||||||
KC_PROXY: {{ keycloak_proxy_mode }}
|
KC_PROXY: {{ keycloak_proxy_mode }}
|
||||||
KC_HOSTNAME: {{ keycloak_domain }}
|
KC_HOSTNAME: {{ keycloak_domain }}
|
||||||
|
KC_HEALTH_ENABLED: "true"
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue