Ansible facts are data gathered about target nodes (host nodes to be configured) and returned back to controller nodes. Ansible facts are stored in JSON format and are used to make important decisions about tasks based on their statistics. Facts are in an ansible_facts variable, which is managed by Ansible Engine. Ansible facts play a major role in syncing with hosts in accordance with real-time data.
[ You might also like: An introduction to Ansible Tower ]
What exactly are Ansible facts and how are they used?
Ansible facts are the host-specific system data and properties to which you connect. A fact can be the IP address, BIOS information, a system's software information, and even hardware information. Ansible facts help the admin to manage the hosts based on their current condition rather than taking the actions directly without having any info about the system's health.
Here is a scenario: You have to install Apache webserver on all your Linux hosts. You know that Red Hat Enterprise Linux (RHEL)-based hosts work with the Red Hat Package Manager (RPM) and yum/dnf
. Other Linux distributions use their own package managers and so it would not be feasible to perform the same task on different systems without modification and reference to those differences. Package names also differ among distributions. For example, on RHEL systems, the Apache web server package is httpd, while in other distributions it's named apache2.
Here's an Ansible playbook to demonstrate the issue:
- hosts: all
tasks:
- package:
name: "httpd"
state: present
when ansible_facts["os_name"] == "RedHat"
- package:
name: "apache2"
state: present
when ansible_facts["os_name"] == "Ubuntu"
Here, the script will collect information about the system using Ansible facts and then perform the operation accordingly. When installing on RHEL systems, it automatically skips the Ubuntu-based package and vice versa. Similarly, you can use the Ansible facts to perform an operation if the system has a minimal amount of resources available.
In short, using Ansible facts, a system admin can make Ansible smarter by specifying parameters for when to perform tasks and when not to.
Accessing the facts
Ansible facts use the setup
module for gathering facts every time before running the playbooks.
Using the Ansible ad-hoc commands
1. Access Ansible facts using ad-hoc commands
The setup
module fetches all the details from the remote hosts to our controller nodes and dumps them directly to our screen for the facts to be visible to users.
ansible all -m setup
2. Filtering out a specific value from Ansible facts
Here, the setup
module is used to fetch the facts about the system, and further, it will use the filter argument to display the value from the Ansible facts.
ansible all -m setup -a "filter=ansible_cmdline"
Note: Ansible facts are retrieved only when working with playbooks. To access the Ansible facts using ad-hoc commands, use the setup
module.
Using the Ansible playbook
To access the variables from Ansible facts in the Ansible playbook, we need to use the actual name without using the ansible keyword.
ansible_facts["ansible_system"] ❌
ansible_facts["system"] ✔️
The gather_facts
module from the Ansible playbook runs the setup
module by default at the start of each playbook to gather the facts about remote hosts.
3. Accessing facts using Ansible playbook
Fetch the Ansible facts and display them using a playbook.
- hosts: all
tasks:
- debug:
var: ansible_facts
4. Accessing a specific fact using an Ansible playbook
Fetching the Ansible facts, filtering them, and displaying them using a playbook.
- hosts: all
tasks:
- debug:
var: ansible_facts["cmdline"]
Ansible facts and the datatype
Ansible facts are stored in JSON format and can be placed into three major categories:
List: Stores the list of items and the stored information is written inside square brackets []. These are mostly facts that can have multiple values, e.g., system_capablities
. The list is accessed using square brackets and specifying the index.
ansible_facts["all_ipv6_addresses"][1]
ansible_facts["all_ipv6_addresses"][2]
Dictionary: Stores the data as a collection of key-value pairs, and the information is stored inside curly brackets {}. These are mostly the facts that have sub-facts inside of them, e.g., memory_mb
. Dictionary is accessed using the dot operator.
ansible_facts.memory_mb.real
Ansible Unsafe Text: This type of variable doesn't have any subpart and stores the data directly, e.g., machine
. Ansible Unsafe Text can be accessed directly by using the fact name.
ansible_facts["machine"]
Use type_debug filter to check the datatype for the Ansible facts.
- hosts: all
tasks:
- debug:
var: ansible_facts["all_ipv6_addresses"]|type_debug
- debug:
var: ansible_facts["memory_mb"]|type_debug
- debug:
var: ansible_facts["machine"]|type_debug
type_debug filter prompts the datatype for the specified fact without printing the value for the fact.
[ Looking for more on system automation? Get started with The Automated Enterprise, a free book from Red Hat. ]
Wrap up
Ansible facts are data about the system which you want to configure. These facts make your Ansible system intelligent by providing the conditions for when to process some task. You can also process by not specifying or using the Ansible facts, but that would make the job as a sysadmin more hectic as the script may fail or change some of the files that were never intended to be modified.
For more information on Ansible facts, please see the official documentation.