Ansible facts are variables that are automatically discovered by Ansible on a managed node.
Facts contain host specific information that can be used just like regular variables in plays, or any other statement that depends on a value collected from a managed node.
Some facts gathered for a managed node might include:
Hostname
Serial number
Network operating system version
Network interface names
Network interface IP addresses
Number of CPUs
Available or free memory
Size and free space of storage devices
Facts are a convenient way to retrieve the state of a managed node and to determine what action to take based on that state.
For example, your play might perform one of the following actions:
Restart a managed node based on the value of a fact that was gathered, such as the state of a particular interface.
Detect and resolve a configuration issue based on the value of a fact.
Customize a configuration based on the network OS version that is reported by a fact.
In previous versions, Ansible was unable to gather facts for managed network nodes using the default fact gathering method of setting the gather_facts keyword to true.
In Ansible version 2.9 and later, if you set the gather_facts keyword to true, then Ansible tries to detect the network platform and use the appropriate *_facts module to gather facts.
The default setting is to gather a minimal subset of facts.
This is equivalent to setting the gather_subset parameter to min.
To view a minimal subset of facts for a specific network platform, create a short playbook with a play that gathers facts by setting the gather_facts keyword to true.
Then use the ansible.builtin.debug module to display the value of the ansible_facts variable.
---
- name: Gather and display default facts for IOS managed nodes
hosts: ios
gather_facts: true
tasks:
- name: Display facts
ansible.builtin.debug:
var: ansible_factsThe following play gathers and displays the equivalent set of facts as the previous play:
--- - name: Gather and display default facts for IOS managed nodes hosts: iosgather_facts: falsetasks: - name: Gather IOS facts cisco.ios.ios_facts:gather_subset:- min- name: Display facts ansible.builtin.debug:var: ansible_facts
Use *_facts resource modules to gather facts for your managed nodes.
For example, for Cisco IOS or IOS XE managed nodes, use the cisco.ios.ios_facts resource module.
For Juniper Junos managed nodes, use the junipernetworks.junos.junos_facts resource module.
View the collections documentation for each network platform at https://docs.ansible.com/ansible/latest/collections/ to determine which modules to use.
To view all available facts for a specific network platform, create a short playbook that gathers all facts by setting the gather_subset parameter to all.
Then use the ansible.builtin.debug module to display the value of the ansible_facts variable.
---
- name: Gather and display all facts for IOS managed nodes
hosts: ios
gather_facts: false
tasks:
- name: Gather IOS facts
cisco.ios.ios_facts:
gather_subset:
- all
- name: Display facts
ansible.builtin.debug:
var: ansible_factsWhen you run the playbook, the facts are displayed in the output:
[user@host ~]$ ansible-navigator run iosfacts.yml -m stdout
PLAY [Gather and display facts for IOS managed nodes] *************************
TASK [Gather IOS facts] **********************************************************
ok: [iosxe2.lab.example.com]
ok: [iosxe1.lab.example.com]
TASK [Display facts] *******************************************************
ok: [iosxe1.lab.example.com] => {
"ansible_facts": {
"net_all_ipv4_addresses": [
"172.25.250.20"
],
"net_all_ipv6_addresses": [],
"net_api": "cliconf",
"net_config": "Building configuration...\n\nCurrent configuration : 6062 bytes\n!\n! Last configuration change at 15:55:19 UTC Thu Jul 6 2023\n!\nversion 17.6\nservice timestamps debug datetime msec\nse
...output omitted...The playbook displays facts in JSON format as a dictionary of variables. You can browse the output to see what facts are gathered, and to find facts that you might want to use in your plays.
The following table shows some facts that might be gathered from a managed node and which might be useful in a playbook:
Table 4.1. Examples of Ansible Facts
| Fact | Variable |
|---|---|
| Hostname |
ansible_facts['net_hostname']
|
| Serial Number |
ansible_facts['net_serialnum']
|
| Network OS |
ansible_facts['net_system']
|
| Network OS Version |
ansible_facts['net_version']
|
| IPv4 addresses |
ansible_facts['net_all_ipv4_addresses']
|
| Current Active Configuration |
ansible_facts['net_config']
|
One of two syntaxes can be used to retrieve the value of a fact, as in the following examples:
ansible_facts['net_hostname'] can also be written as ansible_facts.net_hostname
ansible_facts['net_config'] can also be written as ansible_facts.net_config
You can also register the output of the *_facts resource modules to a variable.
Because facts are stored in the registered variable, you need to reference the facts using the registered variable's namespace, as in the following example:
---
- name: Gather and display facts for IOS managed nodes
hosts: ios
gather_facts: true
tasks:
- name: Gather IOS facts
cisco.ios.ios_facts:
gather_subset:
- all
register: iosfacts
- name: Display a fact
ansible.builtin.debug:
var: iosfacts['ansible_facts']['ansible_net_hostname']Facts stored in a registered variable are referenced using that variable's namespace, and the individual facts are prefaced with the string ansible_.
For example, the fact ansible_facts['net_hostname'] registered under the variable iosfacts is named iosfacts['ansible_facts']['ansible_net_hostname'].
Because gathered facts are automatically added to the ansible_facts variable, it is simpler and more scalable to reference them using the ansible_facts namespace.
When a fact is used in a playbook, Ansible dynamically substitutes the variable name for the fact with the corresponding value:
---
- name: Display specific facts for managed nodes
hosts: ios
gather_facts: false
tasks:
- name: Gather IOS facts
cisco.ios.ios_facts:
gather_subset:
- all
- name: Display hostname and IPv4 addresses
ansible.builtin.debug:
msg: >-
The IPv4 addresses of interfaces on
{{ ansible_facts['net_hostname'] }} are
{{ ansible_facts['net_all_ipv4_addresses'] }}The following output shows how Ansible was able to query the managed node and dynamically use the information to update the variable:
[user@host ~]$ ansible-navigator run factssubset.yml -m stdout
PLAY [Display specific facts for managed nodes] *******************************
TASK [Gather IOS facts] *******************************************************
ok: [iosxe2.lab.example.com]
ok: [iosxe1.lab.example.com]
TASK [Display hostname and IPv4 addresses] ************************************
ok: [iosxe2.lab.example.com] => {
"msg": "The IPv4 addresses of interfaces on iosxe2.lab.example.com are ['172.25.250.21']"
}
ok: [iosxe1.lab.example.com] => {
"msg": "The IPv4 addresses of interfaces on iosxe1.lab.example.com are ['172.25.250.20']"
}
PLAY RECAP ********************************************************************
iosxe1.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 ...
iosxe2.lab.example.com : ok=2 changed=0 unreachable=0 failed=0 ...Gather facts from different network platforms by using the appropriate facts module for each platform.
For example, the following playbook uses a different module in each task to gather facts based on the value of the network_os fact:
---
- name: Gather facts from different network platforms
hosts: all
gather_facts: false
tasks:
- name: Gather IOS facts
cisco.ios.ios_facts:
gather_subset:
- all
when: ansible_network_os == 'cisco.ios.ios'
- name: Gather Junos facts
junipernetworks.junos.junos_facts:
gather_subset:
- all
when: ansible_network_os == 'junipernetworks.junos.junos'You might not want to gather facts for your play for the following reasons:
You might not be using any facts and want to speed up the play, or reduce load caused by the play on the managed nodes.
The managed nodes cannot run the ansible.builtin.setup module for some reason, or cannot gather all facts using that module.
This is often the case for managed network nodes.
To disable fact gathering for a play, set the gather_facts keyword to false.
You should do this for managed network nodes, unless they support the ansible.builtin.setup module for all fact gathering.
Configure fact modules to gather all facts for a managed node by setting the gather_subset parameter to all.
Configure fact modules to only gather a subset of facts by setting the gather_facts parameter to the subset you want to gather.
For example, to only gather facts about the configuration, set the gather_subset parameter to config:
- name: Collect only configuration facts
cisco.ios.ios_facts:
gather_subset:
- configIf you want to gather all facts except a certain subset, add an exclamation point (!) in front of the subset name. Add quotes around the string because in YAML the exclamation point cannot be used at the start of an unquoted string.
- name: Collect all facts except for the configuration subset
cisco.ios.ios_facts:
gather_subset:
- "!config"Refer to the documentation for each fact module to view possible values for the gather_subset parameter.
For example, visit https://docs.ansible.com/ansible/latest/collections/cisco/ios/ios_facts_module.html#ansible-collections-cisco-ios-ios-facts-module to view possible values for the gather_subset parameter for the cisco.ios.ios_facts module.
Use the gather_network_resources parameter to gather facts as structured network resource data.
You can gather all resource facts or a subset of resource facts, similar to the gather_subset parameter.
For example, when using the cisco.ios.ios_facts module, you can set the gather_network_resources parameter to values such as the following:
l3_interfaces
acls
interfaces
"!lldp_interfaces,!ospf_interfaces"
static_routes
"!vlans"
Refer to the module documentation for the full list of valid values for the gather_network_resources parameter.
Display network resource facts by referencing the ansible_network_resources variable, as in the following example:
---
- name: Gather facts as resource data
hosts: ios
gather_facts: false
tasks:
- name: Gather IOS facts
cisco.ios.ios_facts:
gather_network_resources:
- all
- name: Display facts
ansible.builtin.debug:
var: ansible_network_resourcesAnsible sets some special variables automatically. These magic variables can also be useful to get information specific to a particular managed node. Magic variable names are reserved, so you should not define variables with these names.
The following list describes four of the most useful magic variables:
hostvars
The hostvars variable contains the variables for managed nodes, and can be used to get the values for another managed node's variables.
It does not include the managed node's facts if they have not yet been gathered for that host.
group_names
The group_names variable lists all groups that the current managed node is in.
groups
The groups variable lists all groups and managed nodes in the inventory.
inventory_hostname
The inventory_hostname variable contains the hostname for the current managed node as configured in the inventory.
This might be different from the hostname reported by facts for various reasons.
The following task causes every host that runs the play to display the serial number of the junos1.lab.example.com managed node.
It uses the hostvars magic variable to access the ansible_facts['net_serialnum'] fact for that host.
This task works as long as facts were gathered for junos1.lab.example.com earlier in the play or by a preceding play in the playbook:
- name: Print the serial number of junos1
ansible.builtin.debug:
var: hostvars['junos1.lab.example.com']['ansible_facts']['net_serialnum']Several other magic variables are also available.
For more information, see https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html.