Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How To Work With Ansible Variables And Facts?
Ansible is a widely-used open-source tool that helps in automating software provisioning, configuration management, and application deployment. One of its powerful features is the ability to use variables and facts, which can simplify your playbooks and tasks, and allow you to design more dynamic, flexible, and reusable automation scripts.
In this article, we'll dive into how to work with Ansible variables and facts, showcasing several examples and their corresponding output.
Understanding Ansible Variables
Variables in Ansible allow for the storage and manipulation of values, which can be utilized across multiple tasks or even different playbooks. Variables can be defined in various locations, and their scope is mainly determined by where they are defined.
Defining Variables
There are many ways to define variables in Ansible
In a Playbook Here's an example of how you can define a variable within a playbook
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
tasks:
- name: Ensure Apache is at the latest version
yum:
name: httpd
state: latest
In this playbook, the variables http_port and max_clients are defined and can be used in any tasks within this playbook.
In the Inventory File Variables can also be defined in the inventory file
[webservers] server1 ansible_host=192.168.1.10 http_port=80 max_clients=200
In this inventory file, http_port and max_clients are defined for server1.
Using Variables
You can utilize these variables in tasks or templates by enclosing them in double curly braces. Here's an example
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
tasks:
- name: Ensure Apache is configured with vars
template:
src: /etc/httpd/conf/httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
In the template file, you would reference these variables like this
Listen {{ http_port }}
MaxClients {{ max_clients }}
Understanding Ansible Facts
Ansible facts are pieces of information obtained from the target system, such as network interfaces, OS details, IP addresses, etc. These facts are stored in variables and can be used in playbooks.
Ansible uses a module called setup to gather facts. If you want to see what facts Ansible gathers about a system, run the following command
ansible -m setup hostname
Replace hostname with the name or IP of the host you want to target. The output will be a JSON document that lists all the facts gathered for that host.
Here's an example of using facts in a task
---
- hosts: webservers
tasks:
- name: Display OS family
debug:
msg: "The operating system family is {{ ansible_os_family }}"
In this example, ansible_os_family is a fact that gives the OS family of the target system.
Organizing Variables
As you scale your Ansible usage, you might find that you're dealing with a large number of variables. In such scenarios, it's advisable to manage your variables in dedicated files or even directories.
In Separate Variables Files You can define variables in separate files and then include those files in your playbooks like so:
---
- hosts: webservers
vars_files:
- vars/apache.yml
tasks:
- name: Ensure Apache is at the latest version
yum:
name: httpd
state: latest
In vars/apache.yml, you might define the variables like this
--- http_port: 80 max_clients: 200
In a Directory For even better organization, especially for larger projects, you can store variables in a directory structure.
---
- hosts: webservers
vars_files:
- vars/apache.yml
- vars/directory/extra_vars.yml
tasks:
- name: Ensure Apache is at the latest version
yum:
name: httpd
state: latest
Advanced Variable Usage: Facts Caching
One of the powerful features of Ansible is the ability to cache facts. This is especially useful when you're working with a large inventory or when you want to use gathered facts in multiple playbooks without re-gathering them every time.
To enable fact caching, you need to set the following parameters in your ansible.cfg file
[defaults] gathering = smart fact_caching = jsonfile fact_caching_connection = /tmp/ansible_facts fact_caching_timeout = 7200
With this configuration, Ansible will cache gathered facts in the /tmp/ansible_facts directory and will not re-gather them for 7200 seconds (2 hours).
This example demonstrates how to access cached facts
---
- hosts: webservers
tasks:
- name: Display cached OS family
debug:
msg: "The cached operating system family is {{ ansible_os_family }}"
Variable Precedence
In Ansible, there are many ways to set variables, and it's crucial to understand the order in which they are evaluated. This order, known as variable precedence, allows you to control the final value of a variable.
Variable Types
Apart from the standard variables, Ansible offers several special variable types that can be very helpful. These include
List Variables This type allows you to create a list (array) of values.
fruits: - Apple - Banana - Orange
Dictionary Variables This type enables the storage of more complex data structures.
user: name: John Doe job: Developer
Boolean Variables They are used for storing True/False values.
debug_mode: True
Accessing Complex Variables
For list and dictionary variables, you can access individual elements by their index or key. For example
---
- hosts: localhost
gather_facts: no
vars:
fruits:
- Apple
- Banana
- Orange
user:
name: John Doe
job: Developer
tasks:
- debug:
msg: "The first fruit in the list is {{ fruits[0] }}"
- debug:
msg: "The user's job is {{ user['job'] }}"
The above playbook will output
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "The first fruit in the list is Apple"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "The user's job is Developer"
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Using Filters with Variables
Filters in Ansible can manipulate variables. They are used in conjunction with the | character. For instance, the default filter can be used to assign a default value to a variable if it is not defined
---
- hosts: localhost
gather_facts: no
vars:
var1: "Hello"
tasks:
- debug:
msg: "{{ var1 | default('Hi') }}"
- debug:
msg: "{{ var2 | default('Hi') }}"
The above playbook will output
PLAY [localhost] ***************************************************************
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Hello"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "Hi"
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In the first debug task, var1 is defined, so the default filter does not change its value. In the second task, var2 is not defined, so the default filter assigns it the value 'Hi'.
Conclusion
Ansible variables and facts are fundamental building blocks for creating dynamic, flexible automation scripts. From basic variable definitions to advanced concepts like fact caching and variable precedence, understanding these mechanisms enables you to write more efficient and reusable playbooks that adapt to different environments and requirements.
