Skip to content

Build Status


Lab 005 - Facts

  • In this section, we will cover Ansible Facts.
  • Ansible facts are essentially “Ansible Scripts” and constitute one of the building blocks of Ansible.
  • Ansible facts are data corresponding to your remote systems, which includes operating systems, IP addresses, attached filesystems, and more.
  • Ansible facts are gathered, and relate to target nodes (host nodes to be configured). They are returned back to the controller node.

01. How to View Facts?

  • Ansible gathers facts about remote systems using the setup module.
  • You can view facts of a remote machine by running the following command:

    ansible all -m setup
    

  • Example Output (Truncated for brevity):

    {
      "ansible_facts": {
          "ansible_distribution": "Ubuntu",
          "ansible_distribution_version": "22.04",
          "ansible_architecture": "x86_64",
          "ansible_memory_mb": {
              "real": {
                  "total": 7989,
                  "used": 2034
              }
          },
          "ansible_default_ipv4": {
              "address": "192.168.1.10",
              "netmask": "255.255.255.0",
              "gateway": "192.168.1.1"
          }
      }
    }
    


02. How to use facts in playbooks?

  • Facts allow you to base your playbook logic on the properties of the target hosts.
  • All facts are prefixed with ansible_x.
  • For example, to access the operating system distribution of a host, you would use ansible_distribution.
  • Here are some examples of how to use facts in playbooks:


Example: Installing Packages Based on OS

---
- hosts: all
  tasks:
    - name: Install Nginx on Debian using APT
      ansible.builtin.apt:
        name: nginx
        state: present
      when: ansible_distribution == "Ubuntu"

    - name: Install Nginx on RedHat using DNF
      ansible.builtin.dnf:
        name: nginx
        state: present
      when: ansible_distribution == "CentOS"

Example: Conditional execution based on memory

- name: Restart Service if Memory is Low
  ansible.builtin.service:
    name: my_service
    state: restarted
  when: ansible_memory_mb.real.total < 4000

03. Commonly used facts

System Information

Fact Description
ansible_distribution OS name (Ubuntu, CentOS, Windows)
ansible_distribution_version OS version (22.04, 9.1, 10)
ansible_architecture System architecture (x86_64, arm)
ansible_hostname Hostname of the machine
ansible_os_family OS family (Debian, RedHat, Windows)
ansible_facts All gathered facts

Networking

Fact Description
ansible_default_ipv4.address Default IP address
ansible_default_ipv4.gateway Default gateway
ansible_fqdn Fully Qualified Domain Name
ansible_dns.nameservers DNS servers

Hardware

Fact Description
ansible_memory_mb.real.total Total RAM in MB
ansible_processor_count Number of CPUs
ansible_processor_cores Number of CPU cores

User-defined Facts

Fact Description
ansible_user Current user
ansible_group Current group

04. Disabling fact gathering

  • By default, Ansible gathers facts before running a playbook.
  • In order to disable it, add the following at the beginning of your playbook:
  • To disable fact gathering, set gather_facts to no in your playbook:
- hosts: all
  gather_facts: no
  tasks:
    - name: Print a message
      debug:
        msg: "Facts gathering is disabled!"

05. Custom Facts

  • You can define custom facts by creating .fact files, placing them inside /etc/ansible/facts.d/ directory on the managed host.

Example: Creating a custom fact

  • Create the file /etc/ansible/facts.d/custom.fact with:

    [custom]
    environment=production
    app_version=1.2.3
    
  • Retrieve the fact in a playbook:

    - hosts: all
      tasks:
        - debug:
            msg: "App version is {{ ansible_local.custom.app_version }}"
    

Using Custom Facts

  • Another way to define your own custom facts using the set_fact module in your playbooks.
  • Here is an example:

    - hosts: all
      tasks:
        - name: Set custom fact
          ansible.builtin.set_fact:
            my_custom_fact: "Hello, Ansible!"
        - name: Print custom fact
          debug:
            msg: "{{ my_custom_fact }}"
    

06. Hands-on


  • Use the setup module to gather and print all facts from linux-server-1.

    Solution

    ansible linux-server-1 -m setup
    
  • Use the setup module to gather and print only the network-related facts from linux-server-2.

    Solution

    ansible linux-server-2 -m setup -a "filter=ansible_default_ipv4*"
    

  • Create a playbook that installs nginx only if the target host is running Ubuntu.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Install nginx on Ubuntu
          ansible.builtin.apt:
            name: nginx
            state: present
          when: ansible_distribution == "Ubuntu"
    
  • Create a playbook that restarts a service only if the host has less than 4GB of RAM.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Restart service if memory low
          ansible.builtin.service:
            name: my_service
            state: restarted
          when: ansible_memory_mb.real.total < 4096
    

  • Create a custom fact that defines the environment as development and print it in a playbook.

    Solution

    First, create /etc/ansible/facts.d/custom.fact on the host:

    [custom]
    environment=development
    

    Then playbook:

    ---
    - hosts: all
      tasks:
        - debug:
            msg: "Environment is {{ ansible_local.custom.environment }}"
    

  • Create a playbook that sets a custom fact deployment_stage to staging and prints it.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Set custom fact
          ansible.builtin.set_fact:
            deployment_stage: staging
        - name: Print custom fact
          debug:
            msg: "Deployment stage: {{ deployment_stage }}"
    

  • Disable fact gathering in a playbook and print a message indicating that facts are not gathered.

    Solution

    ---
    - hosts: all
      gather_facts: no
      tasks:
        - name: Print message
          debug:
            msg: "Facts gathering is disabled!"
    
  • Create a playbook that prints the hostname of each target host using the appropriate fact.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Print hostname
          debug:
            msg: "Hostname: {{ ansible_hostname }}"
    

  • Create a playbook that checks the OS family and installs a package accordingly (e.g., nginx for Debian, httpd for RedHat).

    Solution

    ---
    - hosts: all
      tasks:
        - name: Install nginx on Debian
          ansible.builtin.apt:
            name: nginx
            state: present
          when: ansible_os_family == "Debian"
        - name: Install httpd on RedHat
          ansible.builtin.dnf:
            name: httpd
            state: present
          when: ansible_os_family == "RedHat"
    
  • Create a playbook that gathers facts and prints the total memory of each host.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Print total memory
          debug:
            msg: "Total memory: {{ ansible_memory_mb.real.total }} MB"
    

  • Create a playbook that checks the default gateway and prints it.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Print default gateway
          debug:
            msg: "Default gateway: {{ ansible_default_ipv4.gateway }}"
    

  • Create a playbook that sets a custom fact backup_required to yes and prints a message if backup is required.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Set custom fact
          ansible.builtin.set_fact:
            backup_required: yes
        - name: Print message if backup required
          debug:
            msg: "Backup is required"
          when: backup_required == "yes"
    

  • Create a playbook that uses the ansible_user fact to print the current user on each host.

    Solution

    ---
    - hosts: all
      tasks:
        - name: Print current user
          debug:
            msg: "Current user: {{ ansible_user }}"
    
  • Print the IP addresses of all the machines.

    Solution

    ansible all -m setup -a "filter=ansible_default_ipv4.address"
    

  • Bonus - Try printing the address of linux-server-2 only, without modifying the inventory file.

    Solution

    ansible linux-server-2 -m setup -a "filter=ansible_default_ipv4.address"
    

07. Summary

🔹 Ansible facts provide system details dynamically.
🔹 They are automatically gathered using the setup module.
🔹 They are useful for conditional logic in playbooks.
🔹 Facts may include OS, networking, CPU, memory and more.
🔹 Custom facts can be created for customized automation.