############################################################################### # 1) Create the LDAP entry if it does not yet exist ############################################################################### - name: Ensure LDAP users exist community.general.ldap_entry: dn: "{{ LDAP.USER.ATTRIBUTES.ID }}={{ item.key }},{{ LDAP.DN.OU.USERS }}" server_uri: "{{ openldap_server_uri }}" bind_dn: "{{ LDAP.DN.ADMINISTRATOR.DATA }}" bind_pw: "{{ LDAP.BIND_CREDENTIAL }}" objectClass: "{{ LDAP.USER.OBJECTS.STRUCTURAL }}" attributes: uid: "{{ item.value.username }}" sn: "{{ item.value.sn | default(item.key) }}" cn: "{{ item.value.cn | default(item.key) }}" userPassword: "{SSHA}{{ item.value.password }}" loginShell: /bin/bash homeDirectory: "/home/{{ item.key }}" uidNumber: "{{ item.value.uid | int }}" gidNumber: "{{ item.value.gid | int }}" state: present # ↳ creates but never updates async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" loop: "{{ users | dict2items }}" loop_control: label: "{{ item.key }}" ############################################################################### # 2) Keep the objectClass list AND the mail attribute up-to-date ############################################################################### - name: Ensure required objectClass values and mail address are present community.general.ldap_attrs: dn: "{{ LDAP.USER.ATTRIBUTES.ID }}={{ item.key }},{{ LDAP.DN.OU.USERS }}" server_uri: "{{ openldap_server_uri }}" bind_dn: "{{ LDAP.DN.ADMINISTRATOR.DATA }}" bind_pw: "{{ LDAP.BIND_CREDENTIAL }}" attributes: objectClass: "{{ LDAP.USER.OBJECTS.STRUCTURAL }}" mail: "{{ item.value.email }}" state: exact async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" loop: "{{ users | dict2items }}" loop_control: label: "{{ item.key }}" - name: "Ensure container for application roles exists" community.general.ldap_entry: dn: "{{ LDAP.DN.OU.ROLES }}" server_uri: "{{ openldap_server_uri }}" bind_dn: "{{ LDAP.DN.ADMINISTRATOR.DATA }}" bind_pw: "{{ LDAP.BIND_CREDENTIAL }}" objectClass: organizationalUnit attributes: ou: roles description: Container for application access profiles state: present