Loop over the items of a list defined as a host variable for each host in a specific group

8,566 views
Skip to first unread message

Petros Moisiadis

unread,
Apr 28, 2014, 1:35:15 PM4/28/14
to ansible...@googlegroups.com
In a task, I am trying to figure out how I can loop over the items of a
list that is defined as a host variable for each host in a specific
group. This must be very common, but I can't think of a solution. I
suppose what I need is some kind of nested loops. An outer loop to loop
over the hosts in the group and an inner loop to loop over the items in
the list variable for each host in the outer loop. Is there a syntax for
this?

in hosts file:
[somegroup]
host1.example.org
host2.example.org

in host1.example.org host_vars files:
mylist:
- item1
- item2
- item3

in host2.example.org host_vars files:
mylist:
- item4
- item5

Adam Morris

unread,
Apr 28, 2014, 2:56:44 PM4/28/14
to ansible...@googlegroups.com


On Monday, April 28, 2014 10:35:15 AM UTC-7, Ernest0x wrote:
In a task, I am trying to figure out how I can loop over the items of a
list that is defined as a host variable for each host in a specific
group. 

I'm not sure what you are trying to do here so I can't offer too much advice.  It also depends on what you are planning on doing with those variables I suspect.  


Normally I only need to iterate over a list of variables for the current host.  But there are examples of accessing variables for groups of hosts on that page.

Adam 

Petros Moisiadis

unread,
Apr 28, 2014, 3:37:05 PM4/28/14
to ansible...@googlegroups.com
On 04/28/2014 09:56 PM, Adam Morris wrote:


On Monday, April 28, 2014 10:35:15 AM UTC-7, Ernest0x wrote:
In a task, I am trying to figure out how I can loop over the items of a
list that is defined as a host variable for each host in a specific
group. 

I'm not sure what you are trying to do here so I can't offer too much advice.  It also depends on what you are planning on doing with those variables I suspect.  


Given the example I wrote in my previous post, what I want is simply to have the task run for each item in  "mylist" for each host in "somegroup". Thus, have the task run for 5 times: for item1, item2, item3, item4 and item5.



Normally I only need to iterate over a list of variables for the current host.  But there are examples of accessing variables for groups of hosts on that page.


I already know about these 'magic' vars. The difficulty is not on how to get the data, but on how to construct the loop so that I get the iteration I want.

Adam 
--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/26c8f5ac-db7c-4171-8c7c-0f9605a212d4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael DeHaan

unread,
Apr 28, 2014, 7:57:55 PM4/28/14
to ansible...@googlegroups.com
"In a task, I am trying to figure out how I can loop over the items of a
list that is defined as a host variable for each host in a specific
group."

If the variable is "listvar"

with_items: listvar




Petros Moisiadis

unread,
Apr 29, 2014, 4:09:26 AM4/29/14
to ansible...@googlegroups.com
On 04/29/2014 02:57 AM, Michael DeHaan wrote:
"In a task, I am trying to figure out how I can loop over the items of a
list that is defined as a host variable for each host in a specific
group."

If the variable is "listvar"

with_items: listvar



What you suggest is the simplest form of a loop. It does not handle the "for each host in a specific group" part. What I want is that the task must run for all the items in each list for each host in a specific group. Particularly, I would need a mechanism, so that the outer loop loops over hosts and the inner loop uses the host in the current step in the outer loop to get the needed host variable.

In general, this is a common case of a nested loop with the inner loop using the value of the current step in the outer loop. Unfortunately, it seems that Ansible does not support this. The current implementation of "with_nested" loop expects its terms to be static lists all evaluated before the execution of the loop. It does not support the second list to be created dynamically for each step in the outer loop. So, I am considering to teach "with_nested" lookup to understand expressions with "item[0]" in the second term as expressions that should be reevaluated to a list for each item in the first term. For example, the loop I need could be simply written like this:

with_nested:
    - groups["somegroup"]
    - hostvars[item[0]].listvar

Would you accept a patch for that?

Michael DeHaan

unread,
Apr 29, 2014, 8:33:25 AM4/29/14
to ansible...@googlegroups.com
"It does not handle the "for each host in a specific group" part. "

with_items: groups.monitoring




Michael DeHaan

unread,
Apr 29, 2014, 8:35:35 AM4/29/14
to ansible...@googlegroups.com
" So, I am considering to teach "with_nested" lookup to understand expressions with "item[0]" in the second term as expressions that should be reevaluated to a list for each item in the first term"

Ansible is not meant to be a programming language, when syntax gets so complicated that it appears to become one, I feel a playbook is strongly going in the wrong direction.

It is usually useful to step back and think about the underlying use case, and there's a clean way to model it without trying to "program in YAML"

I find this problem mostly comes from users coming from Chef, but not always.

