# include + with\_items

**URL:** <https://forum.ansible.com/t/include-with-items/13091>\
**Category:** Ansible Project\
**Created:** [July 9, 2013, 7:05pm UTC](https://forum.ansible.com/t/include-with-items/13091 "2013-07-09T19:05:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Serge\_van\_Ginderacht](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Serge\_van\_Ginderacht](https://forum.ansible.com/u/Serge_van_Ginderacht)\
**Post date:** [July 9, 2013, 7:05pm UTC](https://forum.ansible.com/t/include-with-items/13091/1 "2013-07-09T19:05:01Z")

</div>

Michael,

What exactly is the (technical?) problem doing include + with\_items?

I know you do not recommend it, and are very vocal on that, but I never really understood exactly why.

Is it a syntax problem, difficult to grasp all the possible consequences?  
Is there a particular technical reason not to do that?  
Is this something that coincidently happens to work now, but might break in the future?  
Maybe something else?

Also: is it specific to the items lookup\_plugin, or does this recommendation also apply to other lookup plugins?

Thanks for sorting that out,

Serge

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [July 10, 2013, 1:09am UTC](https://forum.ansible.com/t/include-with-items/13091/2 "2013-07-10T01:09:21Z")

</div>

yeah, with\_items on an include was something Daniel added a while back.

What “include with a with\_items” clause does is create a list of tasks.

While this sounds great (and was technically pretty slick), tasks must be uniform for all hosts in the play (but variables get subbed in later)

95% of everyone seems to want to use this with an inventory scoped data, like having a list of packages or users defined in the group.

This doesn’t work, because the same tasks can’t be created for each item.

So, yes, it’s technically _NOT_ possible to do include + with\_items if with an inventory scoped variable.  
It’s fine otherwise, but I feel it’s much better to include the looping _inside_ the task file, using a simple task + with\_items.

It’s the same kind of thing that comes up with “why aren’t variables in my task name being interpolated” when using inventory variables, except it’s functional instead of cosmetic.

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [July 10, 2013, 1:13pm UTC](https://forum.ansible.com/t/include-with-items/13091/3 "2013-07-10T13:13:23Z")

</div>

Excerpts from Michael DeHaan's message of 2013-07-09 21:09:21 -0400:

> While this sounds great (and was technically pretty slick), tasks must be  
> uniform for all hosts in the play (but variables get subbed in later)
> 
> 95% of everyone seems to want to use this with an inventory scoped data,  
> like having a list of packages or users defined in the group.
> 
> This doesn't work, because the same tasks can't be created for each item.

Just to clarify, this means looping on task includes \*would\* work if the  
list were set in, say, 'group\_vars/all'? And might \*happen to\* work if  
the list were defined in, say, 'group\_vars/foo', and the playbook in  
question had 'hosts' set to 'foo'?

In other words, ansible parses the yaml, encounters an include statement  
(either literally or via role magic), and then evaluates the loop. If  
any variables referenced in the loop cannot be resolved, they are (like  
all unresolved variables in ansible), passed literally.

I can see that coming back to bite you if you forget those specifics.

I assume the exact same conditions imply to looping roles?

Is there any chance of inserting a deprecation warning (or just a 'there  
be dragons' warning) when someone uses a loop with an include statement  
or a role statement?

If not, perhaps we could add a note in the documentation regarding  
variable precedence? Or add a short section near there about scoping  
rules (of which there are very few, this being by far the most  
complicated)? I'd be happy to submit a pull request if that's desired.  
I can also see wanting to let sleeping dogs lie...

Also, re: lookup plugins other than 'with\_items', as Serge asked, I'm  
going to guess is again matters whether the lookup plugin can be  
evaluated.

So, for example, I tested the following:

&nbsp;&nbsp;&nbsp;&nbsp;--- # test.yaml  
&nbsp;&nbsp;&nbsp;&nbsp;hosts: localhost  
&nbsp;&nbsp;&nbsp;&nbsp;connection: local  
&nbsp;&nbsp;&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- include: mytasks.yaml  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_env:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- HOME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- USER  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- PWD  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- EDITOR

&nbsp;&nbsp;&nbsp;&nbsp;--- # mytasks.yaml  
&nbsp;&nbsp;&nbsp;&nbsp;- debug: msg={{item}}

Running `ansible-playbook test.yaml` gives:

&nbsp;&nbsp;&nbsp;&nbsp;PLAY [localhost] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;GATHERING FACTS \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;ok: [localhost]

&nbsp;&nbsp;&nbsp;&nbsp;TASK: [debug msg=/home/chamill] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;ok: [localhost] =\> (item=/home/chamill)  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;TASK: [debug msg=chamill] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;ok: [localhost] =\> (item=chamill)  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;TASK: [debug msg=/home/chamill] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;ok: [localhost] =\> (item=/home/chamill)  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;TASK: [debug msg=vim] \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;ok: [localhost] =\> (item=vim)  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;PLAY RECAP \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
&nbsp;&nbsp;&nbsp;&nbsp;localhost : ok=4 changed=0 unreachable=0 failed=0

Anwyay, sorry about the wall of text, but I got curious. Basically  
with\_items works fine on includes, but only if the variables in the loop  
have an effectively global scope (so, variables set for the 'all' group,  
or directly in the playbook, or resolved at runtime via a lookup plugin;  
I might be missing one or two other types of variables).

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@Michael\_DeHaan](https://forum.ansible.com/u/Michael_DeHaan)\
**Post date:** [July 10, 2013, 1:46pm UTC](https://forum.ansible.com/t/include-with-items/13091/4 "2013-07-10T13:46:11Z")

</div>

“Just to clarify, this means looping on task includes _would_ work if the  
list were set in, say, ‘group\_vars/all’?”

No, it would not.

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [July 10, 2013, 2:07pm UTC](https://forum.ansible.com/t/include-with-items/13091/5 "2013-07-10T14:07:30Z")

</div>

Excerpts from Michael DeHaan's message of 2013-07-10 09:46:11 -0400:

> "Just to clarify, this means looping on task includes \*would\* work if the  
> list were set in, say, 'group\_vars/all'?"
> 
> No, it would not.

Ah, so it is of \*really\* limited utility. Only works with playbook vars  
and lookup plugins.

I can see why you don't encourage its use.

---

<div class="post-metadata">

**Author:** ![Jim\_Kleckner](https://avatars.discourse-cdn.com/v4/letter/j/848f3c/32.png) [@Jim\_Kleckner](https://forum.ansible.com/u/Jim_Kleckner)\
**Post date:** [July 10, 2013, 6:27pm UTC](https://forum.ansible.com/t/include-with-items/13091/6 "2013-07-10T18:27:25Z")

</div>

> Excerpts from Michael DeHaan’s message of 2013-07-09 21:09:21 -0400:

> Is there any chance of inserting a deprecation warning (or just a ‘there  
> be dragons’ warning) when someone uses a loop with an include statement

> or a role statement?

+1 for deprecation warnings  
Also, Ansible with 1.2 has changed and regularized a lot to the better.  
The ability to flag old style/new style would be useful.

Parenthetically, error\_on\_undefined\_vars is useful too.

> If not, perhaps we could add a note in the documentation regarding  
> variable precedence? Or add a short section near there about scoping  
> rules (of which there are very few, this being by far the most  
> complicated)? I’d be happy to submit a pull request if that’s desired.  
> I can also see wanting to let sleeping dogs lie…

+1 for very good documentation about precedence/scoping.  
It seems to generate a lot of questions.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [July 10, 2013, 8:52pm UTC](https://forum.ansible.com/t/include-with-items/13091/7 "2013-07-10T20:52:14Z")

</div>

Right, I haven’t really deprecated it, meaning there is no plan to remove it.
