feat: add 389ds ldap backend to keycloak
Signed-off-by: Bert-Jan Fikse <bert-jan@whatwedo.ch>
This commit is contained in:
parent
59d0174905
commit
12864a13b0
8 changed files with 138 additions and 2 deletions
|
|
@ -19,8 +19,14 @@ ds389_root_password: "changeme"
|
||||||
|
|
||||||
# Instance configuration
|
# Instance configuration
|
||||||
ds389_instance_name: "localhost"
|
ds389_instance_name: "localhost"
|
||||||
|
ds389_hostname: "{{ ds389_service_name }}"
|
||||||
|
|
||||||
# Network configuration
|
# Network configuration
|
||||||
ds389_backend_network: "backend"
|
ds389_backend_network: "backend"
|
||||||
ds389_ldap_port: 3389
|
ds389_ldap_port: 3389
|
||||||
ds389_ldaps_port: 3636
|
ds389_ldaps_port: 3636
|
||||||
|
|
||||||
|
# Base OUs to create after container starts
|
||||||
|
ds389_base_ous:
|
||||||
|
- users
|
||||||
|
- groups
|
||||||
|
|
@ -29,4 +29,48 @@
|
||||||
- name: Start 389ds container
|
- name: Start 389ds container
|
||||||
community.docker.docker_compose_v2:
|
community.docker.docker_compose_v2:
|
||||||
project_src: "{{ ds389_docker_compose_dir }}"
|
project_src: "{{ ds389_docker_compose_dir }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Wait for LDAP to be ready
|
||||||
|
shell: >
|
||||||
|
docker compose -f {{ ds389_docker_compose_dir }}/docker-compose.yml
|
||||||
|
exec -T {{ ds389_service_name }} ldapsearch -H ldap://localhost:3389 -x
|
||||||
|
-D "{{ ds389_root_dn }}" -w "{{ ds389_root_password }}"
|
||||||
|
-b "" -s base "(objectClass=*)"
|
||||||
|
register: ds389_ldap_ready
|
||||||
|
retries: 30
|
||||||
|
delay: 2
|
||||||
|
until: ds389_ldap_ready.rc == 0
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Ensure backend and suffix exist
|
||||||
|
shell: >
|
||||||
|
docker compose -f {{ ds389_docker_compose_dir }}/docker-compose.yml
|
||||||
|
exec -T {{ ds389_service_name }} dsconf localhost backend create
|
||||||
|
--suffix "{{ ds389_suffix }}" --be-name userroot --create-suffix
|
||||||
|
register: ds389_backend_result
|
||||||
|
failed_when:
|
||||||
|
- ds389_backend_result.rc != 0
|
||||||
|
- "'already exists' not in ds389_backend_result.stderr"
|
||||||
|
- "'suffix exists' not in ds389_backend_result.stderr"
|
||||||
|
changed_when: ds389_backend_result.rc == 0
|
||||||
|
|
||||||
|
- name: Template base OUs LDIF
|
||||||
|
template:
|
||||||
|
src: base-ous.ldif.j2
|
||||||
|
dest: "{{ ds389_docker_volume_dir }}/data/base-ous.ldif"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Apply base OUs LDIF
|
||||||
|
shell: >
|
||||||
|
docker compose -f {{ ds389_docker_compose_dir }}/docker-compose.yml
|
||||||
|
exec -T {{ ds389_service_name }} ldapadd -H ldap://localhost:3389 -x
|
||||||
|
-D "{{ ds389_root_dn }}" -w "{{ ds389_root_password }}"
|
||||||
|
-f /data/base-ous.ldif
|
||||||
|
register: ds389_ldapadd_result
|
||||||
|
failed_when:
|
||||||
|
- ds389_ldapadd_result.rc != 0
|
||||||
|
- "'Already exists' not in ds389_ldapadd_result.stderr"
|
||||||
|
changed_when: "'Already exists' not in ds389_ldapadd_result.stderr"
|
||||||
|
no_log: true
|
||||||
7
roles/389ds/templates/base-ous.ldif.j2
Normal file
7
roles/389ds/templates/base-ous.ldif.j2
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{% for ou in ds389_base_ous %}
|
||||||
|
dn: ou={{ ou }},{{ ds389_suffix }}
|
||||||
|
changetype: add
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
ou: {{ ou }}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
services:
|
services:
|
||||||
{{ ds389_service_name }}:
|
{{ ds389_service_name }}:
|
||||||
image: {{ ds389_image }}
|
image: {{ ds389_image }}
|
||||||
|
hostname: {{ ds389_hostname }}
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
DS_SUFFIX_NAME: {{ ds389_suffix }}
|
DS_SUFFIX_NAME: {{ ds389_suffix }}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,14 @@ 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
|
||||||
|
|
||||||
|
# Extra CA certificates to trust (host paths to PEM files)
|
||||||
|
keycloak_truststore_certificates: []
|
||||||
|
# - /srv/data/389ds/data/ssca/ca.crt
|
||||||
|
|
||||||
|
# Extra /etc/hosts entries for the Keycloak container
|
||||||
|
keycloak_extra_hosts: []
|
||||||
|
# - "ldap:192.168.56.11"
|
||||||
|
|
||||||
# Provisioning configuration
|
# Provisioning configuration
|
||||||
keycloak_provisioning_enabled: false
|
keycloak_provisioning_enabled: false
|
||||||
|
|
||||||
|
|
@ -96,3 +104,26 @@ keycloak_removed_clients: []
|
||||||
|
|
||||||
keycloak_removed_identity_providers: []
|
keycloak_removed_identity_providers: []
|
||||||
# - old-idp
|
# - old-idp
|
||||||
|
|
||||||
|
# LDAP user federations
|
||||||
|
keycloak_user_federations: []
|
||||||
|
# - name: ldap-389ds
|
||||||
|
# provider_id: ldap
|
||||||
|
# config:
|
||||||
|
# editMode: WRITABLE
|
||||||
|
# syncRegistrations: "true"
|
||||||
|
# importEnabled: "true"
|
||||||
|
# vendor: rhds
|
||||||
|
# connectionUrl: "ldaps://ldap.example.com:636"
|
||||||
|
# usersDn: "ou=users,dc=example,dc=com"
|
||||||
|
# bindDn: "cn=Directory Manager"
|
||||||
|
# bindCredential: "changeme"
|
||||||
|
# usernameLDAPAttribute: uid
|
||||||
|
# rdnLDAPAttribute: uid
|
||||||
|
# uuidLDAPAttribute: nsuniqueid
|
||||||
|
# userObjectClasses: "inetOrgPerson, organizationalPerson"
|
||||||
|
# authType: simple
|
||||||
|
# useTruststoreSpi: never
|
||||||
|
|
||||||
|
keycloak_removed_user_federations: []
|
||||||
|
# - old-federation
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@
|
||||||
path: "{{ keycloak_docker_volume_dir }}/data"
|
path: "{{ keycloak_docker_volume_dir }}/data"
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
|
owner: "1000"
|
||||||
|
group: "1000"
|
||||||
|
|
||||||
- name: Create postgres data directory
|
- name: Create postgres data directory
|
||||||
file:
|
file:
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,20 @@
|
||||||
loop: "{{ keycloak_removed_identity_providers }}"
|
loop: "{{ keycloak_removed_identity_providers }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
# Cleanup: Remove deleted user federations
|
||||||
|
- name: Remove deleted user federations
|
||||||
|
community.general.keycloak_user_federation:
|
||||||
|
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_user_federations }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
# Cleanup: Remove deleted clients
|
# Cleanup: Remove deleted clients
|
||||||
- name: Remove deleted clients
|
- name: Remove deleted clients
|
||||||
community.general.keycloak_client:
|
community.general.keycloak_client:
|
||||||
|
|
@ -86,6 +100,25 @@
|
||||||
loop: "{{ keycloak_groups }}"
|
loop: "{{ keycloak_groups }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
# Create user federations (LDAP)
|
||||||
|
- name: Create user federations
|
||||||
|
community.general.keycloak_user_federation:
|
||||||
|
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 }}"
|
||||||
|
provider_id: "{{ item.provider_id }}"
|
||||||
|
provider_type: org.keycloak.storage.UserStorageProvider
|
||||||
|
config: "{{ item.config }}"
|
||||||
|
mappers: "{{ item.mappers | default(omit) }}"
|
||||||
|
bind_credential_update_mode: only_indirect
|
||||||
|
state: present
|
||||||
|
validate_certs: false
|
||||||
|
loop: "{{ keycloak_user_federations }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
# Create local users
|
# Create local users
|
||||||
- name: Create local users
|
- name: Create local users
|
||||||
community.general.keycloak_user:
|
community.general.keycloak_user:
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,25 @@ services:
|
||||||
KC_PROXY: {{ keycloak_proxy_mode }}
|
KC_PROXY: {{ keycloak_proxy_mode }}
|
||||||
KC_HOSTNAME: {{ keycloak_domain }}
|
KC_HOSTNAME: {{ keycloak_domain }}
|
||||||
KC_HEALTH_ENABLED: "true"
|
KC_HEALTH_ENABLED: "true"
|
||||||
|
{% if keycloak_truststore_certificates | length > 0 %}
|
||||||
|
KC_TRUSTSTORE_PATHS: "{{ keycloak_truststore_certificates | map('regex_replace', '^.*/(.*)$', '/opt/keycloak/certs/\\1') | join(',') }}"
|
||||||
|
{% endif %}
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
volumes:
|
volumes:
|
||||||
- {{ keycloak_docker_volume_dir }}/data:/opt/keycloak/data
|
- {{ keycloak_docker_volume_dir }}/data:/opt/keycloak/data
|
||||||
|
{% for cert in keycloak_truststore_certificates %}
|
||||||
|
- {{ cert }}:/opt/keycloak/certs/{{ cert | basename }}:ro
|
||||||
|
{% endfor %}
|
||||||
networks:
|
networks:
|
||||||
- {{ keycloak_backend_network }}
|
- {{ keycloak_backend_network }}
|
||||||
- {{ keycloak_traefik_network }}
|
- {{ keycloak_traefik_network }}
|
||||||
|
{% if keycloak_extra_hosts | length > 0 %}
|
||||||
|
extra_hosts:
|
||||||
|
{% for host in keycloak_extra_hosts %}
|
||||||
|
- "{{ host }}"
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
tmpfs:
|
tmpfs:
|
||||||
- /opt/keycloak/data/tmp:size=1024m
|
- /opt/keycloak/data/tmp:size=1024m
|
||||||
labels:
|
labels:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue