# Looping over roles ?

**URL:** <https://forum.ansible.com/t/looping-over-roles/13850>\
**Category:** Ansible Project\
**Created:** [November 5, 2013, 4:43pm UTC](https://forum.ansible.com/t/looping-over-roles/13850 "2013-11-05T16:43:54Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [November 5, 2013, 4:43pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/1 "2013-11-05T16:43:54Z")

</div>

Fellows,

I trying to wrap my head around a simple problem.  
I have a playbook (role) that installs ruby with rbenv.  
Actually, it uses ruby.version host/group variable to install the  
correct ruby version :

group\_vars/some\_servers\_that\_wants\_ruby.yml :

---

<div class="post-metadata">

**Author:** ![James\_Cammarata1](https://avatars.discourse-cdn.com/v4/letter/j/d26b3c/32.png) [@James\_Cammarata1](https://forum.ansible.com/u/James_Cammarata1)\
**Post date:** [November 5, 2013, 5:09pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/2 "2013-11-05T17:09:49Z")

</div>

Yes, pass the array in via the role arguments and then loop over them inside the role itself. For example:

roles:

- { role: ruby, versions: [“1.9.3-p448”, “2.0.0-p247”]}

Then use “with\_items: versions” inside the role.

---

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [November 6, 2013, 6:11am UTC](https://forum.ansible.com/t/looping-over-roles/13850/3 "2013-11-06T06:11:30Z")

</div>

Thanks James.

The problem, as explained previously, is that I can hardly use  
with\_items within a role's task since I use chained actions with  
registered variables. It simply wouldn't work.

For instance, before installing ruby, an action checks if the requested  
version is already installed (and registers a variable). I don't think  
this would survive a "with\_items" loop (unless it is possible to  
register hash entries, but I don't think so).

M

---

<div class="post-metadata">

**Author:** ![Jerome\_Wagner](https://avatars.discourse-cdn.com/v4/letter/j/76d3ee/32.png) [@Jerome\_Wagner](https://forum.ansible.com/u/Jerome_Wagner)\
**Post date:** [November 6, 2013, 10:22am UTC](https://forum.ansible.com/t/looping-over-roles/13850/4 "2013-11-06T10:22:32Z")

</div>

Hello,

I am also looking for a way to loop over a set of tasks.

I used to do it with role.with\_items just as you first posted but it has been deprecated.

The deprecation is for good reasons I think because the plays are unrolled before execution and even if role.with\_items work in simple cases, I believe there are more complex inventory cases where it does weird things.

One option is to push the with\_items down to the task level. This is what I did for my multi-versions installs but I did not need to register variables so it was simpler.

The best would be to make a role loopable with minimum modifications (pushing with\_items down to the tasks level is rather painful imho)

Your question made me think about a potential new way to do it. it will look as a hack to many but may work to unroll the loop. The basis of the idea is to consider that the main use case is to loop N times over the role, N being bounded to for example 5.

Let’s say you have you role : “ruby\_install\_one\_version”

Now you define a new role “loop”

- { role: “loop”, over: “ruby\_install\_one\_version”, iconf: [{ version: “1.9.3-p448”}, { version: “2.0.0-p247” }] }

in meta.main.yml / dependency, you add something like (I still have a hard time with $ and {{}} in these contexts and I am not sure .length is the way to do it)

- { role: “{{ over }}”, conf: $iconf[0], when: “0 \< iconf.length” }
- { role: “{{ over }}”, conf: $iconf[1], when: “1 \< iconf.length” }
- { role: “{{ over }}”, conf: $iconf[2], when: “2 \< iconf.length” }
- { role: “{{ over }}”, conf: $iconf[3], when: “3 \< iconf.length” }
- { role: “{{ over }}”, conf: $iconf[4], when: “4 \< iconf.length” }

The details would have to be refined but I think it could work to have the roles unroll as independent blocks of tasks rather than inside each task ; and if it works, it would look cleaner to me than obscuring the initial role with with\_items and with\_nested all over the place.

Tell me if you try it !

Jerome

---

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [November 6, 2013, 4:26pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/5 "2013-11-06T16:26:44Z")

</div>

> Hello,

Hey Jerome,

> I am also looking for a way to loop over a set of tasks.

[...]

> One option is to push the with\_items down to the task level. This is  
> what I did for my multi-versions installs but I did not need to register  
> variables so it was simpler.
> 
> The best would be to make a role loopable with minimum modifications  
> (pushing with\_items down to the tasks level is rather painful imho)

[...]

> The details would have to be refined but I think it could work to have  
> the roles unroll as independent blocks of tasks rather than inside each  
> task ; and if it works, it would look cleaner to me than obscuring the  
> initial role with with\_items and with\_nested all over the place.
> 
> Tell me if you try it !

That's hell of a hack, but it works like a charm (with few changes) !

$ cat roles/ruby/tasks/main.yml

---

<div class="post-metadata">

**Author:** ![John\_Jarvis](https://avatars.discourse-cdn.com/v4/letter/j/e47774/32.png) [@John\_Jarvis](https://forum.ansible.com/u/John_Jarvis)\
**Post date:** [November 6, 2013, 4:32pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/6 "2013-11-06T16:32:16Z")

</div>

I would like to see your full ruby role if you don't mind making it available.  
-John

---

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [November 6, 2013, 10:35pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/7 "2013-11-06T22:35:17Z")

</div>

Hi John,

I've setup a repos with a Vagrantfile so you can try it out :  
[https://github.com/leucos/ansible-rbenv-playbook](https://github.com/leucos/ansible-rbenv-playbook)

Rough edges, comments & PRs welcome.

M

---

<div class="post-metadata">

**Author:** ![Jerome\_Wagner](https://avatars.discourse-cdn.com/v4/letter/j/76d3ee/32.png) [@Jerome\_Wagner](https://forum.ansible.com/u/Jerome_Wagner)\
**Post date:** [November 7, 2013, 6:43pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/8 "2013-11-07T18:43:47Z")

</div>

I am glad the looping works it means that you can go from a “single” install script to a “multi” without modification and that is interesting.

Note that in your  
ruby\_multi/tasks/main.yml  
you can add a fail test when the versions array has a length superior to the looping cardinality of your multi. This way you will be informed if your array is not fully looped over.

note also that there might be other issues to look at and solve with notify: restart when doing a multi version of a server install. It might be necessary to restart all versions even if only one version is notified. At least until the notify: can accept parameters.

I do not use ruby that much but thanks for the script it is interesting and made me learn a few tricks.

Jerome

---

<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:** [November 10, 2013, 9:28pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/9 "2013-11-10T21:28:21Z")

</div>

“since I use chained actions with  
registered variables. It simply wouldn’t work.”

Not sure what a “chained variable” is.

---

<div class="post-metadata">

**Author:** ![Michel\_Blanc1](https://avatars.discourse-cdn.com/v4/letter/m/fbc32d/32.png) [@Michel\_Blanc1](https://forum.ansible.com/u/Michel_Blanc1)\
**Post date:** [November 11, 2013, 7:25am UTC](https://forum.ansible.com/t/looping-over-roles/13850/10 "2013-11-11T07:25:21Z")

</div>

It's registered variables. I use conditional tasks that depend on  
previously registered variables (for instance, I check if the requested  
ruby version is already installed and depending on the result, I install  
it or not).

I'm not sure I can do that using 'with\_items' for the ruby versions :  
registered variables would be overriden for each item I suppose, unless  
there is some facility that would put the results in a hash instead of a  
simple variable.

M

---

<div class="post-metadata">

**Author:** ![Filias\_Heidt](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@Filias\_Heidt](https://forum.ansible.com/u/Filias_Heidt)\
**Post date:** [September 3, 2015, 10:00am UTC](https://forum.ansible.com/t/looping-over-roles/13850/11 "2015-09-03T10:00:53Z")

</div>

I just had the same problem. But since your post is a few years old, I wondered if there might be a better solution by now. If there isn’t, I’ll try the “hack” :D.

Thanks!

---

<div class="post-metadata">

**Author:** ![cosbug](https://avatars.discourse-cdn.com/v4/letter/c/13edae/32.png) [@cosbug](https://forum.ansible.com/u/cosbug)\
**Post date:** [November 26, 2015, 5:46pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/12 "2015-11-26T17:46:12Z")

</div>

I have the dilemma.  
In my case the list size can vary so the above hack doesn’t work.

Does Ansible 2.0 solve this problem?

---

<div class="post-metadata">

**Author:** ![Filias\_Heidt](https://avatars.discourse-cdn.com/v4/letter/f/f05b48/32.png) [@Filias\_Heidt](https://forum.ansible.com/u/Filias_Heidt)\
**Post date:** [November 27, 2015, 12:04pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/13 "2015-11-27T12:04:58Z")

</div>

In ansible 2.0 include will be possible with with\_ – so that would solve this problem, I guess.

---

<div class="post-metadata">

**Author:** ![Bence\_Takacs](https://avatars.discourse-cdn.com/v4/letter/b/c6cbf5/32.png) [@Bence\_Takacs](https://forum.ansible.com/u/Bence_Takacs)\
**Post date:** [June 22, 2016, 2:59pm UTC](https://forum.ansible.com/t/looping-over-roles/13850/14 "2016-06-22T14:59:35Z")

</div>

I think a permanent solution is needed: many people is looking for that feature.  
[https://groups.google.com/forum/#!topic/ansible-project/B5547FiIhYA](https://groups.google.com/forum/#!topic/ansible-project/B5547FiIhYA)  
[http://phillbarber.blogspot.hu/2015/10/ansibles-for-loops.html](http://phillbarber.blogspot.hu/2015/10/ansibles-for-loops.html)

Is that solved in 2.0?  
Or only includes + with\_items (but for tasks only not for roles)  
… as written here: [http://stackoverflow.com/questions/30785281/one-loop-over-multiple-ansible-tasks#answer-35128533](http://stackoverflow.com/questions/30785281/one-loop-over-multiple-ansible-tasks#answer-35128533)

Regards:  
Bence

1. november 27., péntek 13:04:59 UTC+1 időpontban Filias Heidt a következőt írta:
