🎯 Filtering Data in Ansible: selectattr and map(attribute)
When working with lists of dictionaries in Ansible, filtering and extracting specific values is a common requirement. Jinja2 provides two powerful filters to accomplish this:
selectattr→ Filters the list based on a condition.
map(attribute)→ Extracts a specific field from the filtered result.
In this article, you'll learn:
- ✅ How to filter lists of dictionaries in Ansible using
selectattr
- ✅ How to extract specific values using
map(attribute)
- ✅ How to handle missing values safely using
default()
---
📌 Understanding selectattr and map(attribute)
Before jumping into Ansible playbooks, let's break down these Jinja2 filters.
✅ selectattr('name', 'equalto', search_name')
- Filters a list of dictionaries to select only the ones where
name == search_name.
✅ map(attribute='folder')
- Extracts the
folderfield from the filtered result.
✅ Example Syntax
``yaml
{{ variable | selectattr('name', 'equalto', search_name) | map(attribute='folder') | list }}
`
- selectattr
filters the list wherenameequalssearch_name.
- map(attribute='folder')
extracts only thefoldervalues.
- list
ensures the result is returned as a list.
---
🔥 Example Use Case
Scenario
You have a list of users and their home directories (folder). You want to search for a specific user and get their folder path.
Example Data
`yaml
variable:
- name: alice
folder: /home/alice
- name: bob
folder: /home/bob
- name: charlie
folder: /home/charlie
`
Using selectattr and map(attribute) in Ansible
`yaml
- name: Search for a name and get its folder
hosts: localhost
gather_facts: no
vars:
variable:
- name: alice
folder: /home/alice
- name: bob
folder: /home/bob
- name: charlie
folder: /home/charlie
search_name: alice
tasks:
- name: Get folder for a specific user
debug:
msg: "{{ variable | selectattr('name', 'equalto', search_name) | map(attribute='folder') | list }}"
`
---
🎯 Expected Output
When search_name: alice, the output will be:
`yaml
TASK [Get folder for a specific user] *
ok: [localhost] => {
"msg": [
"/home/alice"
]
}
`
When search_name: bob, the output will be:
`yaml
TASK [Get folder for a specific user] *
ok: [localhost] => {
"msg": [
"/home/bob"
]
}
`
---
🔹 Getting a Single Value Instead of a List
By default, the output is a list with one value. If you need only the string value, add .0:
`yaml
- name: Get a single folder for a user
debug:
msg: "{{ (variable | selectattr('name', 'equalto', search_name) | map(attribute='folder') | list).0 }}"
`
📌 Expected Output
``yaml
TASK