Product and service reviews are conducted independently by our editorial team, but we sometimes make money when you click on links. Learn more.
 

How to Build a Dynamic Inventory with Red Hat's Ansible

By - Source: Toms IT Pro

With Ansible, admins can build a configuration and deliver that configuration to one, 100, or 1,000 servers with a single command, thanks to its running inventory.

Credit: ShutterstockCredit: ShutterstockServer environments are always changing, with new ones getting added and removed regularly. As a result, it's important to keep tooling designed to manage these servers dynamically. Static lists will, over time, become cumbersome to keep up to date and will soon turn into a major headache.

Ansible is an automation framework design to perform lots of different tasks on many servers at once. With Ansible, admins can build a configuration and deliver that configuration to one, 100, or 1,000 servers with a single command. But how does Ansible know which servers to deliver configurations to? Ansible has an inventory that it routinely reads to figure this out. By default, it looks for a host files that contains server names optionally grouped together with group names.

MORE: Choosing the Right Configuration Management Tool

mail.example.com

[webservers]
foo.example.com
bar.example.com

[dbservers]
one.example.com
two.example.com
three.example.com

Ansible then reads this file and delivers configurations to each server defined in the playbook. However, this isn't scalable. Using this method, an administrator will have to manually edit this file every time a new server is added, removed or needed moved to a new group. Wouldn't it be nice if a set of rules could be defined and the servers would just automatically be updated? Luckily, there is by using the dynamic inventory feature. Ansible provides this feature to allow an administrator to replace the static text files with a Python script.

The concept is simple. Traditionally when referencing an inventory file, you can point a playbook at a group of servers by specifying the server group right after the Ansible command.
$ ansible servergroup –a "somecommand"

This works but relies on those static text files. Instead, we can use the -i switch and specify the script name.
$ ansible -i inventory.py -a "somecommand"

Note: For this method to work, ensure that the Python script is marked as executable by running chmod +x beforehand. Otherwise, Ansible will not be able to execute the script.

Now, whatever logic that's inside of inventory.py changes, the targeted servers will change. But a Python script can't just contain any old code. It must return JSON in the following format:

@{
    group=@{
        hosts=@();
        vars=@{}
    };
    _meta=@{
        hostvars=@{}
    }
}

This structure can be used to not only include server names but also groupings, group variables, host variables and more. For example, here's a way to pull server names from Active Directory using PowerShell.

$json = @{group=@{hosts=@();vars=@{}};_meta=@{hostvars=@{}}}
@(Get-ADComputer -Filter * -server domain.local -Credential $Credential | select -ExpandProperty DNSHostName).foreach({ $json.group.hosts += $_ })
[pscustomobject]$json | ConvertTo-Json

Since Ansible cannot run on Windows, this command is run against a Windows "jump host" using the WinRM Python library. Ansible does not care where the JSON data comes from. The example I've just provided is unique and shows this clearly. As long as the Python script has a method to generate a list of server names and groups as strings and the script can output the JSON exactly as indicated above, Ansible will consume this JSON and know what to do with it.  Other typical examples are pulling server names and groups from databases or text files like CSVs on remote servers.

For more information on building Ansible inventories or on dynamic inventory, Ansible provides some excellent documentation. It may take a little bit to get a dynamic inventory up and running, but just realize it's a one-time task that will more than make up for the time incurred over the long term.

Comments