# with\_flattened: list vs lookup('flattened',list-of-lists)

**URL:** <https://forum.ansible.com/t/with-flattened-list-vs-lookup-flattened-list-of-lists/16326>\
**Category:** Ansible Project\
**Created:** [September 24, 2014, 7:09pm UTC](https://forum.ansible.com/t/with-flattened-list-vs-lookup-flattened-list-of-lists/16326 "2014-09-24T19:09:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josh\_Smift1](https://avatars.discourse-cdn.com/v4/letter/j/bcef8e/32.png) [@Josh\_Smift1](https://forum.ansible.com/u/Josh_Smift1)\
**Post date:** [September 24, 2014, 7:09pm UTC](https://forum.ansible.com/t/with-flattened-list-vs-lookup-flattened-list-of-lists/16326/1 "2014-09-24T19:09:38Z")

</div>

We have a playbook like this:

&nbsp;&nbsp;- hosts: localhost  
&nbsp;&nbsp;&nbsp;&nbsp;gather\_facts: false  
&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;produsers: [chris, dana]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stgusers: [pat, sandy]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;allusers: [alex, andy, chris, dan, dana, jamie, pat, sandy, terry]

&nbsp;&nbsp;&nbsp;&nbsp;tasks:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- name: show authorized  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug: msg={{ item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: item in lookup('flattened', [produsers, stgusers])  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: allusers

A list of users who should have access to prod, a list of users who should  
have access to stg, and a list of all the users, including some who  
shouldn't have access to either of those things. The task is then intended  
to show the users who are in one list or the other. Thing is, it does this:

&nbsp;&nbsp;TASK: [show authorized] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;skipping: [localhost] =\> (item=alex)  
&nbsp;&nbsp;ok: [localhost] =\> (item=andy) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "andy",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "andy"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=chris) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "chris",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "chris"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=dan) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "dan",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "dan"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=dana) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "dana",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "dana"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;skipping: [localhost] =\> (item=jamie)  
&nbsp;&nbsp;ok: [localhost] =\> (item=pat) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "pat",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "pat"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=sandy) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "sandy",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "sandy"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;skipping: [localhost] =\> (item=terry)

What are andy and dan doing there? They're not on the right lists! But,  
their names \*are\* substrings of the names of some of the users who \*are\*  
on the right lists. Hmm.

We tried this to debug:

&nbsp;&nbsp;&nbsp;&nbsp;- name: show flattened  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug: msg={{ item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: lookup('flattened', [produsers, stgusers])

That says:

&nbsp;&nbsp;TASK: [show flattened] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;ok: [localhost] =\> (item=chris,dana,pat,sandy) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "chris,dana,pat,sandy",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "chris,dana,pat,sandy"  
&nbsp;&nbsp;}

So, a list of users, right? Not so, because here's a similar one, but with  
a literal list of users, not run lookup('flattened', list-of-lists):

&nbsp;&nbsp;&nbsp;&nbsp;- name: show literal  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug: msg={{ item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: ['chris', 'dana', 'pat', 'sandy']

And that says

&nbsp;&nbsp;TASK: [show literal] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;ok: [localhost] =\> (item=chris) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "chris",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "chris"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=dana) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "dana",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "dana"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=pat) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "pat",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "pat"  
&nbsp;&nbsp;}  
&nbsp;&nbsp;ok: [localhost] =\> (item=sandy) =\> {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"item": "sandy",  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"msg": "sandy"  
&nbsp;&nbsp;}

So it looks like lookup('flattened', list-of-lists) is returning a  
\*string\* of comma-separated values, rather than a list of values.

with\_flattened seems to return a list of values, but we're not sure how to  
use that in this context, because we already need to with\_items over  
allusers.

What's the best way to do this? Is there a lookup plugin that works like  
with\_flattened, i.e. returns a list of values rather than a string?

&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-Josh (jbs@care.com)

This email is intended for the person(s) to whom it is addressed and may contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized use, distribution, copying, or disclosure by any person other than the addressee(s) is strictly prohibited. If you have received this email in error, please notify the sender immediately by return email and delete the message and any attachments from your system.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 24, 2014, 7:14pm UTC](https://forum.ansible.com/t/with-flattened-list-vs-lookup-flattened-list-of-lists/16326/2 "2014-09-24T19:14:56Z")

</div>

" when: item in lookup(‘flattened’, [produsers, stgusers])"

I’ve never seen that syntax used and am slightly surprised it works. However, what’s happening is “item” is the only thing that decides what you are looping over.

The “when” decides, at that loop iteration, what gets executed.

I would _not_ expect to see a lookup inside a “when” conditional. It’s not disallowed, but it’s weird enough to be the first time I’ve seen someone try it.

Ultimately, it may be possible to string ansible together to do some weird/clever things because there’s a template engine in there, though we generally stick to idiomatic things in the docs.

I would have suspected:

- debug: msg={{ item }}  
with\_flatted:
- listone
- listtwo

As the best way to list or iterate over the users in multiple lists at the same time.

It may be that I’m misinterpreting the question, and you are looking for another form of iteration, but that seems to be what you want, to me.

---

<div class="post-metadata">

**Author:** ![Josh\_Smift1](https://avatars.discourse-cdn.com/v4/letter/j/bcef8e/32.png) [@Josh\_Smift1](https://forum.ansible.com/u/Josh_Smift1)\
**Post date:** [September 24, 2014, 7:38pm UTC](https://forum.ansible.com/t/with-flattened-list-vs-lookup-flattened-list-of-lists/16326/3 "2014-09-24T19:38:13Z")

</div>

> However, what's happening is "item" is the only thing that decides  
> what you are looping over.

Right; the thing that we wanted to do here, if I were expressing it in  
Python-like pseudocode, would be something like:

&nbsp;&nbsp;for user in allusers:  
&nbsp;&nbsp;&nbsp;&nbsp;if user in itertools.chain(produsers, stgusers):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do stuff

That is, our logic is to iterate over the list of all users, and then see  
if each of them is in the flattened list of authorized users, do stuff if  
they are, and skip them if they aren't. But to do that, we need to get our  
hands on the flattened list of authorized users, and we can't do that with  
with\_flattened, because we're already in the middle of a with\_items across  
the list of all users.

After thinking about it some more, though, we think that our approach here  
is wrong: Rather than iterating over the list of all users, and seeing if  
they're in one of the lists of authorized users, we should instead iterate  
over the flattened list of authorized users (which we can get just fine  
via with\_flattened), and look up the information about each user that way.  
We didn't think of this at first because our list of all users is  
currently a list of dicts, but if it were a dict, that would work fine.  
(This is a slightly simplified example -- in our real use case, allusers  
isn't just a list of usernames, it's a list of dicts about each user. It  
should really be a dict of dicts instead, and then everything else would  
work perfectly.)

[https://groups.google.com/d/msg/ansible-project/W-o\_hXj-6IA/hzJFs3GRcd4J](https://groups.google.com/d/msg/ansible-project/W-o_hXj-6IA/hzJFs3GRcd4J)  
has an example of this -- that's actually the post that inspired us to do  
it the way we're doing it now, but because our users were a list rather  
than a dict, that example didn't work out of the box, and we came up with  
this other weird thing that seemed to work.

&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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-Josh (jbs@care.com)

This email is intended for the person(s) to whom it is addressed and may contain information that is PRIVILEGED or CONFIDENTIAL. Any unauthorized use, distribution, copying, or disclosure by any person other than the addressee(s) is strictly prohibited. If you have received this email in error, please notify the sender immediately by return email and delete the message and any attachments from your system.
