Ansible Facts

Ansible facts are variables that are automatically discovered by Ansible from a managed host. Facts are pulled by the setup module and contain useful information stored into variables that administrators can reuse. Ansible facts can be part of playbooks, in conditionals, loops, or any other dynamic statement that depends on a value for a managed host

What are facts

  • Facts are information discovered by Ansible about a target system
  • There are two ways facts are collected:
    • Using the setup module with an ad-hoc command: ansible all -m setup
    • Facts are gathered by default when a playbook is executed
  • Fact gathering in playbooks may be disabled using the gather_facts attribute

How to use facts

  • Any collected facts, they may be accessed through variables:
    • {{ ansible_default_ipv4.address))
  • It is possible to use filters with regex, in ad-hoc
    mode, to match certain fact names
  • Facts may also be used with conditionals to have plays behave differently on hosts that meet certain criteria

The following table shows some of the facts gathered from a managed node that may be useful in a playbook:

Fact Variable
Hostname {{ ansible_hostname }}
FQDN {{ ansible_fqdn }}
Main IPv4 address (based on
{{ ansible_default_ipv4.address }}
Main disk first partition size
(based on disk name, such as
vda, vdb, and so on.)
{{ ansible_devices.vda.partitions.vda1.size }}
DNS servers {{ ansible_dns.nameservers }}
kernel version  {{ ansible_kernel }}

When a fact is used in a playbook, Ansible dynamically substitutes the variable name with the corresponding value:

Administrators can manually disable facts for managed hosts if a large number of servers are being managed. To disable facts, set gather_facts to no in the playbook:

Facts are always gathered by Ansible unless overridden in this way.


Custom Facts – Facts.d

  • It is possible to define custom facts on your servers using the facts.d directory
  • Create /etc/ansible/facts.d directory on target system. All valid files within this directory ending in .fact are returned under ansible_local with facts
  • Fact files may be INI, JSON, or an executable that returns JSON


Listing all facts from the managedhost1:

Filter facts from the managedhost1 for example with “ip” word:

Facts about distribution:


Creating local facts on managedhost1:

As we se above ansible is not iinstalled on the managedhost1 because it only use ssh  on the clients.

On the controlnode we can print local facts from the managedhost1:


Example 1.

The Ansible setup module retrieves facts from a system. Run an ad hoc command to retrieve the facts for all servers in the labservers group.

Filter the facts matching the ansible_user expression. Append a wildcard to match all facts starting with ansible_user.

Create a fact file named custom.fact. The fact file defines the package to install and the service to start on servera. The file should read as follows:

Create the setup_facts.yml playbook to make the /etc/ansible/facts.d remote directory and to save the custom.fact file to that directory.

Run an ad hoc command with the setup module. Since user-defined facts are put into the ansible_local section, use a filter to display only this section. There should not be any custom facts at this point.

Run the setup_facts.yml playbook.

Run with become a root parameter:

To ensure the new facts have been properly installed, run an ad hoc command with the setup module again. Display only the ansible_local section. The custom facts should appear.

It is now possible to create the main playbook that uses both default and user facts to configure managedhost2. The first task installs the httpd package. Use the user fact for the name of the package. Second task  uses the custom fact to start the httpd service.

Before running the playbook, use an ad hoc command to verify the httpd service is not currently running on managedhost2:

Run the playbook using the ansible-playbook command. Watch the output as Ansible starts by installing the package, then enabling the service.

Use an ad hoc command to execute systemctl to check if the httpd service is now running on managedhost2: