Subscribe to the feed

If you manage Windows hosts with Red Hat Ansible Automation Platform then this blog is for you! I want to highlight the Active Directory inventory plugin which can be used to leverage Active Directory as a source of truth for Ansible Automation Platform. First, let’s take a step back and look at why inventory management is so important.

Ansible Automation Platform is designed to be an automation tool that is simple, powerful and agentless.

The agentless architecture gives us great breadth and depth in terms of what we can automate as we are not limited to managing devices that we can install agents on. In this agentless world, inventory management becomes a cornerstone for success. Typically we need to know:

  • What devices do we need to manage? Where will we get a list of our infrastructure which is up to date and accurate?
  • How do we classify nodes so that we know how to automate against them? For example, the automation we run against a database server will be different to a web server.

Inventory plugins provide a neat solution to these problems. In their simplest form, they are scripts that allow us to point to a source of truth to gather a list of servers and any characteristics that might help us to better understand how to automate against them.

When we think about managing a Microsoft Windows environment, Active Directory becomes a very appealing source of truth as servers are typically registered to a domain. Thanks to the Red Hat Ansible Certified Content Collection for Microsoft AD, we now have a great set of modules which can interact with Microsoft Active Directory and, importantly, an inventory plugin that  can leverage Active Directory as a source of truth. Using this inventory plugin, we can filter and group hosts based on their Active Directory attributes and group memberships.

Let’s take a look at the plugin in action.

Starting with the command line

Let’s start with the command line using automation content navigator and automation execution environments. Instructions for installing and configuring automation content navigator can be found in the content creation documentation. The supported execution environment that is shipped with Ansible Automation Platform 2.4+ already includes everything we need to start integrating with Microsoft Active Directory - this includes the microsoft.ad collection as well as the necessary Python dependencies. For prior releases, you may need to customize your execution environment to include these prerequisites.

Luckily, the debug_ldap_client module can be used to check for the necessary Python dependencies as well as DNS and Kerberos configuration. As we are using an automation execution environment, we will run this inside of the image to check that we have the required dependencies for the inventory plugin. We can ignore the traceback errors as we are only interested in ensuring the Python dependencies are present for our use-case.

$ ansible-navigator exec -- ansible localhost -m microsoft.ad.debug_ldap_client
  < Output Truncated >
