Ansible Facts: How to Gather and Use Them Seamlessly

Ansible Facts Example

Ansible facts are pieces of information about the remote system that Ansible gathers before executing tasks in a playbook. These facts, stored as variables, provide details about the system’s hardware, network configuration, OS, and much more.

This guide will explain how to gather Ansible facts, and use them in your playbooks. Let’s dive in!

What Are Ansible Facts?

Ansible facts are system properties collected by the setup module, which runs automatically during playbook execution. These facts provide critical details about the managed nodes, such as:

  • IP addresses
  • Hostname
  • Memory
  • Disk space
  • OS type and version
  • User details

Facts are stored as variables and can be accessed throughout your playbook. This enables dynamic behavior in tasks, such as deploying software only on specific OS types or tailoring configurations to system properties.

How to Gather Facts in Ansible

By default, Ansible automatically gathers facts about a target system at the beginning of each playbook execution. This is enabled by the gather_facts option in a playbook.

Example: Default Fact Gathering

- name: Gather facts example
  hosts: all
  gather_facts: yes
  tasks:
    - name: Display gathered facts
      debug:
        var: ansible_facts

When this playbook is executed, Ansible will collect facts using the setup module. You can also manually invoke the setup module to gather facts.

Here is the example playbook:

- name: Gather facts using the setup module
  hosts: all
  tasks:
    - name: Gather facts
      ansible.builtin.setup:
    - name: Display OS version
      debug:
        var: ansible_facts['distribution_version']

This playbook gathers system facts using the setup module and displays the operating system version.

Accessing and Using Ansible Facts

Facts are stored as variables in the ansible_facts dictionary. For example, you can access the hostname with ansible_facts[‘hostname’] or the IP address of a specific interface with ansible_facts[‘interfaces’][0][‘ipv4’][‘address’].

Example: Accessing Specific Facts

- name: Access specific facts
  hosts: all
  tasks:
    - name: Display hostname
      debug:
        var: ansible_facts['hostname']
    - name: Display operating system
      debug:
        var: ansible_facts['distribution']

This playbook retrieves and displays the system’s hostname and operating system name by accessing specific facts from ansible_facts.

Customizing Fact Gathering

Sometimes, gathering all facts can be time-consuming. You can customize the process to gather only specific types of facts.

Example: Restricting Fact Gathering

- name: Gather specific facts
  hosts: all
  tasks:
    - name: Gather network-related facts only
      ansible.builtin.setup:
        gather_subset:
          - '!all'
          - 'network'
    - name: Display network facts
      debug:
        var: ansible_facts['interfaces']

In this example, only network-related facts are collected, improving performance.

Using Facts in Playbooks

You can use facts to create dynamic playbooks by incorporating conditionals, loops, and templates.

Example 1: Conditional Tasks Based on Facts

- name: Install packages based on OS
  hosts: all
  tasks:
    - name: Install httpd on RedHat-based systems
      yum:
        name: httpd
        state: present
      when: ansible_facts['distribution'] == "RedHat"
    - name: Install apache2 on Debian-based systems
      apt:
        name: apache2
        state: present
      when: ansible_facts['distribution'] == "Debian"

This playbook installs httpd on RedHat-based systems using yum and apache2 on Debian-based systems using apt, based on the value of the ansible_facts[‘distribution’] fact.

Example 2: Using Facts in Templates

Templates can use facts to generate configuration files dynamically.

Here is a template file nginx.conf.j2:

server {
    listen {{ ansible_facts['interfaces'][0]['ipv4']['address'] }};
    server_name {{ ansible_facts['hostname'] }};
}

Create a playbook using the above template:

- name: Configure NGINX with facts
  hosts: all
  tasks:
    - name: Deploy NGINX configuration
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf

This playbook uses the template module to deploy the nginx.conf.j2 file, dynamically populating it with facts such as the IP address and hostname.

Conclusion

Ansible facts are handy features that can transform how you automate infrastructure tasks. By dynamically adapting to the properties of the target systems, you can write flexible, efficient, and reusable playbooks.

Try these techniques in your next playbook, and you’ll see how much smoother and smarter your automation becomes.

FAQs

1. Can I disable fact gathering in Ansible?

Yes, you can disable fact gathering by setting gather_facts: no in your playbook.

2. How do I cache facts in Ansible?

Enable fact caching by configuring the fact_caching parameter in the Ansible configuration file.

3. Can Ansible facts be used with roles?

Yes, facts are globally available in playbooks and roles, making them suitable for role-based task execution and configurations.

About Hitesh Jethva

I am Hitesh Jethva, Founder and Author at Code2DevOps.com. With over 15 years of experience in DevOps and open source technologies, I am passionate about empowering teams through automation, continuous integration, and scalable solutions.

View all posts by Hitesh Jethva