---
- include_tasks: utils/once/flag.yml
- name: "π Create LDIF dirs {{ OPENLDAP_LDIF_PATH_HOST }} before swarm bind-mount"
directory_batch:
paths: "{{ [OPENLDAP_LDIF_PATH_HOST] | product(OPENLDAP_LDIF_TYPES) | map('join') | list }}"
mode: "0755"
- name: π¬ Initialize docker
include_tasks: 01_docker.yml
- name: π Render {{ lookup('domain',application_id) }}.conf if LDAP is public
stack_host_template:
src: "nginx.stream.conf.j2"
dest: "{{ lookup('nginx','directories.configuration.streams') }}{{ lookup('domain',application_id) }}.conf"
vars:
domain: "{{ lookup('domain', application_id) }}"
notify: restart-openresty
when: OPENLDAP_NETWORK_SWITCH_PUBLIC | bool
- name: π§Ή Remove {{ lookup('domain',application_id) }}.conf if LDAP not public
file:
path: "{{ lookup('nginx','directories.configuration.streams') }}{{ lookup('domain',application_id) }}.conf"
state: absent
when: not OPENLDAP_NETWORK_SWITCH_PUBLIC | bool
- name: "β³ Wait for LDAP to be available"
wait_for:
host: "{{ DOCKER_REACH_HOST }}"
port: "{{ lookup('config', application_id, 'services.openldap.ports.local.ldap') }}"
delay: 5
timeout: "{{ lookup('timeout', 120) | int }}"
state: started
when: IS_COMPOSE_MODE
- name: π Check if current RootDN/RootPW already work
ansible.builtin.shell: >
container exec -e OPENLDAP_BIND_PW {{ OPENLDAP_CONTAINER_ADDRESS }}
sh -c 'exec ldapwhoami -x -H ldap://127.0.0.1:389 -D "{{ OPENLDAP_BIND_DN }}" -w "$OPENLDAP_BIND_PW"'
environment:
OPENLDAP_BIND_PW: "{{ OPENLDAP_BIND_PW }}"
register: openldap_bind_check
delegate_to: "{{ STACK_HOST }}"
run_once: true
changed_when: false
failed_when: false
- name: β
Ensure LDAP RootPW is set on every deploy
include_tasks: 02_credentials.yml
when:
- OPENLDAP_NETWORK_SWITCH_LOCAL | bool
- OPENLDAP_PROVISION_CREDENTIALS | bool
- openldap_bind_check.rc != 0
- name: π§ Set OPENLDAP_MODULE_DN (from filesystem)
shell: >
container exec {{ OPENLDAP_CONTAINER_ADDRESS }}
sh -lc 'grep -m1 "^dn: " /etc/ldap/slapd.d/cn=config/cn=module{0}.ldif | sed "s/^dn: //"'
register: openldap_module_dn_raw
delegate_to: "{{ STACK_HOST }}"
run_once: true
changed_when: false
retries: 30
delay: 5
until:
- openldap_module_dn_raw.rc == 0
- (openldap_module_dn_raw.stdout | trim) != ""
- name: π Normalize OPENLDAP_MODULE_DN (ensure ,cn=config suffix)
set_fact:
OPENLDAP_MODULE_DN: >-
{{
(openldap_module_dn_raw.stdout | trim)
~ ('' if (openldap_module_dn_raw.stdout | trim) is search(',cn=config$') else ',cn=config')
}}
- name: π Query available LDAP databases
shell: >
container exec {{ OPENLDAP_CONTAINER_ADDRESS }}
ldapsearch -Q -Y EXTERNAL -H {{ OPENLDAP_CONFIG_URI }} -LLL -b cn=config "(olcDatabase=*)" dn
register: ldap_databases
delegate_to: "{{ STACK_HOST }}"
run_once: true
changed_when: false
- name: π§ Set OPENLDAP_DATA_BACKEND_DN (mdb preferred, hdb fallback)
set_fact:
OPENLDAP_DATA_BACKEND_DN: >-
{{
(
ldap_databases.stdout_lines
| select('search', '^dn: olcDatabase=.*mdb')
| map('regex_replace', '^dn: ', '')
| list
| first
)
| default(
(
ldap_databases.stdout_lines
| select('search', '^dn: olcDatabase=.*hdb')
| map('regex_replace', '^dn: ', '')
| list
| first
)
)
}}
- name: π Normalize OPENLDAP_DATA_BACKEND_DN (ensure ,cn=config suffix)
set_fact:
OPENLDAP_DATA_BACKEND_DN: >-
{{
OPENLDAP_DATA_BACKEND_DN
~ ('' if OPENLDAP_DATA_BACKEND_DN is search(',cn=config$') else ',cn=config')
}}
when: OPENLDAP_DATA_BACKEND_DN | default('') | length > 0
- name: "π Import LDIF Configuration"
include_tasks: _ldifs_creation.yml
loop:
- configuration
loop_control:
loop_var: folder
when: OPENLDAP_PROVISION_CONFIGURATION | bool
- name: πΏ flush LDIF handlers
meta: flush_handlers
- name: π₯ Load python-ldap build prerequisites
include_tasks: _python_ldap_prerequisites.yml
- name: π₯ Load python-ldap header fallback when Python.h is missing
include_tasks: _python_ldap_header_fallback.yml
when: not openldap_python_header.stat.exists
- name: π¦ Install python-ldap in active Ansible interpreter
include_role:
name: sys-pip-install
vars:
package_name: python-ldap
package_state: present
global_install: true
- name: β
Sanity check python-ldap import (verbose)
ansible.builtin.shell: |
set -euo pipefail
{{ ansible_python_interpreter }} - <<'EOF'
import traceback
try:
import ldap
print("python-ldap version:", ldap.__version__)
print("ldap module:", ldap.__file__)
except Exception:
traceback.print_exc()
raise
EOF
changed_when: false
when: MODE_DEBUG | bool
- name: "π Include Schemas (if enabled)"
include_tasks:
file: 03_schemas.yml
apply:
run_once: true
delegate_to: "{{ STACK_HOST }}"
when: OPENLDAP_PROVISION_SCHEMAS | bool
- name: "π Import LDAP Entries (if enabled)"
include_tasks:
file: 04_users.yml
apply:
run_once: true
delegate_to: "{{ STACK_HOST }}"
when: OPENLDAP_PROVISION_USERS | bool
- name: "π Import LDIF Data (if enabled)"
include_tasks: _ldifs_creation.yml
loop:
- groups
loop_control:
loop_var: folder
when: OPENLDAP_PROVISION_GROUPS | bool
- meta: flush_handlers
- name: "β Add Objects to all users"
include_tasks:
file: 05_update.yml
apply:
run_once: true
delegate_to: "{{ STACK_HOST }}"
when: OPENLDAP_PROVISION_UPDATE | bool