So, as such, I feel this is a bit of a slippery slope.  Rather than initially discussing the patch, let's understand what's the real world thing you are trying to configure, at a high level, and we can likely offer up some suggestions.



Petros Moisiadis

unread,
Apr 29, 2014, 10:03:23 AM4/29/14
to ansible...@googlegroups.com
On 04/29/14 15:35, Michael DeHaan wrote:
" So, I am considering to teach "with_nested" lookup to understand expressions with "item[0]" in the second term as expressions that should be reevaluated to a list for each item in the first term"

Ansible is not meant to be a programming language, when syntax gets so complicated that it appears to become one, I feel a playbook is strongly going in the wrong direction.

It is usually useful to step back and think about the underlying use case, and there's a clean way to model it without trying to "program in YAML"

I find this problem mostly comes from users coming from Chef, but not always.

So, as such, I feel this is a bit of a slippery slope.  Rather than initially discussing the patch, let's understand what's the real world thing you are trying to configure, at a high level, and we can likely offer up some suggestions.


My use case: I want a task to run for all network interfaces for each host in a specific group. Each host has a "network_interfaces" list variable.
I cannot be convinced that this is something that one should not be able to describe in a playbook.

Nevertheless, I have just patched the "with_nested" lookup to support item[0] in the nested loop list. I am doing some tests and I will soon send a pull request for it.

Adam Morris

unread,
Apr 29, 2014, 10:09:30 AM4/29/14
to ansible...@googlegroups.com


On Apr 29, 2014 7:03 AM, "'Petros Moisiadis' via Ansible Project" <ansible...@googlegroups.com> wrote:
>

>
> My use case: I want a task to run for all network interfaces for each host in a specific group. Each host has a "network_interfaces" list variable.
> I cannot be convinced that this is something that one should not be able to describe in a playbook.

>

That is not really a use case but a description.  What are you trying to do with these network interfaces?  Add them to a list? Build a dhcp configuration file? 

Adam

Michael DeHaan

unread,
Apr 29, 2014, 11:56:19 AM4/29/14
to ansible...@googlegroups.com
This feels like something that can be done with a group or inventory variable for me, and the basic host looping that is already in Ansible, coupled with a "with_items".

"My use case: I want a task to run for all network interfaces for each host in a specific group. Each host has a "network_interfaces" list variable"

- hosts: all_my_servers
  tasks:
     - example_module: some_arguments {{ item }}
       with_items: network_interfaces

If you need to delegate this command to different hosts than the one you are currently looping over (unlikely -- but possible) let me know -- but perhaps I'm missing something.





Adam

--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.

nZac

unread,
Apr 29, 2014, 1:43:49 PM4/29/14
to ansible...@googlegroups.com
"I want is simply to have the task run for each item in "mylist" for each host in "somegroup"."

Ansible loops through your groups and hosts and executes tasks against them. Therefore there is no need to manage an outer loop, Ansible does it for you and is central to how Ansible works.

"Thus, have the task run for 5 times: for item1, item2, item3, item4 and item5."

This inner loop is as simple as with_items as already suggested.

Does that help or did I confuse you more?

Adam Morris

unread,
May 1, 2014, 10:24:26 AM5/1/14
to ansible...@googlegroups.com

Actually I think that he is trying to configure something for a group of hosts rather than configure something on a group of hosts.  For example lets assume that you have a DHCP server and you want to configure static ip addresses for each of your servers. You could run through each host grabbing all of the MAC addresses and IP addresses from each server but you would only be configuring them on one server.

I am not saying that that is the case and I am curious as to what the case is, but that is an example of what I think we are being asked for here.

--
You received this message because you are subscribed to a topic in the Google Groups "Ansible Project" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ansible-project/RQYOP_yR5Yk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ansible-proje...@googlegroups.com.

To post to this group, send email to ansible...@googlegroups.com.

Michael DeHaan

unread,
May 1, 2014, 5:18:53 PM5/1/14
to ansible...@googlegroups.com
"Actually I think that he is trying to configure something for a group of hosts rather than configure something on a group of hosts."

Still:

   - hosts: whichever

       - local_action: shell echo one host name name is {{ item }}
         with_items: groups.monitoring




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.

To post to this group, send email to ansible...@googlegroups.com.

Petros Moisiadis

unread,
May 5, 2014, 9:28:56 AM5/5/14
to ansible...@googlegroups.com
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.

To post to this group, send email to ansible...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Case: From a specific host, run a command (e.g. ping) for all interfaces for each host in a specific group.

I have just sent a pull request (https://github.com/ansible/ansible/pull/7278) which would allow that.  The commit message includes an example which should make it clear to everyone.

Michael DeHaan

unread,
May 5, 2014, 11:50:41 PM5/5/14
to ansible...@googlegroups.com
Replied, didn't find the description very clear -- if you can update the formatting of this ticket to where the YAML is readable that would be helpful.




Reply all
Reply to author
Forward
0 new messages