0 Basic idea
Before running any task on a managed node, ansible first tries to detect the state of the targeted machine. What's detected is called a "fact", all the "fact" collected is called "facts". Some common facts are the hostname, OS type, IP addresses, disks, and file systems.
As a result, the following tasks can run conditionally based on these "facts". For example, a task may run differently on a Linux node and a Solaris node.
1 module "setup"
In Ansible, every task is implemented by a module. Collecting facts is not an exception. The module used by Ansible to collect facts is named "setup". By default, before running any playbook ansible-playbook runs the "setup" module first. So "setup" can be the most common task at all.
So we can always see ansible-playbook printing the following message.
TASK [Gathering Facts] ****************************
Now that "setup" is a module, we can also run it by ansible command.
$ ansible localhost -m setup
localhost | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.100.1",
"192.168.42.1",
"192.168.122.1",
"192.168.0.31",
"192.168.121.1"
],
...
The output can be very long depending on the configuration of the managed node.
From the output, we can at least know that the collected facts are saved as a python dictionary type variable called "ansible_facts".
2. How to use facts?
As facts are saved as a variable named "ansible_facts", it can be used like any other variable in a playbook.
2.1 print the facts
Sometimes, printing facts is important for us to monitor the managed nodes. We can use "debug" module to print out any fact(s) collected.
---
- hosts: localhost
tasks:
- name: print firt IP address
debug: var=ansible_facts.all_ipv4_addresses[0]
- name: print hostname
debug: var=ansible_facts.hostname
- name: print CPU cores
debug: var=ansible_facts.processor_cores
Note: the var parameter of the debug module already runs in JinJa2 context and has an implicit {{ }} wrapping, so no JinJa2 delimiters here.
$ ansible-playbook playbook.yml
PLAY [localhost] *******************************************************************************************
TASK [Gathering Facts] *************************************************************************************
ok: [localhost]
TASK [print firt IP address] *******************************************************************************
ok: [localhost] => {
"ansible_facts.all_ipv4_addresses[0]": "192.168.100.1"
}
TASK [print hostname] **************************************************************************************
ok: [localhost] => {
"ansible_facts.hostname": "cf-31"
}
TASK [print CPU cores] *************************************************************************************
ok: [localhost] => {
"ansible_facts.processor_cores": "2"
}
PLAY RECAP *************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.2 conditionally run tasks based on facts
In this example, the first task only runs on CentOS 7.7 nodes.
- hosts: home
tasks:
- name: "run this task only on CentOS 7.7"
shell: "cat /etc/os-release"
register: r
when: "'CentOS' in ansible_facts.distribution and '7.7' in ansible_facts.distribution_version"
- debug: var=r.stdout
Note: "when" runs in JinJa2 context and has an implicit {{}} wrapping, so no JinJa2 delimiters here.
No comments:
Post a Comment