# Learning looping

**URL:** <https://forum.ansible.com/t/learning-looping/12359>\
**Category:** Ansible Project\
**Created:** [February 15, 2013, 12:43am UTC](https://forum.ansible.com/t/learning-looping/12359 "2013-02-15T00:43:31Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 12:43am UTC](https://forum.ansible.com/t/learning-looping/12359/1 "2013-02-15T00:43:31Z")

</div>

So i am try to learn how to do loops in the playbook :

So suppose for example i wanted to look through all hosts get their public key and add on all other nodes, So they can have password less access. This is the best example i could think of , doing loops in playbook. This should work in template but how do i do in playbook. (yml)

{% for host in groups[$hosts] %}

- authorized\_key: key={{hostvars[host][‘ansible\_ssh\_host\_key\_rsa\_public’]}}  
{% endfor %}

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [February 15, 2013, 12:52am UTC](https://forum.ansible.com/t/learning-looping/12359/2 "2013-02-15T00:52:27Z")

</div>

I would run 2 playbooks, both loop over all hosts. The first adds their keys to a file, the 2nd copies the filw

Brian Coca

---

<div class="post-metadata">

**Author:** ![Romeo\_Theriault](https://avatars.discourse-cdn.com/v4/letter/r/839c29/32.png) [@Romeo\_Theriault](https://forum.ansible.com/u/Romeo_Theriault)\
**Post date:** [February 15, 2013, 12:56am UTC](https://forum.ansible.com/t/learning-looping/12359/3 "2013-02-15T00:56:18Z")

</div>

Don't believe you can do this in the playbooks themselves. (Think there was  
some talk of maybe allowing playbooks to be templated... don't think that  
ever happened.)

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [February 15, 2013, 12:58am UTC](https://forum.ansible.com/t/learning-looping/12359/4 "2013-02-15T00:58:33Z")

</div>

I have templatesd playbooks, we generate them locally and then call ansible on them.

Brian Coca

---

<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:** [February 15, 2013, 1:03am UTC](https://forum.ansible.com/t/learning-looping/12359/5 "2013-02-15T01:03:01Z")

</div>

> > {% for host in groups[$hosts] %}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- authorized\_key:  
> > key={{hostvars[host]['ansible\_ssh\_host\_key\_rsa\_public']}}  
> > &nbsp;&nbsp;{% endfor %}
> 
> Don't believe you can do this in the playbooks themselves. (Think there was  
> some talk of maybe allowing playbooks to be templated... don't think that  
> ever happened.)

Yeah, this is a terrible idea because if you do that, your playbooks  
stop being valid data, and you can't just parse them by arbitrary  
software.

We loop by using things like with\_items.

---

<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:** [February 15, 2013, 1:06am UTC](https://forum.ansible.com/t/learning-looping/12359/6 "2013-02-15T01:06:30Z")

</div>

I'd keep it simple and define an array of keys and put that in a file  
like group\_vars/all.

tasks:

&nbsp;&nbsp;&nbsp;- authorized\_key: key=$item  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: $all\_my\_keys

It's also convient to just template out the authorized file directly,  
and put your conditional logic in the .j2 file.

---

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 3:58am UTC](https://forum.ansible.com/t/learning-looping/12359/7 "2013-02-15T03:58:44Z")

</div>

Thanks, This is helpful… Is there an example i can see (to populate $all\_my\_keys from all nodes) , Yes using templates was my last option, i just wanted to explore other possibilities.

Regards,–  
Kavin Kankeshwar

---

<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:** [February 15, 2013, 4:23am UTC](https://forum.ansible.com/t/learning-looping/12359/8 "2013-02-15T04:23:03Z")

</div>

Sure thing. Here is what I would try.

Either in a file specified by vars\_files or in a file named  
group\_vars/all alongside your playbook or group\_vars/groupname, I  
would define something like so:

---

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 4:44am UTC](https://forum.ansible.com/t/learning-looping/12359/9 "2013-02-15T04:44:28Z")

</div>

Thanks , So i should write another playbook to populate the group\_vars or i can do that on the fly ?

Regards,–  
Kavin Kankeshwar

---

<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:** [February 15, 2013, 1:13pm UTC](https://forum.ansible.com/t/learning-looping/12359/10 "2013-02-15T13:13:51Z")

</div>

You would write a YAML file, just data, rather than a playbook for this.

If your inventory is /path/hosts

group\_vars/all is just a YAML text file:

/path/group\_vars/all

---

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 9:56pm UTC](https://forum.ansible.com/t/learning-looping/12359/11 "2013-02-15T21:56:45Z")

</div>

Thanks, Related to looping:

Is it possible to do the following

my.yml

hosts=$hosts

tasks:

- action : something $item  
with\_items: $hosts

where $hosts is my group of servers im working on. So instead of putting in a list how do i create a list of all hosts this playbook is running on.

---

<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:** [February 15, 2013, 10:26pm UTC](https://forum.ansible.com/t/learning-looping/12359/12 "2013-02-15T22:26:52Z")

</div>

> Thanks, Related to looping:
> 
> Is it possible to do the following
> 
> my.yml
> 
> hosts=$hosts
> 
> tasks:  
> &nbsp;&nbsp;&nbsp;- action : something $item  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items: $hosts
> 
> where $hosts is my group of servers im working on. So instead of putting in  
> a list how do i create a list of all hosts this playbook is running on.

Not so much.

However, you don't typically need that kind of loop as you are already  
looping over those hosts for connectivity.

delegate\_to and local\_action are more natural in this case.

But in case you do want it, the following is available.

${groups.all} or ${groups.webservers} etc

Just be aware that if using that inside a play, it will still get  
executed once for every host in that play, so don't use it where you  
really meant local\_action or delegate\_to

Sorry, this is probably a bit incoherrent -- I would understand much  
better if we were talking about a specific use case.

---

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 10:54pm UTC](https://forum.ansible.com/t/learning-looping/12359/13 "2013-02-15T22:54:39Z")

</div>

So basically how do people do loop in a loop, Like playbook is looping through all the hosts in group , 1 by 1 , but for each node i want to again loop through the entire group and get something from all nodes and do it on 1 node.

Regards,–  
Kavin Kankeshwar

---

<div class="post-metadata">

**Author:** ![Kavin](https://avatars.discourse-cdn.com/v4/letter/k/ba8739/32.png) [@Kavin](https://forum.ansible.com/u/Kavin)\
**Post date:** [February 15, 2013, 11:09pm UTC](https://forum.ansible.com/t/learning-looping/12359/14 "2013-02-15T23:09:31Z")

</div>

Like 1 good example is :

So i have a group of servers,

I want to use the “with\_random\_choice” and make it use all the hosts in the group the playbook in running on. Then this will select randomly 1 node, Then in template i just want to use this random nodes internal IP.

How best can i achieve this, As this will give a fairly good understanding how to do things like this.

Regards,–  
Kavin Kankeshwar

---

<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:** [February 15, 2013, 11:12pm UTC](https://forum.ansible.com/t/learning-looping/12359/15 "2013-02-15T23:12:14Z")

</div>

Ok, got it.

With random choice will select a random string element, but that  
variable you select is namespaced, not a global or anything like that.

Thus you can't currently randomly select a host.

You can however assign a random probability that you select the host  
(may have to write a better filter plugin to do this), which is  
probably not what you want.

I'll think about syntax about how we could possibly make that cleaner.

Other folks may have some ideas too.
