04_users.ymlΒΆ

---
# ##############################################################################
#
# Purpose:
# - Ensure base LDAP tree exists (suffix + OUs)
# - Ensure LDAP user entries exist (without setting userPassword here)
# - Set user passwords:
#   * default: on every deploy
#   * optional per-user override: set once on create via password_update: false
# - Keep objectClass list and mail attribute up to date
# ##############################################################################

# ##############################################################################
# 0) Ensure base tree exists (suffix + OUs)
# ##############################################################################
- name: βœ… Ensure LDAP root (suffix) entry exists
  community.general.ldap_entry:
    dn: "{{ LDAP.DN.ROOT }}"
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    objectClass:
      - top
      - dcObject
      - organization
    attributes:
      dc: "{{ (LDAP.DN.ROOT | regex_search('dc=([^,]+)', '\\1')) | first | default('infinito') }}"
      o: "{{ (LDAP.DN.ROOT | regex_search('dc=([^,]+)', '\\1')) | first | default('infinito') }}"
    state: present

- name: βœ… Ensure people OU exists
  community.general.ldap_entry:
    dn: "{{ LDAP.DN.OU.USERS }}"
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    objectClass:
      - top
      - organizationalUnit
    attributes:
      ou: users
      description: "Users container"
    state: present

- name: βœ… Ensure groups OU exists
  community.general.ldap_entry:
    dn: "{{ LDAP.DN.OU.GROUPS }}"
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    objectClass:
      - top
      - organizationalUnit
    attributes:
      ou: groups
      description: "Groups container"
    state: present

- name: βœ… Ensure roles OU exists
  community.general.ldap_entry:
    dn: "{{ LDAP.DN.OU.ROLES }}"
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    objectClass:
      - top
      - organizationalUnit
    attributes:
      ou: roles
      description: "Container for application access profiles"
    state: present

- name: βœ… Ensure LDAP users exist
  ldap_entries:
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    state: create
    entries: >-
      {{ OPENLDAP_USERS | openldap_user_entries(LDAP.USER.ATTRIBUTES.ID,
                                                LDAP.DN.OU.USERS,
                                                LDAP.USER.OBJECTS.STRUCTURAL) }}
  register: openldap_users_created
  changed_when: false
  throttle: 1
  no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

- name: πŸ”§ Set LDAP user passwords (per-user update policy)
  ldap_passwords:
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    entries: >-
      {{ OPENLDAP_USERS | openldap_user_passwords(LDAP.USER.ATTRIBUTES.ID,
                                                  LDAP.DN.OU.USERS,
                                                  openldap_users_created.changed_dns) }}
  no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"

- name: βœ… Ensure required objectClass values and mail address are present
  ldap_entries:
    server_uri: "{{ OPENLDAP_SERVER_URI }}"
    bind_dn: "{{ OPENLDAP_BIND_DN }}"
    bind_pw: "{{ OPENLDAP_BIND_PW }}"
    state: "{{ 'exact' if MODE_CLEANUP | bool else 'present' }}"
    entries: >-
      {{ OPENLDAP_USERS | openldap_user_mail_entries(LDAP.USER.ATTRIBUTES.ID,
                                                     LDAP.DN.OU.USERS,
                                                     LDAP.USER.OBJECTS.STRUCTURAL) }}
  changed_when: false
  throttle: 1
  no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"