In Ansible, a dictionary (also known as a hash, map, or associative array) is a data type that allows you to store and manipulate key-value pairs.
Dictionaries are commonly used to represent configuration data, variables, and other structured information in Ansible playbooks.
A dictionary in Ansible is enclosed in curly braces {} and consists of key-value pairs separated by colons :.
Keys are strings, and values can be of any data type, including strings, numbers, lists, or even nested dictionaries.
Get Your Free Linux training!
Join our free Linux training and discover the power of open-source technology. Enhance your skills and boost your career! Learn Linux for Free!Dictionaries are commonly used in tasks and playbooks to pass and manipulate data, configure tasks, and conditionally execute tasks based on the values of certain keys.
They provide a flexible and powerful way to store and manage structured data in Ansible, allowing you to customize the behavior of your playbooks based on dynamic input.
Here’s an example of a dictionary in Ansible:
--- - name: Configure Users hosts: localhost gather_facts: no tasks: - name: Create dictionary of users set_fact: users: user1: name: jdoe uid: 1001 state: present user2: name: jsmith uid: 1002 state: absent user3: name: jbrown uid: 1003 state: present
In this example, a dictionary called users is defined using the set_fact module. The users dictionary contains three users, each represented as a key-value pair, with the key as the username and the value as a dictionary containing the user’s properties such as name, uid, and state.
Table of Contents
how to check if a variable is a dict in ansible?
In Ansible, you can use the type_debug filter to check if a variable is a dictionary. Here’s an example:
--- - name: Check if Variable is a Dictionary hosts: localhost gather_facts: no vars: var1: key1: value1 key2: value2 var2: "Not a dictionary" tasks: - name: Check if var1 is a dictionary debug: msg: "var1 is a dictionary." when: "'dict' in (var1|type_debug)" - name: Check if var2 is a dictionary debug: msg: "var2 is not a dictionary." when: "'dict' not in (var2|type_debug)"
In this example, we define two variables var1 and var2, where var1 is a dictionary and var2 is a string. We then use the type_debug filter in combination with the in and not in operators to check the type of each variable.
In the first task, we use the when condition to check if var1 is a dictionary by checking if the string ‘dict’ is present in the output of (var1|type_debug). If it is, the task will display a message saying “var1 is a dictionary.”
In the second task, we use the when condition to check if var2 is not a dictionary by checking if the string ‘dict’ is not present in the output of (var2|type_debug). If it is not, the task will display a message saying “var2 is not a dictionary.”
Define a dict using the vars section in Ansible playbook
There are a few methods to create dictionaries in Ansible.
we can define a dictionary using the vars section in your playbook. Here’s an simple example:
--- - name: Define a Simple Dictionary hosts: localhost gather_facts: no vars: my_dict: key1: value1 key2: value2 key3: value3 tasks: - name: Display the Dictionary debug: var: my_dict - name: Display the keys in Dictionary debug: var: my_dict.keys() - name: Display the values in Dictionary debug: var: my_dict.values() Output: PLAY [Define a Simple Dictionary] ************************************************************************************************************************************************************************************** TASK [Display the Dictionary] ****************************************************************************************************************************************************************************************** ok: [localhost] => { "my_dict": { "key1": "value1", "key2": "value2", "key3": "value3" } } TASK [Display the keys in Dictionary] ********************************************************************************************************************************************************************************** ok: [localhost] => { "my_dict.keys()": [ "key1", "key2", "key3" ] } TASK [Display the values in Dictionary] ********************************************************************************************************************************************************************************** ok: [localhost] => { "my_dict.values()": [ "value1", "value2", "value3" ] } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In this example, we define a dictionary my_dict using the vars section with keys (key1, key2, key3) and their corresponding values (value1, value2, value3).
We then use the debug module to display the contents of the my_dict dictionary. You can access the values from the dictionary using the my_dict.key syntax within your tasks or templates as needed.
Let’s see a another example.
--- - name: Define and Use a Dictionary hosts: localhost gather_facts: no vars: server_config: server1: ip: 192.168.1.101 port: 8080 user: admin server2: ip: 192.168.1.102 port: 8080 user: admin server3: ip: 192.168.1.103 port: 8080 user: admin tasks: - name: Display server configuration debug: var: server_config # You can use the dictionary values in tasks - name: Configure servers debug: msg: "Configuring server {{ item.key }} with IP: {{ item.value.ip }}, Port: {{ item.value.port }}, User: {{ item.value.user }}" loop: "{{ server_config|dict2items }}" - name: Configure servers debug: msg: "Configuring server {{ item.key }}" with_dict : "{{ server_config }}" - name: Configure servers debug: msg: "Configuring server {{ item.value }}" with_dict : "{{ server_config }}" PLAY [Define and Use a Dictionary] ************************************************************************************************************************************************************************************* TASK [Display server configuration] ************************************************************************************************************************************************************************************ ok: [localhost] => { "server_config": { "server1": { "ip": "192.168.1.101", "port": 8080, "user": "admin" }, "server2": { "ip": "192.168.1.102", "port": 8080, "user": "admin" }, "server3": { "ip": "192.168.1.103", "port": 8080, "user": "admin" } } } TASK [Configure servers] *********************************************************************************************************************************************************************************************** ok: [localhost] => (item={'key': 'server1', 'value': {'ip': '192.168.1.101', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server1 with IP: 192.168.1.101, Port: 8080, User: admin" } ok: [localhost] => (item={'key': 'server2', 'value': {'ip': '192.168.1.102', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server2 with IP: 192.168.1.102, Port: 8080, User: admin" } ok: [localhost] => (item={'key': 'server3', 'value': {'ip': '192.168.1.103', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server3 with IP: 192.168.1.103, Port: 8080, User: admin" } TASK [Configure servers] *********************************************************************************************************************************************************************************************** ok: [localhost] => (item={'key': 'server1', 'value': {'ip': '192.168.1.101', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server1" } ok: [localhost] => (item={'key': 'server2', 'value': {'ip': '192.168.1.102', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server2" } ok: [localhost] => (item={'key': 'server3', 'value': {'ip': '192.168.1.103', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server server3" } TASK [Configure servers] *********************************************************************************************************************************************************************************************** ok: [localhost] => (item={'key': 'server1', 'value': {'ip': '192.168.1.101', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server {'ip': '192.168.1.101', 'port': 8080, 'user': 'admin'}" } ok: [localhost] => (item={'key': 'server2', 'value': {'ip': '192.168.1.102', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server {'ip': '192.168.1.102', 'port': 8080, 'user': 'admin'}" } ok: [localhost] => (item={'key': 'server3', 'value': {'ip': '192.168.1.103', 'port': 8080, 'user': 'admin'}}) => { "msg": "Configuring server {'ip': '192.168.1.103', 'port': 8080, 'user': 'admin'}" } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In this example, we define a dictionary server_config using the vars section with keys representing the server names (server1, server2, server3) and values representing their respective IP addresses, ports, and users.
We then use the debug module to display the contents of the server_config dictionary. You can access the values from the dictionary using the item.value syntax within a loop, as shown in the second task, where we loop through the server_config dictionary using the dict2items filter and display the values in a message. You can replace the debug task with your actual configuration tasks as needed.
create dict variable with set_fact function in ansible
In Ansible, the set_fact module is used to set variables dynamically during playbook execution.
To define a dictionary variable using the set_fact module, you can follow the syntax below:
- hosts: localhost tasks: - name: Create dictionary set_fact: my_dict: key1: value1 key2: value2 key3: value3
In this example, the set_fact module is used to define a dictionary named my_dict in the playbook and set its key-value pairs.
or you can use the following way.
- hosts: localhost tasks: - name: Create dictionary set_fact: my_dict: "{{ {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'} }}" - debug: var: my_dict PLAY [localhost] ******************************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************************************* ok: [localhost] TASK [Create dictionary] *********************************************************************************************************************************************************************************************** ok: [localhost] TASK [debug] *********************************************************************************************************************************************************************************************************** ok: [localhost] => { "my_dict": { "key1": "value1", "key2": "value2", "key3": "value3" } } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 view raw
In this case, it sets the “my_dict” variable to a dictionary with three key-value pairs: ‘key1’ with the value ‘value1’, ‘key2’ with the value ‘value2’, and ‘key3’ with the value ‘value3’. The dictionary is defined using YAML syntax within double curly braces “{{ }}” as an Ansible expression.
Here’s an example of creating a dictionary with the given key-value pairs using set_fact module in Ansible:
- hosts: localhost tasks: - name: Create dictionary set_fact: my_dict: name: David website: howtouselinux.com - name: Display dictionary values debug: var: my_dict PLAY [localhost] ******************************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************************************* ok: [localhost] TASK [Create dictionary] *********************************************************************************************************************************************************************************************** ok: [localhost] TASK [Display dictionary values] *************************************************************************************************************************************************************************************** ok: [localhost] => { "my_dict": { "name": "David", "website": "howtouselinux.com" } } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In this example, we are using the set_fact module in Ansible to create a dictionary named my_dict with two key-value pairs: name: David and website: howtouselinux.com. The my_dict variable is then available for use in subsequent tasks or roles within the playbook.
You can run this playbook on the localhost inventory (which represents the local machine) using the ansible-playbook command. When the playbook is run, the my_dict dictionary will be created and its values will be displayed using the debug module, allowing you to verify that the dictionary has been created successfully with the given key-value pairs.
Create a dictionary using the default filter in Ansible
Let’s see an example.
- hosts: localhost tasks: - name: Create dictionary set_fact: my_dict: "{{ my_dict | default({}) | combine({'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}) }}" - debug: var: my_dict
This playbook has one play that targets the “localhost” host, meaning it will be executed locally on the machine where Ansible is running. The play consists of two tasks:
The first task is named “Create dictionary” and it uses the set_fact module to create a dictionary named “my_dict”. The set_fact module is used to set a fact (a variable) in Ansible. In this case, it sets the “my_dict” variable to a dictionary created using the default filter and the combine filter.
The default filter sets the value of “my_dict” to an empty dictionary if it is not already defined, and the combine filter is used to merge the empty dictionary with a new dictionary containing three key-value pairs: ‘key1’ with the value ‘value1’, ‘key2’ with the value ‘value2’, and ‘key3’ with the value ‘value3’. The resulting “my_dict” variable will be a dictionary with these key-value pairs.
The second task is named “debug” and it uses the debug module to display the value of the “my_dict” variable. The var parameter specifies the variable to be displayed, which is “my_dict” in this case. This task will print the contents of the “my_dict” dictionary during the playbook execution for debugging purposes.
In summary, this playbook creates a dictionary named “my_dict” with three key-value pairs, and then displays the contents of this dictionary using the “debug” task.
Here are more info about combine filter, .
In Ansible, the combine filter is used to merge two or more dictionaries into a single dictionary. It allows you to concatenate multiple dictionaries, overriding or extending the values of the keys in the process.
The syntax for using the combine filter is as follows:
dict1 | combine(dict2)
where dict1 and dict2 are the dictionaries that you want to merge. dict1 will be the base dictionary, and dict2 will be merged into it.
Here are some key points to understand about the combine filter:
The combine filter does not modify the original dictionaries. Instead, it returns a new dictionary that is the result of the merge.
If keys in dict2 already exist in dict1, their values will be overridden with the values from dict2.
If keys in dict2 do not exist in dict1, they will be added to the merged dictionary.
If you pass more than two dictionaries to the combine filter, they will be merged in the order they are provided, from left to right. This means that dictionaries on the right will take precedence over dictionaries on the left in case of key conflicts.
The combine filter can also be used with multiple dictionaries, like this:
dict1 | combine(dict2) | combine(dict3) | ...
This allows you to merge more than two dictionaries into a single dictionary.
Here’s an example of using the combine filter in an Ansible playbook:
- name: Merge dictionaries hosts: localhost tasks: - name: Create dict1 set_fact: dict1: key1: value1 key2: value2 - name: Create dict2 set_fact: dict2: key2: new_value2 key3: value3 - name: Merge dict1 and dict2 set_fact: merged_dict: "{{ dict1 | combine(dict2) }}" - debug: var: merged_dict PLAY [Merge dictionaries] ********************************************************************************************************************************************************************************************** TASK [Gathering Facts] ************************************************************************************************************************************************************************************************* ok: [localhost] TASK [Create dict1] **************************************************************************************************************************************************************************************************** ok: [localhost] TASK [Create dict2] **************************************************************************************************************************************************************************************************** ok: [localhost] TASK [Merge dict1 and dict2] ******************************************************************************************************************************************************************************************* ok: [localhost] TASK [debug] *********************************************************************************************************************************************************************************************************** ok: [localhost] => { "merged_dict": { "key1": "value1", "key2": "new_value2", "key3": "value3" } } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
In this example, two dictionaries “dict1” and “dict2” are created using the set_fact module. Then, the combine filter is used to merge “dict1” and “dict2” into a new dictionary called “merged_dict”. The resulting “merged_dict” will contain the keys and values from both “dict1” and “dict2”, with the value of “key2” overridden by “new_value2” from “dict2”. Finally, the “merged_dict” is displayed using the “debug” task.
Let’s see one more example.
--- - name: Dictionary playbook example hosts: localhost tasks: - name: Create and Add items to dictionary set_fact: userdata: "{{ userdata | default({}) | combine({ item.key: item.value }) }}" loop: - key: 'Name' value: 'David' - key: 'Email' value: '[email protected]' - key: 'Nationality' value: 'US' - name: Display the Dictionary debug: var: userdata PLAY [Dictionary playbook example] ************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************************************* ok: [localhost] TASK [Create and Add items to dictionary] ****************************************************************************************************************************************************************************** ok: [localhost] => (item={'key': 'Name', 'value': 'David'}) ok: [localhost] => (item={'key': 'Email', 'value': '[email protected]'}) ok: [localhost] => (item={'key': 'Nationality', 'value': 'US'}) TASK [Display the Dictionary] ****************************************************************************************************************************************************************************************** ok: [localhost] => { "userdata": { "Email": "[email protected]", "Name": "David", "Nationality": "US" } } PLAY RECAP ************************************************************************************************************************************************************************************************************* localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Aysad Kozanoglu
Friday 1st of December 2023
very usefull and helpfull documentation to understand dict lists with using in playbooks.
the different ways explains use case scenarios for diffent type of implementation.