In the world of IT automation, Ansible stands out as a powerful tool that simplifies the management of server configurations and deployments. One of the key features of Ansible is its ability to use dynamic inventories, which allow you to fetch hosts from external sources. In this article, we will explore how to create a dynamic inventory that fetches hosts from Microsoft Active Directory (AD).
Problem Scenario
Many organizations use Microsoft AD to manage their infrastructure, and it's common to want to automate tasks across these servers using Ansible. A common requirement is to create a dynamic inventory that can automatically pull the necessary host information from AD, rather than maintaining a static inventory file. Here’s an example of a problem that many system administrators face:
Original Code:
[servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11
This static inventory setup is cumbersome, particularly in environments where servers frequently change.
Understanding Dynamic Inventory
A dynamic inventory for Ansible is a script that retrieves host information from an external source at runtime. For Microsoft Active Directory, you can use a combination of Python scripts and the ldap
module to query AD and return the list of hosts in a format that Ansible can interpret.
Steps to Create Dynamic Inventory for Active Directory
Here are the steps to create a dynamic inventory script that fetches hosts from Microsoft AD.
Step 1: Prerequisites
Before you begin, ensure you have the following:
- Ansible installed on your control machine.
- Python 3.x and the
ldap3
library. You can installldap3
using pip:
pip install ldap3
Step 2: Create the Dynamic Inventory Script
Create a new Python script, let's call it ad_inventory.py
. Below is a basic version of what this script might look like:
#!/usr/bin/env python3
import json
import ldap3
# LDAP server details
LDAP_SERVER = 'ldap://your_ad_server'
USERNAME = '[email protected]'
PASSWORD = 'your_password'
BASE_DN = 'dc=domain,dc=com'
def get_hosts():
# Connect to the LDAP server
server = ldap3.Server(LDAP_SERVER)
conn = ldap3.Connection(server, user=USERNAME, password=PASSWORD, auto_bind=True)
# Search for all computers in AD
conn.search(BASE_DN, '(objectClass=computer)', attributes=['cn', 'ipHostNumber'])
hosts = {}
for entry in conn.entries:
host_name = entry.cn.value
ip_address = entry.ipHostNumber.value if 'ipHostNumber' in entry else 'unknown'
hosts[host_name] = {'ansible_host': ip_address}
return hosts
if __name__ == '__main__':
inventory = {
'all': {
'children': {
'servers': {
'hosts': get_hosts()
}
}
}
}
print(json.dumps(inventory))
Step 3: Make the Script Executable
Make sure your script is executable:
chmod +x ad_inventory.py
Step 4: Configure Ansible to Use the Dynamic Inventory
In your Ansible configuration file (ansible.cfg
), set the inventory to your dynamic inventory script:
[defaults]
inventory = ./ad_inventory.py
Step 5: Test the Dynamic Inventory
You can test your dynamic inventory by running the following command:
ansible-inventory --list
This will display the list of hosts fetched from Active Directory.
Additional Considerations
-
Security: Ensure that you handle credentials securely. Instead of hardcoding them, consider using environment variables or a secure credential store.
-
Filtering: Depending on your environment, you may want to refine your LDAP search to filter the results further (e.g., by organizational unit).
-
Error Handling: Enhance the script with error handling to manage connection issues or search failures.
Conclusion
Creating a dynamic inventory for Ansible that fetches hosts from Microsoft Active Directory is a powerful way to simplify your automation tasks. With the provided Python script, you can efficiently manage your inventory without the hassle of maintaining static files.
By leveraging Ansible's capabilities alongside Active Directory, organizations can streamline their operations, enhance productivity, and ensure that their configurations are always up to date.
Useful Resources
Feel free to modify and expand upon the provided script to better fit your organization’s needs. Happy automating!