top of page

Ansible Facts & Conditional Execution

Ansible facts are information about a host which ansible automatically gathers. It contains information about a host like IP Address, Partition details, Server architecture, ethernet card details, mac address etc...

These are very useful details when you want to write a conditional base playbook looking at its remote server configuration. For e.g If you have different kind of OS flavor servers like Centos & Ubuntu in single inventory group then while running automation through playbook, You may need to take a conditional call to install or perform a task accordingly.


How to retrieve all ansible facts using ad-hoc ?


You can use ansible setup module to capture all variable facts. So lets see how to use this usnig ad-hoc.

[root@siddhesh ~]# ansible dbserver -m setup
node2.tecgeek.info | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.51.75"
        ],
        "ansible_all_ipv6_addresses": [],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "12/01/2006",
        "ansible_bios_version": "VirtualBox",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-693.2.2.el7.x86_64",
            "biosdevname": "0",
            "crashkernel": "auto",
            "net.ifnames": "0",
            "quiet": true,
            "rhgb": true,
            "ro": true,
            "root": "UUID=e5dae63e-08a4-43e7-9766-2d51cc71a772",
            "selinux": "0"
        },
....Output Truncate 
node1.tecgeek.info | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.30.1"
        ],
        "ansible_all_ipv6_addresses": [],
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "12/01/2006",
        "ansible_bios_version": "VirtualBox",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-693.2.2.el7.x86_64",
            "biosdevname": "0",
            "crashkernel": "auto",
            "net.ifnames": "0",
            "quiet": true,
            "rd.lvm.lv": "cl/swap",
            "rhgb": true,
            "ro": true,
            "root": "/dev/mapper/cl-root",
            "selinux": "0"
        },
[root@siddhesh ~]#

Here :

dbserver ==> Host Inventory Group. -m setup ==> Module gathers facts about remote hosts

From above output you can see that it capture most of all systems facts of remote servers.

I have truncate output of this command while pasting here as its content around 400 lines of report per host.


How to capture specific facts of remote servers ?

In some cases you want to pull a report of specific facts of remote server. Before making any final call through ansible playbook. This method can be used to fulfill your requirement of audit.

So in below example I going to capture following details from my remote servers.

1. Remote Server MAC Address. 2. Remote Server Architecture. 3. Remote Server Kernel Details.

[root@siddhesh ~]# cat facts.yml
- hosts: dbserver
  gather_facts: true
  tasks:
    - name: Ansible fact for mac address
      debug:
        msg: "Remote Server IP Address: {{ ansible_default_ipv4.macaddress }}  System Arch: {{ ansible_architecture }} System Kernel : {{ ansible_kernel }}"
[root@siddhesh ~]#

Here :

ansible_default_ipv4.macaddress ==> To get mac address.

ansible_architecture ==> To get system architecture details.

ansible_kernel ==> To get kernel release details.

Lets run this playbook to see if it is generating required output.

[root@siddhesh ~]# ansible-playbook facts.yml

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node2.tecgeek.info]
ok: [node1.tecgeek.info]

TASK [Ansible fact for mac address] *********************************************************************************************************************************
ok: [node1.tecgeek.info] => {
    "msg": "Remote Server IP Address: 08:00:27:35:d2:a3  System Arch: x86_64 System Kernel : 3.10.0-693.2.2.el7.x86_64"
}
ok: [node2.tecgeek.info] => {
    "msg": "Remote Server IP Address: 08:00:27:fd:fa:07  System Arch: x86_64 System Kernel : 3.10.0-693.2.2.el7.x86_64"
}

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=2    changed=0    unreachable=0    failed=0
node2.tecgeek.info         : ok=2    changed=0    unreachable=0    failed=0
[root@siddhesh ~]#

So as you can see here that we have capture all required details from remote server. By using this method you can capture a lots of facts from remote server to monitor or to take a call of deployment any specific package or changes.


How to put conditional statement using facts ?


So far we have saw that how to capture facts, Now lets see how to use this module to do an automation using conditional statement. In this scenario I am going to install package wget only if it matches mac address to 08:00:27:35:d2:a3.

[root@siddhesh ~]# cat factscondition.yml
- hosts: dbserver
  tasks:
    - name: conditional facts check
      when: ansible_default_ipv4.macaddress == "08:00:27:35:d2:a3"
      package:
        name: wget
        state: latest
[root@siddhesh ~]#

Here :

when: ansible_default_ipv4.macaddress == "08:00:27:35:d2:a3" ==> will match if remote server having mac address of 08:00:27:35:d2:a3

So lets run this playbook and see if it works.

[root@siddhesh ~]# ansible-playbook factscondition.yml

PLAY [dbserver] *****************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************
ok: [node1.tecgeek.info]
ok: [node2.tecgeek.info]

TASK [conditional facts check] **************************************************************************************************************************************
skipping: [node2.tecgeek.info]
changed: [node1.tecgeek.info]

PLAY RECAP **********************************************************************************************************************************************************
node1.tecgeek.info         : ok=2    changed=1    unreachable=0    failed=0
node2.tecgeek.info         : ok=1    changed=0    unreachable=0    failed=0
[root@siddhesh ~]# 

As you can see, task execution of installing wget package got skipped on node2 as it didn't matches the mac address which we have defined under playbook. So you can use same method to put on various conditions to check prior to execute any task.

bottom of page