"packages": {
    "dnspython": "2.3.0",
    "krb5": "0.5.0",
    "pyspnego": "0.9.0",
    "sansldap": "0.1.0"

To create an inventory definition to query our Active Directory server, our inventory file must end in microsoft.ad.ldap.yml or microsoft.ad.ldap.yaml so let’s simply call it microsoft.ad.ldap.yml. To test, I am using the following configuration. Before you shout -  I know that the username and password are in plain text. This is simply to allow us to do some initial connection testing so we can start playing with some of the attributes we might want to use. We will fix the credentials later.

plugin: microsoft.ad.ldap
server: ms-ad.demolab.local
username: svc-aap-ldap
password: Redhat123
tls_mode: ldaps

We can now test the plugin from the command line using the Ansible Automation Platform navigator “inventory” sub-command. As we are using ldaps, we are mapping the CA trust store from our RHEL host to the execution environment using the /etc/pki/ca-trust path.

If we look at the output, we can see that we have discovered a host called MS-AD which is our domain controller. 

$ ansible-navigator inventory -i microsoft.ad.ldap.yml --list -m stdout --eev /etc/pki/ca-trust:/etc/pki/ca-trust:O
{
"_meta": {
    "hostvars": {
        "MS-AD": {
            "ansible_host": "ms-ad.demolab.local",
            "microsoft_ad_distinguished_name": "CN=MS-AD,OU=Domain Controllers,DC=demolab,DC=local"
        }
    }
},
"all": {
    "children": [
        "ungrouped"
    ]
},
"ungrouped": {
    "hosts": [
        "MS-AD"
    ]
}
}

Connectivity looks good, but the information we got back is a little sparse and we didn’t manage to add the host to any groups. There are loads of documented parameters that we can provide the inventory plugin to customize it as needed.

In fact, all of the computer attributes from Active Directory can be used to filter, set variables or group hosts. To see all of the available attributes for our MS-AD host, we can use the following PowerShell command on a Windows host with the Active Directory PowerShell module installed.

Get-ADComputer -Identity "MS-AD" -Properties *

Let’s include some additional parameters and start to group hosts. Update the inventory configuration file - microsoft.ad.ldap.yml to include some additional attributes to retrieve from Active Directory. In our updated example, we are getting attributes for “OperatingSystem” and “location” as well as a list of all of the groups the computer is a member of. Don’t worry if that regex_search line looks scary–I copied and pasted from the documentation.

The last section of the configuration defines our Ansible Automation Platform groups so we can classify nodes. All machines will automatically be added to a group called “windows”. We will also add any host which is a member of a “Production” domain group to a corresponding group called “production”. Lastly, we’ll add hosts to groups based on the operating system and location attributes. Here is the final configuration file.

plugin: microsoft.ad.ldap
server: ms-ad.demolab.local
username: svc-aap-ldap
password: Redhat123
tls_mode: ldaps
attributes:
  OperatingSystem:
operating_system:
  location:
  memberOf:
computer_membership: this | map("regex_search", '^CN=(?P<name>.+?)((?<!\\),)', '\g<name>') | flatten
groups:
  windows: true
  production: '"Production" in computer_membership'
keyed_groups:
- key: operating_system | lower
  prefix: os
  default_value: unknown
- key: location | lower
  default_value: unknown
  prefix: location

One final test from the command line. Let’s review the attributes we get back from Active Directory. The values with “__ansible_unsafe” simply mean that they are blocked from jinja2 templating.

$ ansible-navigator inventory -i microsoft.ad.ldap.yml -m stdout --host MS-AD --eev /etc/pki/ca-trust:/etc/pki/ca-trust:O
{
    "ansible_host": "ms-ad.demolab.local",
    "computer_membership": [
    {
        "__ansible_unsafe": "Production"
    }
    ],
    "location": {
    "__ansible_unsafe": "london-dc1"
    },
    "microsoft_ad_distinguished_name": "CN=MS-AD,OU=Domain Controllers,DC=demolab,DC=local",
    "operating_system": {
    "__ansible_unsafe": "Windows Server 2019 Standard Evaluation"
    }
}

Next let’s view the group membership. Our server is now a member of four Ansible Automation Platform groups which we can use to target it as needed.

$ ansible-navigator inventory -i microsoft.ad.ldap.yml -m stdout --graph --eev /etc/pki/ca-trust:/etc/pki/ca-trust:O
@all:
  |--@_london_dc1:
  |  |--MS-AD
  |--@os_windows_server_2019_standard_evaluation:
  |  |--MS-AD
  |--@production:
  |  |--MS-AD
  |--@windows:
  |  |--MS-AD

Testing complete! Let’s look at how we can use this in an enterprise environment with automation controller.

Configuring automation controller

Automation controller allows enterprises to standardize how automation is deployed, initiated, delegated and audited. Time to fix our plaintext credentials and put some controls around our inventory configuration.

  1. Create a credential type - Automation controller allows us to define custom credential types so that we can interact with various systems while maintaining our security posture. This will allow us to inject environment variables at run time rather than having them in plaintext. If you look in the documentation for the inventory plugin you will see that it will accept various environment variables for authentication. We will use these variables with automation controller.

    In the automation controller UI, go to “Credential Types” and press “Add”.  Give the credential type a name - let’s call it “Microsoft AD Inventory”. For the “Input configuration” we can use these fields to define the fields we expect for our username, password and AD server.

    fields:
      - id: MICROSOFT_AD_LDAP_USERNAME
    type: string
    label: Username
      - id: MICROSOFT_AD_LDAP_PASSWORD
    type: string
    label: Password
    secret: true
      - id: MICROSOFT_AD_LDAP_SERVER
    type: string
    label: AD Server
    required:
      - MICROSOFT_AD_LDAP_USERNAME
      - MICROSOFT_AD_LDAP_PASSWORD
      - MICROSOFT_AD_LDAP_SERVER

    The “injector configuration” defines the variables that we will inject into the inventory sync. Use the following:

    env:
      MICROSOFT_AD_LDAP_SERVER: '{{ MICROSOFT_AD_LDAP_SERVER }}'
      MICROSOFT_AD_LDAP_PASSWORD: '{{ MICROSOFT_AD_LDAP_PASSWORD }}'
      MICROSOFT_AD_LDAP_USERNAME: '{{ MICROSOFT_AD_LDAP_USERNAME }}'

 

  1. Create a Credential - Now that we have a new credential type, we can create a corresponding credential. Go to “Credentials” and click “Add”. Select the new credential type of “Microsoft AD Inventory” and populate the username, password and Active Directory server as we did from the command line.

  1. Create a project - We want to manage our Active Directory inventory configuration in source control so that changes flow through the relevant peer reviews and approvals. A project in automation controller allows us to map to a source control repository. I’ve taken the configuration we wrote for the command line and pushed it to a GitHub repository - https://github.com/pharriso/ansible_microsoft_ad_inventory

    IMPORTANT! - We haven’t pushed our username, password or Active Directory server to source control. These are now handled by our credential in automation controller. Please remove the parameters from the inventory configuration!

    In the automation controller UI, navigate to “Projects” and click “Add”. Here are the details for our project with the appropriate source control URL populated. You can learn more about the additional project fields in the documentation.

  1. Create an Inventory - We are ready to create our inventory. Navigate to “Inventories” and click “Add” and then “Add Inventory”. Give the inventory an appropriate name.

    Once you hit “Save”, additional options will become available for the inventory. Select “Sources” and click “Add”. This is where we will bring our configuration together by selecting the inventory configuration file and credential. Here is our completed inventory source.

    NOTE - the only possible gotcha here is that you need to manually enter the inventory file name and press enter to populate that field.

When we hit “Save” we will see a “Sync” button at the bottom of the screen. Pressing this will run our inventory plugin. We can follow the progress by looking at the “Last job status” or going to the “Jobs” menu item. Hopefully we will see “Success”!

We can validate our plugin configuration by going to “Inventories”, “Demolab AD Inventory” and then selecting the “Hosts” tab. We should see our hosts have been imported:

Clicking on the host we can also view the variables (attributes) we gathered from Active Directory. Finally, we can click on the “Groups” tab to check that we grouped the host correctly.

 

Next Steps

Inventory management is key to optimizing and scaling automation with Ansible Automation Platform. The Microsoft AD inventory plugin is just another example of how Ansible Automation Platform is able to simplify life for users like us. Hopefully by leveraging Active Directory as a source of truth you will be able to accelerate your journey with Ansible Automation Platform for Windows automation.


About the author

Pat Harrison works for Red Hat in the UK as an Associate Principal Specialist Solution Architect focused on Ansible automation. Prior to this, Pat worked as a Red Hat Consultant helping to deliver solutions across various Red Hat products.
Read full bio

Browse by channel

automation icon

Automation

The latest on IT automation for tech, teams, and environments

AI icon

Artificial intelligence

Updates on the platforms that free customers to run AI workloads anywhere

open hybrid cloud icon

Open hybrid cloud

Explore how we build a more flexible future with hybrid cloud

security icon

Security

The latest on how we reduce risks across environments and technologies

edge icon

Edge computing

Updates on the platforms that simplify operations at the edge

Infrastructure icon

Infrastructure

The latest on the world’s leading enterprise Linux platform

application development icon

Applications

Inside our solutions to the toughest application challenges

Original series icon

Original shows

Entertaining stories from the makers and leaders in enterprise tech