Facts

Tip

We recommend to use the Sandbox to play around with this example.

Tip

All the files from this section are in facts.zip.

In Hello World with Jinja, variables were introduced. In this section, you will learn about a special type of variables named facts that are gathered from the managed nodes. Facts can be used to conditionally execution of tasks as illustrated in Module and return.

Playbook

playbook.yml
- name: Display facts
  hosts:
    - all
  tasks:
    - name: Display GNU/Linux distribution
      ansible.builtin.debug:
        msg: '{{ ansible_distribution }}'

The above playbook has a single play with a single task that prints the name of the GNU/Linux distribution running on the managed node.

Running

cd facts &&
ansible-playbook \
--ask-vault-pass \
-i inventories/production.yml \
--extra-vars @vault/production \
playbook.yaml

Note

The password for the vault used in the example is 123. You must use a strong passwords, for example, a minimum of 8 randomly generated characters.

returns

PLAY [Display facts] ***********************************************************

TASK [Gathering Facts] *********************************************************
ok: [managed_node_02]
ok: [managed_node_03]
ok: [managed_node_04]
ok: [managed_node_01]

TASK [Display GNU/Linux distribution] ******************************************
ok: [managed_node_01] => {
    "msg": "Alpine"
}
ok: [managed_node_02] => {
    "msg": "Debian"
}
ok: [managed_node_03] => {
    "msg": "Ubuntu"
}
ok: [managed_node_04] => {
    "msg": "Fedora"
}

PLAY RECAP *********************************************************************
managed_node_01            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_02            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_03            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_04            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Note that each managed node is running a different GNU/Linux distribution.

Speed up tip

When we execute a playbook, each play`_ runs a hidden task, named Gathering Facts. For example,

cd facts &&
ansible-playbook \
--ask-vault-pass \
-i inventories/production.yml \
--extra-vars @vault/production \
playbook-with-multi-play.yaml

Note

The password for the vault used in the example is 123. You must use a strong passwords, for example, a minimum of 8 randomly generated characters.

returns

PLAY [Display facts] ***********************************************************

TASK [Gathering Facts] *********************************************************
ok: [managed_node_02]
ok: [managed_node_03]
ok: [managed_node_04]
ok: [managed_node_01]

TASK [Display GNU/Linux distribution] ******************************************
ok: [managed_node_01] => {
    "msg": "Alpine"
}
ok: [managed_node_02] => {
    "msg": "Debian"
}
ok: [managed_node_03] => {
    "msg": "Ubuntu"
}
ok: [managed_node_04] => {
    "msg": "Fedora"
}

PLAY [Display more facts] ******************************************************

TASK [Gathering Facts] *********************************************************
ok: [managed_node_02]
ok: [managed_node_01]
ok: [managed_node_03]
ok: [managed_node_04]

TASK [Display GNU/Linux distribution version] **********************************
ok: [managed_node_01] => {
    "msg": "3.21.3"
}
ok: [managed_node_02] => {
    "msg": "12.10"
}
ok: [managed_node_03] => {
    "msg": "25.04"
}
ok: [managed_node_04] => {
    "msg": "42"
}

PLAY RECAP *********************************************************************
managed_node_01            : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_02            : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_03            : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
managed_node_04            : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Because of this, a tip to speed up the execution of a playbook is to disable the Gathering Facts task for a play using the gather_facts keyword. It is important to remember that the use of a fact without gathering will result in a failed exection of the playbook. For example,

cd facts &&
ansible-playbook \
--ask-vault-pass \
-i inventories/production.yml \
--extra-vars @vault/production \
playbook-without-facts.yaml

Note

The password for the vault used in the example is 123. You must use a strong passwords, for example, a minimum of 8 randomly generated characters.

returns

PLAY [Display facts] ***********************************************************

TASK [Display GNU/Linux distribution] ******************************************
fatal: [managed_node_01]: FAILED! => {"msg": "The task includes an option with an undefined variable.. 'ansible_distribution' is undefined\n\nThe error appears to be in '/home/ansible/tutorial/facts/playbook-without-facts.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Display GNU/Linux distribution\n      ^ here\n"}
fatal: [managed_node_02]: FAILED! => {"msg": "The task includes an option with an undefined variable.. 'ansible_distribution' is undefined\n\nThe error appears to be in '/home/ansible/tutorial/facts/playbook-without-facts.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Display GNU/Linux distribution\n      ^ here\n"}
fatal: [managed_node_03]: FAILED! => {"msg": "The task includes an option with an undefined variable.. 'ansible_distribution' is undefined\n\nThe error appears to be in '/home/ansible/tutorial/facts/playbook-without-facts.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Display GNU/Linux distribution\n      ^ here\n"}
fatal: [managed_node_04]: FAILED! => {"msg": "The task includes an option with an undefined variable.. 'ansible_distribution' is undefined\n\nThe error appears to be in '/home/ansible/tutorial/facts/playbook-without-facts.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: Display GNU/Linux distribution\n      ^ here\n"}

PLAY RECAP *********************************************************************
managed_node_01            : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
managed_node_02            : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
managed_node_03            : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
managed_node_04            : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0