Ansible Facts
An Ansible fact is a variable that contains information about a target system.This information can be used in conditional statements to tailor playbooks to that system. Systems facts are system property values. Custom facts are user-defined variables stored on managed hosts. system.
Facts are collected when Ansible executes on the remote system. You’ll see a “Gathering Facts” task everytime you run a playbook. These facts are then stored in the variable ansible_facts.
Use the debug module to check the value of variables. This module requires variables to be enclosed in curly brackets. This example shows a large list of facts from managed nodes:
There are two supported formats for using Ansible fact variables:
It’s recommended to use square brackets: ansible_facts['default_ipv4']['address'] but dotted notation is also supported for now: ansible_facts.default_ipv4.address
Commonly used ansible_facts:
There are additional Ansible modules for gathering more information. See `ansible-doc -l | grep fact
package_facts module collects information about software packages installed on managed hosts.
Two ways facts are displayed
Ansible_facts variable (current way)
- All facts are stored in a dictionary with the name ansible_facts, and items in this dictionary are addressed using the notation with square brackets
- ie:
ansible_facts['distribution_version'] - Recommended to use this.
injected variables (old way)
-
Variable are prefixed with the string ansible_
-
Will lose support eventually
-
Old approach and the new approach both still occur.
ansible ansible1 -m setupcommand Ansible facts are injected as variables.
Comparing ansible_facts Versus Injected Facts as Variables
Different notations can be used in either method, the listings address the facts in dotted notation, not in the notation with square brackets.
Addressing Facts with Injected Variables:
Addressing Facts Using the ansible_facts Variable
If, for some reason, you want the method where facts are injected into variables to be the default method, you can use inject_facts_as_vars=true in the [default] section of the ansible.cfg file.
• In Ansible versions since 2.5, all facts are stored in one variable: ansible_facts. This method is used while gathering facts from a playbook.
• Before Ansible version 2.5, facts were injected into variables such as ansible_hostname. This method is used by the setup module. (Note that this may change in future versions of Ansible.)
• Facts can be addressed in dotted notation:
{{ansible_facts.default_ipv4.address }}
• Alternatively, facts can be addressed in square brackets notation:
{{ ansible_facts['default_ipv4']['address'] }}. (preferred)
Managing Fact Gathering
By default, upon execution of each playbook, facts are gathered. This does slow down playbooks, and for that reason, it is possible to disable fact gathering completely. To do so, you can use the gather_facts: no parameter in the play header. If later in the same playbook it is necessary to gather facts, you can do this by running the setup module in a task.
Even if it is possible to disable fact gathering for all of your Ansible configuration, this practice is not recommended. Too many playbooks use conditionals that are based on the current value of facts, and all of these conditionals would stop working if fact gathering were disabled altogether.
As an alternative to make working with facts more efficient, you can disable a fact cache. To do so, you need to install an external plug-in. Currently, two plug-ins are available for this purpose: jsonfile and redis. To configure fact caching using the redis plug-in, you need to install it first. Next, you can enable fact caching through ansible.cfg.
The following procedure describes how to do this:
1. Use yum install redis.
2. Use service redis start.
3. Use pip install redis.
4. Edit /etc/ansible/ansible.cfg and ensure it contains the following parameters:
Note
Fact caching can be convenient but should be used with caution. If, for instance, a playbook installs a certain package only if a sufficient amount of disk space is available, it should not do this based on information that may be up to 24 hours old. For that reason, using a fact cache is not recommended in many situations.
Custom Facts
-
Used to provide a host with arbitrary values that Ansible can use to change the behavior of plays.
-
can be provided as static files.
-
files must
- be in either INI or JSON format,
- have the extension .fact, and
- on the managed hosts must be stored in the /etc/ansible/facts.d directory.
-
can be generated by a script, and
- in that case the only requirement is that the script must generate its output in JSON format.
Dynamic custom facts are useful because they allow the facts to be determined at the moment that a script is running. provides an example of a static custom fact file.
Custom Facts Sample File:
To get the custom facts files on the managed hosts, you can use a playbook that copies a local custom fact file (existing in the current Ansible project directory) to the appropriate location on the managed hosts. Notice that this playbook uses variables, which are explained in more detail in the section titled “Working with Variables.”
Custom facts are stored in the variable ansible_facts.ansible_local. In this variable, you use the filename of the custom fact file and the label in the custom fact file. For instance, after you run the playbook in Listing 6-9, the web_package fact that was defined in listing68.fact is accessible as
{{ ansible_facts[’ansible_local’][’listing67’][’packages’][’web_package’] }}
To verify, you can use the setup module with the filter argument. Notice that because the setup module produces injected variables as a result, the ad hoc command to use is ansible all -m setup -a "filter=ansible_local" . The command ansible all -m setup -a "filter=ansible_facts\['ansible_local'\]" does not work.
Lab Working with Ansible Facts
1. Create a custom fact file with the name custom.fact and the following contents:
2. Write a playbook with the name copy_facts.yaml and the following contents:
3. Apply the playbook using ansible-playbook copy_facts.yaml -i inventory
4. Check the availability of the custom facts by using ansible all -m setup -a "filter=ansible_local" -i inventory
5. Use an ad hoc command to ensure that the httpd service is not installed on any of the managed servers: ansible all -m yum -a "name=httpd state=absent" -i inventory -b
6. Create a playbook with the name setup_with_facts.yaml that installs and enables the httpd service, using the custom facts:
7. Run the playbook to install and set up the service by using ansible-playbook setup_with_facts.yaml -i inventory -b
8. Use an ad hoc command to verify the service is running: ansible ansible1 -a "systemctl status httpd" -i inventory -b
