# Dynamic Inventory using Active Directory / LDAP

**URL:** <https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714>\
**Category:** Ansible Project\
**Tags:** windows\
**Created:** [February 13, 2018, 1:50am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714 "2018-02-13T01:50:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![aaron](https://avatars.discourse-cdn.com/v4/letter/a/e19adc/32.png) [@aaron](https://forum.ansible.com/u/aaron)\
**Post date:** [February 13, 2018, 1:50am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/1 "2018-02-13T01:50:31Z")

</div>

Does anyone have code that can pull a dynamic inventory from list of AD OUs? Want to use the windows\_update module to patch our servers only in specific OUs.

Maybe I missed it, but I don’t see Windows Active Directory inventory here: [https://github.com/ansible/ansible/tree/devel/contrib/inventory](https://github.com/ansible/ansible/tree/devel/contrib/inventory)

---

<div class="post-metadata">

**Author:** ![Michael\_Stroder](https://avatars.discourse-cdn.com/v4/letter/m/7ea924/32.png) [@Michael\_Stroder](https://forum.ansible.com/u/Michael_Stroder)\
**Post date:** [February 13, 2018, 9:26am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/2 "2018-02-13T09:26:23Z")

</div>

aaron@klep.net wrote:

> Does anyone have code that can pull a dynamic inventory from list of AD  
> OUs? Want to use the windows\_update module to patch our servers only in  
> specific OUs.
> 
> Maybe I missed it, but I don't see Windows Active Directory inventory  
> here: [https://github.com/ansible/ansible/tree/devel/contrib/inventory](https://github.com/ansible/ansible/tree/devel/contrib/inventory)

I've never used it myself but you could try to tweak this one to match  
your specific needs:

[https://github.com/vincentvdk/ansible\_inventory/tree/master/ldap](https://github.com/vincentvdk/ansible_inventory/tree/master/ldap)

Ciao, Michael.

---

<div class="post-metadata">

**Author:** ![balz.aschwanden](https://avatars.discourse-cdn.com/v4/letter/b/50afbb/32.png) [@balz.aschwanden](https://forum.ansible.com/u/balz.aschwanden)\
**Post date:** [February 14, 2018, 8:02am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/3 "2018-02-14T08:02:33Z")

</div>

We do exactly that: We run ansible in pull mode with AD as inventory.

Maybe you can take a look at the dynamic inventory script we use: [https://github.com/ANTS-Framework/ants/blob/master/antslib/inventory/inventory\_ad](https://github.com/ANTS-Framework/ants/blob/master/antslib/inventory/inventory_ad)  
(Because it is used for ansible-pull, it will only return the current host, but it should give you some ideas.)

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [February 19, 2018, 2:09pm UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/4 "2018-02-19T14:09:54Z")

</div>

Here’s a rather basic and unfinished script which might be of use to you too.

By the way inventory plugins are a thing now, might be worth while making into a inventory plugin rather than a simple inventory script

`

#!/usr/bin/env python

# -_- coding: utf-8 -_-

‘’’

Example dynamic inventory script which queries active directory.

Likely to need modification for each environment as there are likely  
to be different versions of active directory in use needing different  
connection parameters.

To use, create a configuration file in users’s home dir  
called .ansible\_inventory.cfg

must contain a [domain] section  
and then settings for the following values  
domain\_controller  
connect\_to\_dc\_with\_ssl (either True or False)  
query\_domain  
query\_user  
query\_pass

‘’’

# import class and constants

from ldap3 import Server, Connection, ALL, NTLM, Tls  
import json  
import ssl  
import pprint  
import re  
import ConfigParser, os

config = ConfigParser.ConfigParser()  
user\_dir = os.path.expanduser(“~”)  
config.read(user\_dir + ‘/.ansible\_inventory.cfg’)

domain\_controller = config.get(‘domain’, ‘domain\_controller’)  
connect\_to\_dc\_with\_ssl= config.getboolean(‘domain’, ‘connect\_to\_dc\_with\_ssl’)  
query\_domain = config.get(‘domain’, ‘query\_domain’)  
query\_user = config.get(‘domain’, ‘query\_user’)  
query\_cred = config.get(‘domain’, ‘query\_pass’)

user = query\_domain + “\” + query\_user

# define the server and the connection

# TODO see if not doing get\_info speeds things up

server = Server(domain\_controller, use\_ssl=connect\_to\_dc\_with\_ssl, get\_info=‘ALL’)

# TODO remove debug statements

# print “showing server information”

# print (server.info)

# TODO determine if it is quicker to use auto\_bind=True

#conn = Connection(server, user=“[playnetwork.com](http://playnetwork.com)\ldapusr”, password=ldappwd, authentication=NTLM, auto\_bind=True)

conn = Connection(server, user=user, password=query\_cred, authentication=NTLM)

conn.open()  
conn.bind()

# conn.entries

# print(conn)

conn.search(‘CN=Computers, DC=subdomain, DC=yourorg, DC=yourcompany, DC=com’, ‘(objectclass=computer)’, attributes=[“name”,“OperatingSystem”])

#pp = pprint.PrettyPrinter(indent=4)  
#pp.pprint (conn.response)

# print conn.entries

# generate list of all servers (replace ‘HOST’ with something that matches machines you want to be part of inventory

names =   
for x in conn.response:  
atts = x[‘attributes’]  
if ‘operatingSystem’ in atts:  
if atts[“operatingSystem”] == ‘Windows Server 2012 R2 Standard’:  
if re.match(‘HOST’, atts[‘name’] ):  
names.append(atts[‘name’])

# TODO add group. This ought to be doable via a server naming convention

# TODO add \_meta for speed as mentioned here: [http://docs.ansible.com/ansible/developing\_inventory.html](http://docs.ansible.com/ansible/developing_inventory.html)

# TODO add vars

conn.unbind()

hosts = {}  
hosts[‘hosts’] = names  
var = {‘a’:True}

export = {}  
export[‘main\_group’] = hosts  
export[‘main\_group\_win’] = hosts  
#export[‘vars’] = var  
`

---

<div class="post-metadata">

**Author:** ![Sam2](https://avatars.discourse-cdn.com/v4/letter/s/9de0a6/32.png) [@Sam2](https://forum.ansible.com/u/Sam2)\
**Post date:** [January 4, 2019, 10:40am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/5 "2019-01-04T10:40:04Z")

</div>

Hi,

Thanks for sharing, I spent sometime trying to make it work … but I am getting an error about Python module:

# python

Python 2.7.5 (default, Oct 30 2018, 23:45:53)  
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2  
Type “help”, “copyright”, “credits” or “license” for more information.

> > > import ants

but I still get:

Traceback (most recent call last):  
File “/tmp/tt”, line 32, in   
from antslib import configer  
ImportError: No module named antslib

any ideas ?

Thanks  
Sam

---

<div class="post-metadata">

**Author:** ![balz.aschwanden](https://avatars.discourse-cdn.com/v4/letter/b/50afbb/32.png) [@balz.aschwanden](https://forum.ansible.com/u/balz.aschwanden)\
**Post date:** [January 4, 2019, 1:51pm UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/6 "2019-01-04T13:51:09Z")

</div>

Hey Sam

I never tried to import ants directly. Depending on your use case, it might be easier to 1) call it using subprocess or 2) copy [the inventory file](https://github.com/ANTS-Framework/ants/blob/master/antslib/inventory/inventory_ad) and adapt it to your needs.

Regards,  
Balz

---

<div class="post-metadata">

**Author:** ![j.r.hawkesworth](https://avatars.discourse-cdn.com/v4/letter/j/a3d4f5/32.png) [@j.r.hawkesworth](https://forum.ansible.com/u/j.r.hawkesworth)\
**Post date:** [January 5, 2019, 9:23am UTC](https://forum.ansible.com/t/dynamic-inventory-using-active-directory-ldap/26714/7 "2019-01-05T09:23:28Z")

</div>

Can you share the script you have so far? I’m not aware of ‘ants’ but sounds like its a problem locating something that you are importing.

Jon
