The title is a bit confusing but I didn't know how else to describe it. My hostvars
look like this:
{
"host1": {
"tags": {
"Name": "host1-name"
}
},
"host2": {
"tags": {
"Name": "host2-name"
}
}
}
I don't know which host I want to capture--I need to get that dynamically based on the results of the Name
tag. I tried this:
hostvars | selectattr("tags.Name", "equalto", "host2-name")
But of course the tags
attribute isn't at the root so it errors out. The problem is the root attribute is variable (host1
, host2
, etc.).
I tried to use an asterisk, but I got "VARIABLE IS NOT DEFINED!: 'str object' has no attribute '*'"
:
hostvars | selectattr("*.tags.Name", "equalto", "host2-name")
So how would I filter based on the Name
tag, where I don't know what the root attribute is?
The selectattr
filter is meant for list of dicts. You are trying to apply it to hostvars
which is not a list but a dictionary.
To perform your search you'll first need to transform that dict to a list. There are basically two options to do this:
dict2items
filter to get a list of key/value pairs (i.e. key=host_name_string, value=dict_of_host_variables
)The solution to choose depends on your requirement. I this example I'll take the second one as we will not loose any information. In fact the key we will drop will still exist inside the value as the inventory_hostname
variable.
Here is how to filter your hosts with this solution:
matching_hosts_list: "{{ hostvars.values() | selectattr('tags.Name', "==", "AIR-Media-Release-SW5") }}"
From there you can use the result as you wish. For example, to print a list of matching host names:
- name: Show matching host names
ansible.builtin.debug:
var: matching_hosts_list | map(attribute='inventory_hostname')