How to Create and Use Custom Fact Variables in Ansible
Charanjit Singh Cheema
Cloud Architect | Expert in Linux Systems, Ansible, Terraform Automation, and Cloud Solutions | Proven Leadership in Global IT Projects
In Ansible, fact variables are dynamically gathered data about the managed hosts. Ansible collects these variables, known as "facts," by using its setup module, which gathers details like OS type, network settings, hardware details, and more. You can also create custom fact variables to store specific information or perform calculations to use in your playbooks, enhancing automation flexibility.
In this guide, I’ll walk you through understanding fact variables and creating custom facts in Ansible.
?
Lab Setup
To demonstrate the usage of Ansible’s built-in fact variables and the creation of custom fact variables, I’ve set up a lab environment using Ubuntu Linux on Oracle VirtualBox. The setup includes:
The Ansible Master (ubuntu-vm1) is used to run playbooks on the other Ubuntu machines (ubuntu-vm2 and ubuntu-vm3).
Note: You can find the Ansible Playbook codes referenced in this article at my GitHub link: https://github.com/cjcheema/my_ansible_project
?
Understanding Built-in Facts
Ansible automatically collects system information from managed hosts when a playbook runs, storing them in built-in facts. For example, facts like ansible_hostname, ansible_os_family, and ansible_processor_count give details about the system. To see all built-in facts, you can run the following command:
ansible localhost -m setup
This will output JSON data containing all gathered facts for the localhost.
Using Built-in Facts
You can reference these built-in facts within your playbooks to make tasks conditional or to configure resources based on system properties. Here’s an example:
- name: Example of using built-in facts
? hosts: all
? tasks:
??? - name: Print the operating system family
????? debug:
??????? msg: "Operating system family is {{ ansible_os_family }}."
Creating Custom Fact Variables
Custom facts allow you to define additional facts that might be specific to your infrastructure, environment, or application requirements. Custom facts can be created in two main ways:
Method 1: Defining Custom Facts in Playbooks
You can define custom facts directly in playbooks using set_fact, which makes them available during the playbook's execution.
- name: Create custom fact variables
? hosts: Production
? tasks:
??? - name: Set custom fact for application environment
????? set_fact:
??????? app_environment: "production"
??????? app_version: "v1.2.3"?
- name: Display custom fact variables
????? debug:
??????? msg: "App Environment: {{ app_environment }}, Version: {{ app_version }}"
In this example:
Method 2: Creating Custom Facts on Managed Hosts
Another approach is to place custom fact files on managed hosts. These files reside in the /etc/ansible/facts.d directory on each managed host and are written in JSON or INI format.
sudo mkdir -p /etc/ansible/facts.d
echo '{"app_environment": "production", "app_version": "v1.2.3"}' | sudo tee /etc/ansible/facts.d/custom_app.fact
领英推荐
- name: Using custom facts from managed host
? hosts: Production
? tasks:
??? - name: Display custom facts
????? debug:
??????? msg: "App Environment: {{ ansible_local.custom_app.app_environment }}, Version: {{ ansible_local.custom_app.app_version }}"
In this case:
Using Conditional Statements with Custom Facts
Custom facts can be used in conditional statements to change task behavior based on the facts' values.
- name: Install packages based on app environment
? hosts: all
? become: yes
? tasks:
??? - name: Set custom app environment fact
????? set_fact:
??????? app_environment: "{{ app_env_var }}"
??? - name: Install production package
????? apt:
??????? name: apache2
??????? state: present
????? when: inventory_hostname in groups['Production'] and app_environment == "production"
??? - name: Install development package
????? apt:
??????? name: nginx
??????? state: present
????? when: inventory_hostname in groups['Development'] and app_environment == "development"
How to execute this playbook:
ansible-playbook your_playbook.yml -e "app_env_var=production"
ansible-playbook your_playbook.yml -e "app_env_var=development"
?
Explanation of this playbook:
Creating Complex Facts with Jinja2
You can use Jinja2 expressions in set_fact to calculate values for custom facts. This allows for dynamically calculated facts that update based on other variables or facts in real-time.
- name: Create complex custom facts with Jinja2
? hosts: all
? tasks:
??? - name: Set server tier fact based on vCPU count
????? set_fact:
??????? server_tier: "{{ 'high' if ansible_processor_vcpus > 1 else 'standard' }}"
??? - name: Print server tier
????? debug:
??????? msg: "This server is classified as {{ server_tier }} tier based on vCPU count."
In this example:
?
Registering Facts in Ansible for Later Use
You can use the register module to capture the output of a task and save it as a fact. This is helpful for dynamically created information, like command outputs or file contents.
- name: Register custom fact from command output
? hosts: all
? tasks:
??? - name: Get uptime information
????? command: uptime
????? register: uptime_info
??? - name: Print uptime
????? debug:
??????? msg: "The server uptime is: {{ uptime_info.stdout }}"
?
Wrap Up!
This approach to using both built-in and custom facts in Ansible enhances flexibility, making automation more adaptable to specific needs and conditions.
Well done, thanks.
(RHCSA | CKA | TCA | EX374 ) I am always Interested in contributing meaningfully to simplify repetitive tasks.
4 个月Its helpful
Director @ Kyndryl India | Executive Leadership, Cloud Migration, Dark Data enthusiast, DEI Advocate, Wellness Advocate, POSH Champion
4 个月Good one. Continue to publish Charanjit Singh Cheema
Delivery Leader at Kyndryl
4 个月Charanjit Singh Cheema another good one