Ansible’s setup module retrieves “facts” from nodes, and Seth Vidal, whom I had the great pleasure meeting during AnsibleFest last week, has added a very nice feature to it.

By specifying the configurable fact_path parameter to a directory on a node, Ansible will populate a special branch of the facts with information gleaned from *.fact files in the fact_path directory. (The fact_path directory defaults to /etc/ansible/facts.d.) Files can be in either INI file format (e.g. populated by Ansible’s ini_file or template modules), or they can return JSON.

In addition, if a file in fact_path is executable, setup will launch it and read its INI or JSON format output and merge all of that into the facts returned by setup.

For example, suppose I have the directory called /etc/ansible/facts.d containing the following files:

$ ls -l
-rwxr-xr-x 1 jpm mens 70 Jun 17 14:57 administrator.fact
-rw-r--r-- 1 jpm mens 39 Jun 17 14:58 system.fact

$ cat system.fact
[location]
city=Boston
street=Boylston

$ ./administrator.fact
{
    "name" : "Jane Jolie",
    "number" : 47,
    "phones" : [ "123456", "654321" ]
}

If I now launch setup, these facts are populated, in addition to all other facts that setup provides. (I’m using filter to show just the local branch.)

$ ansible wwww -m setup -a 'fact_path=/etc/ansible/facts.d filter=ansible_local'
www | success >> {
    "ansible_facts": {
        "ansible_local": {
            "administrator": {
                "name": "Jane Jolie",
                "number": 47,
                "phones": [
                    "123456",
                    "654321"
                ]
            },
            "system": {
                "location": {
                    "city": "Boston",
                    "street": "Boylston"
                }
            }
        }
    },
    "changed": false
}

Static fact files would probably be installed during initial provisioning of the bare metal, whereas dynamic (i.e. executable) fact files could obtain all sorts of data from any manner of places.

A question arose as to the usefulness of this, particularly in view of host_vars or group_vars being available to populate variables on a host or group of hosts basis. facts_path allows us to delegate control of settings to the owner of a node, and of course it allows us to populate facts dynamically from, say, a temperature sensor running on the node. How’s that for coolness (pun intended)? :-)

I’m sure you’ll be able to use this nicely. Thanks, Seth!

Further reading