Fact Gathering
Relevant source files
The following files were used as context for generating this wiki page:
- lib/ansible/modules/gather_facts.py
- lib/ansible/modules/setup.py
- test/units/module_utils/facts/test_ansible_collector.py
- lib/ansible/config/base.yml
- test/integration/targets/gathering_facts/test_gathering_facts.yml
- test/support/windows-integration/plugins/modules/setup.ps1
- lib/ansible/module_utils/facts/system/local.py
- lib/ansible/modules/package_facts.py
- test/integration/targets/facts_d/tasks/main.yml
Fact gathering is the process by which Ansible collects useful variables about remote hosts. These variables, or "facts," contain information such as operating system, network interfaces, memory, and more. This process is typically run automatically at the beginning of a playbook execution, making system-specific data available for use in subsequent tasks, templates, and conditionals.
The primary module responsible for fact gathering is ansible.builtin.setup. The ansible.builtin.gather_facts module serves as a wrapper that executes configured fact-gathering modules, with setup being the default. The entire system is extensible, allowing for different collectors to gather specific subsets of information, and can be customized to improve performance by limiting the scope of data collection.
Sources: lib/ansible/modules/setup.py:59-63, lib/ansible/modules/gather_facts.py:16-19
Core Components and Process Flow
The fact-gathering mechanism involves several key components: the gather_facts keyword in a play, the gather_facts module, and the underlying fact collector modules like setup.
The general process is as follows:
- A playbook execution begins.
- If
gather_facts: true(the default) is set for a play, Ansible implicitly runs a setup task. - This task invokes the
ansible.builtin.gather_factsmodule (or another configured module viaFACTS_MODULES). - The
gather_factsmodule executes one or more fact-gathering modules, by defaultansible.builtin.setup. - The
setupmodule runs on the target host and utilizes a system of fact collectors to gather information. - The collected facts are returned as a JSON object and stored in the
ansible_factsvariable for the host.
Sources: lib/ansible/modules/gather_facts.py:16-19, lib/ansible/modules/setup.py:59-63, lib/ansible/config/base.yml:1115-1126
Process Flow Diagram
This diagram illustrates the high-level flow of the fact-gathering process.
Fact Collectors
The setup module uses a modular architecture of "Fact Collectors" to gather different categories of information. Each collector is a class responsible for a specific subset of facts.
Sources: lib/ansible/modules/setup.py:126-136, test/units/module_utils/facts/test_ansible_collector.py:30-58
Collector Architecture
The system is built around a BaseFactCollector class, from which more specific collectors inherit. The ansible_collector.get_ansible_collector function is responsible for assembling the required set of collectors based on the gather_subset parameter.
This diagram shows the relationship between the main AnsibleFactCollector and various BaseFactCollector implementations.
Fact Subsets
Facts are organized into subsets, which allows for granular control over what information is collected. The gather_subset parameter controls which collectors are activated.
Some of the available subsets include:
all: Gathers all facts. This is the default.min: A minimal subset required for many basic operations.network: Network configuration, interfaces, and addresses.hardware: CPU, memory, and BIOS information.virtual: Virtualization type and role (guest/host).local: Custom facts from/etc/ansible/facts.d.pkg_mgr: Information about the system's package manager.facter/ohai: Facts from external tools if installed.
A minimal_gather_subset is defined to include essential facts even when a smaller subset is requested. This minimal set includes apparmor, caps, cmdline, date_time, distribution, dns, env, fips, local, lsb, pkg_mgr, platform, python, selinux, service_mgr, and user.
Sources: lib/ansible/modules/setup.py:14-46,117-121, test/integration/targets/gathering_facts/test_gathering_facts.yml
Controlling Fact Gathering
Several parameters and configuration settings allow for fine-tuning the fact-gathering process, primarily for performance optimization.
setup Module Parameters
The ansible.builtin.setup module accepts several parameters to control its behavior.
| Parameter | Type | Default | Description |
|---|---|---|---|
gather_subset | list | ["all"] | Restricts fact collection to the given subset(s). Can use ! for negation (e.g., !hardware). |
gather_timeout | int | 10 | Timeout in seconds for individual fact-gathering operations. |
filter | list | [] | Filters the returned facts using shell-style (fnmatch) patterns. An empty list means no filtering. |
fact_path | path | /etc/ansible/facts.d | Path to a directory containing local fact files (*.fact). |
Sources: lib/ansible/modules/setup.py:12-58
gather_subset Usage
The gather_subset parameter is the primary way to control which facts are collected.
- Collect only specific subsets:
gather_subset: [network, virtual] - Collect all except specific subsets:
gather_subset: ['!all', 'network', 'virtual'] - Exclude certain subsets:
gather_subset: ['!hardware', '!facter'] - Collect only the minimal set:
gather_subset: '!all' - Collect no facts (not even minimal):
gather_subset: ['!all', '!min']
These can be specified at the play level or directly on a setup task.
Sources: lib/ansible/modules/setup.py:14-46, test/integration/targets/gathering_facts/test_gathering_facts.yml:250-257,280-287
Local Facts (fact_path)
Ansible can load custom facts from files located in a specific directory on the managed node, defined by the fact_path parameter (defaulting to /etc/ansible/facts.d).
- Files ending in
.factare processed. - If a file is executable, it is run, and its standard output is parsed.
- If not executable, the file content is read.
- The content is parsed as JSON. If that fails, it's parsed as an INI file.
- The resulting facts are placed under the
ansible_localkey inansible_facts.
For Windows targets, files in fact_path must be PowerShell scripts (.ps1) that output a PowerShell object. The facts are added to a variable named after the file, not ansible_local.
Sources: lib/ansible/module_utils/facts/system/local.py:22-86, lib/ansible/modules/setup.py:47-58, test/integration/targets/facts_d/tasks/main.yml:26-28
Configuration Settings
Several settings in ansible.cfg can modify the default fact-gathering behavior.
| Setting | Default | Description |
|---|---|---|
DEFAULT_GATHERING | implicit | Controls the default fact-gathering policy. implicit gathers per play, explicit requires gather_facts: true, and smart uses a cache. |
FACTS_MODULES | ['smart'] | A list of modules to run for fact gathering. smart tries to determine the correct module based on connection type. |
CACHE_PLUGIN | memory | The plugin to use for fact caching. |
CACHE_PLUGIN_CONNECTION | ~ | Connection string for the cache plugin. |
CACHE_PLUGIN_TIMEOUT | 86400 | Expiration timeout in seconds for cached facts. |
INJECT_FACTS_AS_VARS | True | If True, injects facts into the main variable namespace in addition to ansible_facts. |
Sources: lib/ansible/config/base.yml:1115-1126,134-149,1292-1300
Platform-Specific Implementations
POSIX Systems
On POSIX-like systems, fact gathering is handled by the Python-based ansible.builtin.setup module. It uses a series of Python classes (collectors) to gather information from system files, commands, and environment variables.
Sources: lib/ansible/modules/setup.py:108-136
Windows Systems
On Windows targets, fact gathering is handled by a PowerShell script, setup.ps1. This script mirrors the functionality of its Python counterpart.
- It respects the
gather_subsetparameter to limit data collection. - It uses
Get-CimInstanceto query WMI/CIM for system information like BIOS, OS details, memory, and processor specs. - It supports custom facts via
fact_path, executing.ps1scripts and adding their output to the facts dictionary. - It organizes subsets into groups (
min,network,hardware) similar to the Python version.
The following diagram shows the sequence for Windows fact gathering.
Specialized Fact Modules
Besides the general-purpose setup module, Ansible includes specialized modules for gathering specific types of facts. An example is ansible.builtin.package_facts.
package_facts Module
This module collects information about installed packages on a system.
- It can automatically detect the package manager (
rpm,apt,pacman, etc.) or be told which one to use via themanagerparameter. - It returns a
packagesdictionary withinansible_facts, where keys are package names and values are lists of installed versions. - This allows for checks like
when: "'foobar' in ansible_facts.packages".