# How to extract a value of a field within a list of deeply nested dictionaries when some keys match other values

**URL:** <https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040>\
**Category:** Ansible Project\
**Created:** [October 15, 2020, 4:32pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040 "2020-10-15T16:32:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [October 15, 2020, 4:32pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/1 "2020-10-15T16:32:04Z")

</div>

Let’s assume the following fictional dictionary with nested lists, dictionaries, and strings, of arbitrary depth.:  
_domain\_definition.yml_

```auto
---

domain_definition:
- name: server01
cluster: cluster0
port: '8070'
- name: server11
cluster: cluster1
port: '8080'
workstations:
- name: debian1
revision: '2016-06-21'
url: http://debian1.example.com:9911/2016-06-21
- name: ubuntu1
revision: '2017-08-16'
url: http://ubuntu1.example.com:9912/2017-08-16
- name: server12
cluster: cluster2
port: '8090'
workstations:
- name: debian2
revision: '2018-04-15'
url: http://debian2.example.com:9921/2018-04-15
- name: ubuntu2
revision: '2020-01-12'
url: http://ubuntu2.example.com:9922/2020-01-12

```

The goal is to extract as efficiently as possible (the original file can be quite large) a workstation matching:

- a workstation os with its : for instance ubuntu1 ↔ 2017-08-16
- only a workstation os : for instance debian2  
As you can see from example above, the key is not always set.

A major constraint is to avoid “json\_query” as it cannot deal properly with keys containing a colon (as it may happen in my real context), last time I checked

I unsuccessfully tried different tasks, including the following:

```auto

- name: Extracting a value of a field deep within a list of complex dictionaries when some keys match other values
hosts:
- localhost
strategy: debug
tasks:
- name: Including domain_definition
include_vars: "domain_definition.yml"

- name: Extracting the OS URL when <os_revision> is known
vars:
- os_name: ubuntu1
- os_revision: 2017-08-16
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations') |
list |
selectattr('name', 'eq', os_name) |
list |
selectattr('revision', 'eq', os_revision) |
map(attribute= 'url') |
first }}"
ignore_errors: yes

- name: Extracting the OS URL when <os_revision> is known
vars:
- os_name: ubuntu1
- os_revision: 2017-08-16
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations.name', 'eq', os_name) |
list |
selectattr('workstations.revision', 'eq', os_revision) |
map(attribute= 'workstations.url') |
first }}"
ignore_errors: yes

- name: Extracting the OS URL when <os_revision> is unknown
vars:
- os_name: debian2
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations') |
list |
selectattr('name', 'eq', os_name) |
map(attribute= 'url') |
first }}"
ignore_errors: yes

- name: Extracting the OS URL when <os_revision> is unknown
vars:
- os_name: debian2
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations.name', 'eq', os_name) |
map(attribute= 'workstations.url') |
first }}"
ignore_errors: yes

```

I always get the error msg: ‘dict object’ has no attribute ‘workstations’.

Any suggestion?

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [October 15, 2020, 6:47pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/2 "2020-10-15T18:47:15Z")

</div>

Add an empty list if the attribute is missing. For example

&nbsp;&nbsp;&nbsp;&nbsp;- include\_vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file: domain\_definition.yml  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name: domain\_definition\_raw  
&nbsp;&nbsp;&nbsp;&nbsp;- set\_fact:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;domain\_definition: "{{ domain\_definition|default() +  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[my\_item] }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop: "{{ domain\_definition\_raw.domain\_definition }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;empty\_workstations:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;workstations:   
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my\_item: "{{ (item.workstations is defined)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ternary(item, item|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;combine(empty\_workstations)) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var: domain\_definition

give

&nbsp;&nbsp;domain\_definition:  
&nbsp;&nbsp;- cluster: cluster0  
&nbsp;&nbsp;&nbsp;&nbsp;name: server01  
&nbsp;&nbsp;&nbsp;&nbsp;port: '8070'  
&nbsp;&nbsp;&nbsp;&nbsp;workstations:   
&nbsp;&nbsp;- cluster: cluster1  
&nbsp;&nbsp;&nbsp;&nbsp;name: server11  
&nbsp;&nbsp;&nbsp;&nbsp;port: '8080'  
&nbsp;&nbsp;&nbsp;&nbsp;workstations:  
&nbsp;&nbsp;&nbsp;&nbsp;- name: debian1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;revision: '2016-06-21'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url: [http://debian1.example.com:9911/2016-06-21](http://debian1.example.com:9911/2016-06-21)  
&nbsp;&nbsp;&nbsp;&nbsp;- name: ubuntu1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;revision: '2017-08-16'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url: [http://ubuntu1.example.com:9912/2017-08-16](http://ubuntu1.example.com:9912/2017-08-16)  
&nbsp;&nbsp;- cluster: cluster2  
&nbsp;&nbsp;&nbsp;&nbsp;name: server12  
&nbsp;&nbsp;&nbsp;&nbsp;port: '8090'  
&nbsp;&nbsp;&nbsp;&nbsp;workstations:  
&nbsp;&nbsp;&nbsp;&nbsp;- name: debian2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;revision: '2018-04-15'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url: [http://debian2.example.com:9921/2018-04-15](http://debian2.example.com:9921/2018-04-15)  
&nbsp;&nbsp;&nbsp;&nbsp;- name: ubuntu2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;revision: '2020-01-12'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url: [http://ubuntu2.example.com:9922/2020-01-12](http://ubuntu2.example.com:9922/2020-01-12)

This should solve the problems.

---

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [October 16, 2020, 2:10pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/3 "2020-10-16T14:10:24Z")

</div>

Thanks for your answer Vladimir.  
Now, there is a ‘workstations’ attribute all the time.  
However, I still cannot get ‘os\_url’.  
The following includes your few lines:

```auto

- name: Extracting a value of a field deep within a list of complex dictionaries when some keys match other values
hosts:
- localhost
strategy: debug
tasks:
- include_vars:
file: domain_definition.yml
name: domain_definition_raw

- set_fact:
domain_definition: "{{ domain_definition|default([]) + [my_item] }}"
loop: "{{ domain_definition_raw.domain_definition }}"
vars:
empty_workstations:
workstations: []
my_item: "{{ (item.workstations is defined)|
ternary(item, item|combine(empty_workstations)) }}"

- name: (1) Extracting the OS URL when <os_revision> is known

vars:
- os_name: ubuntu1
- os_revision: 2017-08-16
debug:
msg:
"os_url: {{ domain_definition |
selectattr('workstations') |
list |
selectattr('name', 'eq', os_name) |
list |
selectattr('revision', 'eq', os_revision) |
map(attribute= 'url') |
first }}"
ignore_errors: yes

```

leads to:  
“The task includes an option with an undefined variable. The error was: No first item, sequence was empty…”

If I try to list only the workstations dictionaries with:

```auto

- name: (0) Listing all workstations
debug:
msg:
"workstations: {{ domain_definition |
selectattr('workstations') |
list }}"
ignore_errors: yes

```

I get:

ok: [localhost] =\> {  
“msg”: “workstations: [{‘name’: ‘server11’, ‘cluster’: ‘cluster1’, ‘port’: ‘8080’, ‘workstations’: [{‘name’: ‘debian1’, ‘revision’: ‘2016-06-21’, ‘url’: ‘[http://debian1.example.com:9911/2016-06-21](http://debian1.example.com:9911/2016-06-21)’}, {‘name’: ‘ubuntu1’, ‘revision’: ‘2017-08-16’, ‘url’: ‘[http://ubuntu1.example.com:9912/2017-08-16](http://ubuntu1.example.com:9912/2017-08-16)’}]}, {‘name’: ‘server12’, ‘cluster’: ‘cluster2’, ‘port’: ‘8090’, ‘workstations’: [{‘name’: ‘debian2’, ‘revision’: ‘2018-04-15’, ‘url’: ‘[http://debian2.example.com:9921/2018-04-15](http://debian2.example.com:9921/2018-04-15)’}, {‘name’: ‘ubuntu2’, ‘revision’: ‘2020-01-12’, ‘url’: ‘[http://ubuntu2.example.com:9922/2020-01-12](http://ubuntu2.example.com:9922/2020-01-12)’}]}]”  
}

On top of that, even if I were able to extract only the ‘workstations’ dictionaries instead of the whole structure, there would also probably be an issue with the empty one(s) since I would not be able to access their non-existent nested attributes (name, version and url).

---

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [October 16, 2020, 2:15pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/4 "2020-10-16T14:15:03Z")

</div>

Regarding my last remark, I probably should rather define the empty workstations as:

```auto

empty_workstations:
workstations:
- name:
revision:
url:

```

What are your thoughts?

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [October 16, 2020, 2:48pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/5 "2020-10-16T14:48:24Z")

</div>

It's up to you. If you need default values put them into the  
empty\_workstation, or better in this case, into the  
default\_workstations. For example

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default\_workstations:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;workstations:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: name\_default  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;revision: revision\_default  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;url: url\_default

Otherwise, you might want to simply skip the empty lists. For example

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ item.name }}:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ item.workstations|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectattr('name', 'eq', os\_name)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectattr('revision', 'eq', os\_revision)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map(attribute= 'url')|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop: "{{ domain\_definition }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: item.workstations|length \> 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os\_name: ubuntu1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os\_revision: '2017-08-16'

---

<div class="post-metadata">

**Author:** ![actionmystique](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/actionmystique/32/1678_2.png) [@actionmystique](https://forum.ansible.com/u/actionmystique)\
**Post date:** [October 16, 2020, 4:13pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/6 "2020-10-16T16:13:21Z")

</div>

There are 2 issues:.

1. The loop can become costly as the number of entries rise: I have files with hundreds (potentially thousands) of servers/workstations.
2. it also results in as many answers as the number of entries, although only one is non empty. I don’t know how to set a variable with the single right answer.

```auto

- debug:
msg: "{{ item.workstations|
selectattr('name', 'eq', os_name)|
selectattr('revision', 'eq', os_revision)|
map(attribute= 'url')|
list }}"
loop: "{{ domain_definition }}"
when: item.workstations|length > 0
vars:
os_name: ubuntu1
os_revision: '2017-08-16'

```

leads to:

```auto

ok: [localhost] => (item={'name': 'server01', 'cluster': 'cluster0', 'port': '8070', 'workstations': [{'name': 'name_default', 'revision': 'revision_default', 'url': 'url_default'}]}) => {
"msg": []
}
ok: [localhost] => (item={'name': 'server11', 'cluster': 'cluster1', 'port': '8080', 'workstations': [{'name': 'debian1', 'revision': '2016-06-21', 'url': 'http://debian1.example.com:9911/2016-06-21'}, {'name': 'ubuntu1', 'revision': '2017-08-16', 'url': 'http://ubuntu1.example.com:9912/2017-08-16'}]}) => {
"msg": [
"http://ubuntu1.example.com:9912/2017-08-16"
]
}
ok: [localhost] => (item={'name': 'server12', 'cluster': 'cluster2', 'port': '8090', 'workstations': [{'name': 'debian2', 'revision': '2018-04-15', 'url': 'http://debian2.example.com:9921/2018-04-15'}, {'name': 'ubuntu2', 'revision': '2020-01-12', 'url': 'http://ubuntu2.example.com:9922/2020-01-12'}]}) => {
"msg": []
}

```

Isn’t there a loopless solution?

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [October 16, 2020, 7:31pm UTC](https://forum.ansible.com/t/how-to-extract-a-value-of-a-field-within-a-list-of-deeply-nested-dictionaries-when-some-keys-match-other-values/34040/7 "2020-10-16T19:31:59Z")

</div>

> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ item.workstations|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectattr('name', 'eq', os\_name)|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selectattr('revision', 'eq', os\_revision)|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map(attribute= 'url')|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list }}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop: "{{ domain\_definition }}"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: item.workstations|length \> 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os\_name: ubuntu1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os\_revision: '2017-08-16'
> 
> Isn't there a loopless solution?

Next option is a custom filter. For example,

> cat filter\_plugins/custom\_select\_url.py

def custom\_select\_url(l, os\_name, os\_revision):  
&nbsp;&nbsp;&nbsp;&nbsp;l1 =   
&nbsp;&nbsp;&nbsp;&nbsp;for i in l:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 'workstations' in i.keys():  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for j in i['workstations']:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (j['name'] == os\_name) and \  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(j['revision'] == os\_revision):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;l1.append(j['url'])  
&nbsp;&nbsp;&nbsp;&nbsp;return l1

class FilterModule(object):

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def filters(self):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'custom\_select\_url': custom\_select\_url  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

and the playbook

> cat pb.yml

- hosts: localhost  
&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;- include\_vars: domain\_definition.yml  
&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ domain\_definition|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;custom\_select\_url('ubuntu1', '2017-08-16') }}"

give

&nbsp;&nbsp;msg:  
&nbsp;&nbsp;- [http://ubuntu1.example.com:9912/2017-08-16](http://ubuntu1.example.com:9912/2017-08-16)
