AWX LDAP configuration in a declarative way

,

Hi,
In order to fully configure my AWX instance in a declarative way, I set up an Ansible playbook I launch from my Debian server to my AWX instance (K8s hosting).

Everything works great, i’m able to configure teams webhook, custom EE image, organization etc… but I face some issues when talking about some LDAP settings.

First of all, I tested my LDAP configuration manually through AWX GUI and everything works great, so my queries in this post will be about the way of configure it through a playbook rather than LDAP syntax.

According to this documentation I set up a bunch of task to configure each and every LDAP settings I need (AUTH_LDAP_SERVER_URI, AUTH_LDAP_BIND_PASSWORD, AUTH_LDAP_GROUP_TYPE and so on…)
Also, as settings name are based on django-auth-ldap, I took the settings names I need right here.

For instance, a single task with 1x set of name,value is working great:

  - name: Configuration AUTH_LDAP_SERVER_URI
    settings:
      name: "AUTH_LDAP_SERVER_URI"
      value: "ldap://my-ldap:389"
      tower_config_file: "./tower_config_file.cfg"

But it comes tricky when I have to set different values, so let’s focus on the first task failling :

  tasks:
  - name: Configuration AUTH_LDAP_USER_SEARCH
    settings:
      name: AUTH_LDAP_USER_SEARCH
      value: 'LDAPSearch("OU=MyGroup,DC=MyDC,DC=net",ldap.SCOPE_SUBTREE,"(sAMAccountName=%(user)s)",)'
      tower_config_file: "./tower_config_file.cfg"

Here’s the error message about "Expected a list of items but got type \"str\"."

    "changed": false,
    "invocation": {
        "module_args": {
            "controller_config_file": "./tower_config_file.cfg",
            "controller_host": null,
            "controller_oauthtoken": null,
            "controller_password": null,
            "controller_username": null,
            "name": "AUTH_LDAP_USER_SEARCH",
            "request_timeout": null,
            "settings": null,
            "tower_config_file": "./tower_config_file.cfg",
            "validate_certs": null,
            "value": "LDAPSearch(\"OU=MyGroup,DC=MyDC,DC=net\",ldap.SCOPE_SUBTREE,\"(sAMAccountName=%(user)s)\",)"
        }
    },
    "msg": "Unable to update settings, see response",
    "response": {
        "json": {
            "AUTH_LDAP_USER_SEARCH": [
                "Expected a list of items but got type \"str\"."
            ]
        },
        "status_code": 400
    }
}

I tried to convert my task as a list of items :

  tasks:
  - name: Configuration AUTH_LDAP_USER_SEARCH
    settings:
      name: AUTH_LDAP_USER_SEARCH
      value:
        - "OU=MyGroup"
        - "DC=MyDC"
        - "DC=net"
        - "SCOPE_SUBTREE"
        - "(sAMAccountName=%(user)s)"
      tower_config_file: "./tower_config_file.cfg"

But got a different error message :

fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "controller_config_file": "./tower_config_file.cfg",
            "controller_host": null,
            "controller_oauthtoken": null,
            "controller_password": null,
            "controller_username": null,
            "name": "AUTH_LDAP_USER_SEARCH",
            "request_timeout": null,
            "settings": null,
            "tower_config_file": "./tower_config_file.cfg",
            "validate_certs": null,
            "value": "['OU=MyGroup', 'DC=MyDC', 'DC=net', 'SCOPE_SUBTREE', '(sAMAccountName=%(user)s)']"
        }
    },
    "msg": "Unable to update settings, see response",
    "response": {
        "json": {
            "AUTH_LDAP_USER_SEARCH": [
                "In order to ultilize LDAP Union, input element No. 1 should be a search query array."
            ]
        },
        "status_code": 400
    }
}

I don’t have any other ideas at the moment, does someone still face that kind of issue ?

Thanks a lot

Gael

2 Likes

After reading this code at line 383 def to_internal_value(self, data):, I saw that the function is looking for [].

I set some tests and the working solution is :

  tasks:
  - name: Configuration AUTH_LDAP_USER_SEARCH
    settings:
      name: AUTH_LDAP_USER_SEARCH
      value:
        - ["ou=users,dc=example,dc=com","SCOPE_SUBTREE","(sAMAccountName=%(user)s)"]
      tower_config_file: "./tower_config_file.cfg"

Be careful: the collection is waiting for a list of 3 items (in my above example, separated by a , for instance: ("item1","item2","item3")

else you got this error :

        "json": {
            "AUTH_LDAP_USER_SEARCH": [
                "Error parsing LDAP Union element No. 1:",
                "Expected a list of three items but got 1 instead."
2 Likes

**For those who need a working LDAP configuration within an ansible-playbook, here’s mine (read before use it as you may have differents needs): **

- name: Configure AWX LDAP
  hosts: localhost
  connection: local

  collections:
    - awx.awx

  tasks:
####### Configuration LDAP #######
  - name: Configuration AUTH_LDAP_SERVER_URI
    settings:
      name: "AUTH_LDAP_SERVER_URI"
      value: "ldap://XXXXX:389"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_BIND_PASSWORD
    settings:
      name: "AUTH_LDAP_BIND_PASSWORD"
      value: "XXXXX"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_GROUP_TYPE
    settings:
      name: AUTH_LDAP_GROUP_TYPE
      value: "ActiveDirectoryGroupType"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_BIND_DN
    settings:
      name: AUTH_LDAP_BIND_DN
      value: "CN=XXXXX,OU=YYYY,DC=mYdc,DC=net"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_REQUIRE_GROUP
    settings:
      name: AUTH_LDAP_REQUIRE_GROUP
      value: "CN=XXXXX,OU=YYYY,DC=mYdc,DC=net"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_USER_SEARCH
    settings:
      name: AUTH_LDAP_USER_SEARCH
      value: 
        - ["CN=XXXXX,OU=YYYY,DC=mYdc,DC=net",SCOPE_SUBTREE,"(sAMAccountName=%(user)s)"]
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_GROUP_SEARCH
    settings:
      name: AUTH_LDAP_GROUP_SEARCH
      value:
        - "CN=XXXXX,OU=YYYY,DC=mYdc,DC=net"
        - "SCOPE_SUBTREE"
        - "(objectClass=group)"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_USER_ATTR_MAP
    settings:
      name: AUTH_LDAP_USER_ATTR_MAP
      value:
        email: "userPrincipalName"
        last_name: "sn"
        first_name: "givenName"
      tower_config_file: "./tower_config_file.cfg"

  - name: Configuration AUTH_LDAP_ORGANIZATION_MAP
    settings:
      name: AUTH_LDAP_ORGANIZATION_MAP
      value:
        Service-Infrastructure:
          users: "true"
          admins: "CN=XXXXX,OU=YYYY,DC=mYdc,DC=net"
          remove_users: "false"
          remove_admins: "false"
      tower_config_file: "./tower_config_file.cfg"

2 Likes

Thinking about it, would it not work if you did this instead?

tasks:
  - name: Configuration AUTH_LDAP_USER_SEARCH
    settings:
      name: AUTH_LDAP_USER_SEARCH
      value:
        - 'ou=users,dc=example,dc=com'
        - 'SCOPE_SUBTREE'
        - '(sAMAccountName=%(user)s)'
      tower_config_file: "./tower_config_file.cfg"

To me, that is a bit easier to read and maintain, unless I’m misreading your answer.

Hi, indeed it’s working and easier to maintain.
Actually at the top of my post I did a test like that but I missed to split the OU,DC,DC and I had an error message.
Thanks for your solution too :slight_smile:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.