# with\_recursive: A lookup plugin that chains other lookups

**URL:** <https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601>\
**Category:** Ansible Developer\
**Created:** [June 25, 2015, 8:32am UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601 "2015-06-25T08:32:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [June 25, 2015, 8:32am UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/1 "2015-06-25T08:32:47Z")

</div>

Hi

I wrote a lookup plugin and I’d like to hear what you think. It allows one to nest loops inside each other. Kind of like with\_nested, but with other loop types than ‘items’. The code is here: [Ansible lookup plugin that chains other lookup plugins together and makes them iterate on each other · GitHub](https://gist.github.com/hkariti/d07695b4b9c5a68d8c02)

It allows you to do these:

vars:  
some\_dict:  
key1:  
inner\_dict:  
i\_key1: value  
key2:  
inner\_dict:  
n\_key1: value2  
tasks:

# Will output ‘value’ and ‘value2’

- debug: var=item.value  
with\_recursive:
- { name: dict, args: some\_dict }
- { name: dict: args: “{{item.value.inner\_dict}}” }

and:

vars:  
cmds:

- cat /etc/passwd
- ls -l  
tasks:

# Will output the stdout of both commands

- debug: var=item  
with\_recursive:
- { name: items, args: urls }
- { name: pipe, args: “{{item}}” }

Before callling each lookup plugin, it’s arguments are templated. Each lookup is also provided with the following variables:

- ‘item’, which is the iterated value from the previous lookup’s results.
- ‘items’, which is a list of all the items from all previous nesting levels
- ‘item\_idx’, which is the index of ‘item’ in ‘items’

I’d love to hear about whether it’s ugly, cool, unnecessary, etc.

Thanks,  
Hagai

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [June 25, 2015, 2:00pm UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/2 "2015-06-25T14:00:52Z")

</div>

This is already possible, just with diff format:

with\_file:

- ‘/file/iknow/of’

- “{{ lookup(‘pipe’, ‘find path/to/dir/with/files/ -type f’}}”

You can even nest lookups {{ lookup(‘pipe’, ‘grep ’ + lookup(‘consul\_kv’, ‘special\_key’) + ’ path/to/local/files/\*’) }}

---

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [June 25, 2015, 2:03pm UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/3 "2015-06-25T14:03:21Z")

</div>

Yes, you can combine lookups, but each lookup needs to be independent in your example. You can’t use the results of the previous lookup. Can you do my first example (with the dict and deep\_dict) with lookups?

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [June 26, 2015, 12:29am UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/4 "2015-06-26T00:29:29Z")

</div>

That is what both my examples do, in the 2nd it consul data to return a list of files that file lookup will read and return the file content.

---

<div class="post-metadata">

**Author:** ![Hagai\_Kariti](https://avatars.discourse-cdn.com/v4/letter/h/4491bb/32.png) [@Hagai\_Kariti](https://forum.ansible.com/u/Hagai_Kariti)\
**Post date:** [June 26, 2015, 7:04pm UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/5 "2015-06-26T19:04:11Z")

</div>

The first example doesn’t really work when `find` returns multiple results, as `with_file` parses the entire output as a single file. Using the `lines` lookup instead with the `wantlist=True` option fails because `with_file` doesn’t handle nested lists. The second example only works when the consul lookup returns a single value, for the same reason.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [June 26, 2015, 7:46pm UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/6 "2015-06-26T19:46:02Z")

</div>

all lookups take lists as inputs, even when passing a single string it  
gets converted into a list, I'll look into the issues you mention, but  
this was designed to be chainable, I've also used them this way in the  
past.

Most lookups won't do flattening, but 'items' does 1 level and  
'flattened' does multiple levels and you can chain them in also.

---

<div class="post-metadata">

**Author:** ![Hank\_Beatty](https://avatars.discourse-cdn.com/v4/letter/h/f6c823/32.png) [@Hank\_Beatty](https://forum.ansible.com/u/Hank_Beatty)\
**Post date:** [July 1, 2015, 6:07pm UTC](https://forum.ansible.com/t/with-recursive-a-lookup-plugin-that-chains-other-lookups/18601/7 "2015-07-01T18:07:03Z")

</div>

Hello Hagai,

I think this is awesome! It is exactly what I was looking for. I think this is much easier to understand than the lookup option Brian mentions in the continuing thread. Which I completely didn't understand.

Keep up the great work.

Hank
