# Include a task for each element of a list

**URL:** <https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405>\
**Category:** Ansible Project\
**Created:** [September 2, 2013, 4:44pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405 "2013-09-02T16:44:21Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![stephane](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@stephane](https://forum.ansible.com/u/stephane)\
**Post date:** [September 2, 2013, 4:44pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/1 "2013-09-02T16:44:21Z")

</div>

Hi!

I’d like to manage users on my servers. Basically, I want 3 variables for each group of servers (may be overrided for a specific host) containing the users I want to create :  
users: basic users  
sudo\_users: users in the sudo group  
disabled\_users: users disabled (or deleted).

So in the common role, I have a task like this :

- include: create\_sudo\_user.yml user={{item}}  
with\_items: sudo\_users

- name: echo  
shell: echo {{ item }}  
with\_items: sudo\_users

sudo\_users is a list defined in a group\_vars file. The echo task is here for debugging purpose.

The included task is simply:

---

<div class="post-metadata">

**Author:** ![Christopher\_O\_Conne2](https://avatars.discourse-cdn.com/v4/letter/c/e0b2c6/32.png) [@Christopher\_O\_Conne2](https://forum.ansible.com/u/Christopher_O_Conne2)\
**Post date:** [September 2, 2013, 11:06pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/2 "2013-09-02T23:06:17Z")

</div>

Assuming that your list of users is defined in as a list in a vars file, then something like this has worked for me before.

_accounts.yml_:

- accounts:
- name: one  
list: [a]
- name: two  
list: [a, b, c]
- name: three  
list: [c]

_playbook.yml_:

- include: setup\_accounts.yml  
with\_items: ${accounts}

_setup\_accounts.yml_:

- task: Do something for {{ item.name }}  
action: {{ item.name }} works here
- task: Do something for {{ item.name }} lists  
action: {{ item }} is an item in the list from the vars file  
with\_items: ${item.list}

As I asked in another thread, I’m not sure this is a **good** way to set this up, but it does seem to work.

Presumably, if you setup a vars file with an entry like:

- my\_list:
- value1
- value2
- value3

Then simply using {{ item }} in the included file will produce ‘value1’, ‘value2’, ‘value3’.

All the best,

~ Christopher

---

<div class="post-metadata">

**Author:** ![stephane](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@stephane](https://forum.ansible.com/u/stephane)\
**Post date:** [September 3, 2013, 3:14pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/3 "2013-09-03T15:14:07Z")

</div>

Hello!

I defined my accounts list as is, in a vars\_file:  
sudo\_users: [test1,test2,test3]

The problem is that the with\_item statement in include tasks doesn’t behave the same way as in other tasks.

In any task, the with\_item is “evaluated”, so I can get the content of the variable. But for include task, the with\_item part is not “evaluated”, and I can only put some constant value.

So, when I do something like that:

- include: create\_sudo\_user.yml user={{item}}  
with\_items: ${ sudo\_users }

I get this error: ERROR: with\_items expects a list

If I do

- include: create\_sudo\_user.yml user={{item}}  
with\_items: sudo\_users

I get in the included file the value “sudo\_users” instead of the content of the list.

In that case, if instead of an include task I do a shell task, it works well.

It seems to me that’s a bug: with\_items should behave the same way for any task. What do you think?

Oh, for the record, I’m using the current git version, fetched today.

$ ansible --version  
ansible 1.3

Many thanks for your help.

---

<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:** [September 3, 2013, 8:53pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/4 "2013-09-03T20:53:56Z")

</div>

I see you are using include combined with a with\_items. Don’t do that! 🙂

This will solve most of your problems.

It was not implemented well originally and I should have never taken the patch for it – people try to use it with inventory variables and that simply cannot work because of the way the system works.  
It’s much better to loop inside the task itself, use with\_items inside there, and it’s fine to pass a list to a role variable if you like to achieve the same level of parameterization.

include + with\_items is likely to be removed completely by 1.5. Please take appropriate steps to not rely on it.

Meanwhile, you’re also using old style variables.

with\_items: sudo\_users

would be enough.

–Michael

---

<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:** [September 3, 2013, 9:03pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/5 "2013-09-03T21:03:03Z")

</div>

​Whilst I fully understand the problem with include + with\_items, the only  
places I use it, is when I nest loops: ​a double with\_items so to speak,  
where the outer loop doesn't get variables from inventory of course.

Any plans or options to extend or support something similar if include +  
with\_items gets removed? I know about with\_nested, not sure if that covers  
all my use cases.

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:** [September 3, 2013, 9:28pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/6 "2013-09-03T21:28:32Z")

</div>

Let me know where you think with\_nested wouldn’t work.

---

<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:** [September 3, 2013, 9:55pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/7 "2013-09-03T21:55:05Z")

</div>

Is there any reason an include + with\_items couldn't be translated to an  
include, with every included task having the with\_items applied  
individually?

Sort of like it works now with include + when? The only issue I can think  
of is how to handle the case where an included task also has a with\_items.

Thoughts?

---

<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:** [September 3, 2013, 10:41pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/8 "2013-09-03T22:41:58Z")

</div>

Morgan,

_MAYBE_. That’s a good idea, but it would also have to upgrade any “with\_items” it found to “with\_nested” calls, and that’s confusing because then you have a {{ item.0 }} and {{ item.1 }} to content with.

Better to loop explicitly inside the task.

---

<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:** [September 4, 2013, 12:10am UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/9 "2013-09-04T00:10:12Z")

</div>

Right, it's definitely a tricky one.

Would a patch which made is "do the right thing" be accepted, assuming it  
wasn't a god-awful hack, or would you rather leave things as they are?

---

<div class="post-metadata">

**Author:** ![stephane](https://avatars.discourse-cdn.com/v4/letter/s/dfb087/32.png) [@stephane](https://forum.ansible.com/u/stephane)\
**Post date:** [September 4, 2013, 7:48am UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/10 "2013-09-04T07:48:22Z")

</div>

Hello,

groumpf.

Looping over an include is, in my opinion, a must-have feature.

What I wanted to do: for each user create a group, create a user, send a ssh-key, and send config files for each user. So I have 4 tasks, and each one for a single user. Yes, I can loop for each task, but it’s a little bit more painful.

If that cannot be achieved using a with\_items, a construct using a jinja loop may be definitely useful. Is there a way to preprocess playbooks in the jinja templating system? I may be wrong but it seems to me easier to do.

If I cannot loop over an include, I have an other issue. I may have (or not have) in my roles/common/files/config/ directory some files I would like to send to my servers (each user may have different config files, a different shell, …). Does that kind of construct work?

- name: deploy config files  
sudo: yes  
copy: src={{ item }} dest=“/home/{{ item }}/” owner={{ item }} mode={{ 600 }}  
with\_fileglob:
- configfiles/{{ item }}/\*  
with\_items: sudo\_users  
ignore\_errors: yes

How can I loop both on a list and some files? Can I mix with\_items and with\_fileglob?

Thanks,

---

<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:** [September 4, 2013, 12:31pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/11 "2013-09-04T12:31:09Z")

</div>

I’m afraid it would be a hack, because of other types of iterators.

---

<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:** [September 4, 2013, 12:31pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/12 "2013-09-04T12:31:34Z")

</div>

“What I wanted to do: for each user create a group, create a user, send a ssh-key, and send config files for each user.”

You use with\_nested.

---

<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:** [September 7, 2013, 1:11pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/13 "2013-09-07T13:11:51Z")

</div>

​I reviewed the scripts where I use include+with\_items, and the problem  
exists where I combine a with\_item loop + with\_fileglob, which is also the  
use case Stéphane mentioned.

​As discussed per irc:

This could be solved - I think - if we could get the output of a lookup  
plugin as a complex var, a list, and not a flattened string, on a with\_  
construct:

&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;users:  
&nbsp;&nbsp;&nbsp;&nbsp;- foo  
&nbsp;&nbsp;&nbsp;&nbsp;- bar

&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;- debug: 'msg="{{ item.0, item.1 }}"'  
&nbsp;&nbsp;&nbsp;&nbsp;with\_nested:  
&nbsp;&nbsp;&nbsp;&nbsp;- users  
&nbsp;&nbsp;&nbsp;&nbsp;- lookup('fileglob', 'files/\*')  
​  
Need to further think on implementation.

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:** [September 7, 2013, 1:29pm UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/14 "2013-09-07T13:29:28Z")

</div>

As discussed on IRC, I like this suggestion, though we would need to make sure it was implemented for “with\_items” and the various other appropriate “with\_” statements as well.

---

<div class="post-metadata">

**Author:** ![Christopher\_O\_Conne2](https://avatars.discourse-cdn.com/v4/letter/c/e0b2c6/32.png) [@Christopher\_O\_Conne2](https://forum.ansible.com/u/Christopher_O_Conne2)\
**Post date:** [September 9, 2013, 6:42am UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/15 "2013-09-09T06:42:49Z")

</div>

I would like to second the suggestion of allowing lookup plugins to return complex types. It would greatly simplify building reusable play books.

All the best,

~ Christopher

---

<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:** [September 9, 2013, 6:48am UTC](https://forum.ansible.com/t/include-a-task-for-each-element-of-a-list/13405/16 "2013-09-09T06:48:37Z")

</div>

fyi, feature ticket filed: [https://github.com/ansible/ansible/issues/4060](https://github.com/ansible/ansible/issues/4060)
