One of the cornerstones of Ansible’s power is its ability to use variables which can use to store an information and reference it throughout playbooks, roles, and templates.
Nested variables in Ansible refer to the feature of defining a variable within another variable. These can help simplify and structure your data, making Ansible playbooks more readable and manageable.
This tutorial teaches us how to work with nested variables in Ansible YAML definitions. This includes how to define the nested variables and how to access them.
What Are Ansible Nested Variables?
Let us start by defining what the Ansible nested variables are.
We can define the variables such as strings, integers, Boolean, and other complex data structures such as dictionaries and lists in Ansible. A list or a dictionary is an example of a nested variable.
The main role of nested variables is organizing the data more hierarchically which is easier to read and maintain.
Nested variables also provide a highly efficient method of dynamically referring a sub-value based on another variable’s value.
Create Nested Variables
We can use the YAML syntax to define and initialize the nested variables in Ansible. An example is as follows:
linuxhint:
uid: 1001
shell: "/bin/bash"
admin:
uid: 1002
shell: "/bin/zsh"
In the given example, we define a dictionary called “users” with two other nested dictionaries for the Linuxhint and the admin users.
Reference the Nested Variables
We can reference the nested variables in Ansible using the dot or bracket notation. Consider the following example:
msg: "{{ users.linuxhint.shell }}"
In this case, we use the dot notation to access the value of the shell key from the “linuxhint” dictionary that is nested inside the “users” dictionary.
Bracket notation is also very useful when referencing a variable dynamically. An example is as follows:
selected_user: "linuxhint"
- debug:
msg: "{{ users[selected_user].shell }}"
This feches the value of the defined key.
Setting the Ansible Nested Variables
We can set the nested variables in the inventory file, in an Ansible playbook, or via the included files in Ansible.
Let us look at various examples of defining the nested variables in each.
Creating Nested Variables in an Ansible Inventory File
The following example shows how to create the nested variables in an Ansible inventory file:
webserver1 ansible_host=192.168.1.10
[web:vars]
databases:
db1: "postgresql"
db2: "mysql"
As you can see, we include two nested variables inside the database group.
Creating Nested Variables in Ansible Playbook
We can also define the nested variables in a playbook as demonstrated in the following provided example:
- hosts: web
vars:
configs:
nginx:
port: 80
apache:
port: 8080
tasks:
- name: Print apache port
debug:
msg: "{{ configs.apache.port }}"
Looping Over Nested Variables
Ansible also allows us to iterate over nested variables as demonstrated in the following playbook example:
vars:
services:
nginx:
port: 80
state: started
apache:
port: 8080
state: stopped
tasks:
- name: Ensure services are in the desired state
service:
name: "{{ item.key }}"
state: "{{ item.value.state }}"
with_dict: "{{ services }}"
The given example should iterate over each service and ensure it’s in the desired state.
Conclusion
We explored Ansible’s functionality of defining and referencing the nested variables to provide a powerful way of organizing and structuring the data for configuration management.