# Loop through inventory group and reference index of host

**URL:** <https://forum.ansible.com/t/loop-through-inventory-group-and-reference-index-of-host/24072>\
**Category:** Ansible Project\
**Created:** [March 27, 2017, 6:13pm UTC](https://forum.ansible.com/t/loop-through-inventory-group-and-reference-index-of-host/24072 "2017-03-27T18:13:44Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kevin\_Cackler](https://avatars.discourse-cdn.com/v4/letter/k/f4b2a3/32.png) [@Kevin\_Cackler](https://forum.ansible.com/u/Kevin_Cackler)\
**Post date:** [March 27, 2017, 6:13pm UTC](https://forum.ansible.com/t/loop-through-inventory-group-and-reference-index-of-host/24072/1 "2017-03-27T18:13:44Z")

</div>

I have an inventory file defined as follows:

`[app] app1.service.com ansible_host=192.168.1.1 app2.service.com ansible_host=192.168.1.2 app3.service.com ansible_host=192.168.1.3`

I need to generate multiple configuration files for each of those hosts. The current task looks like this:

`

- name: Create node-specific csync2 config files  
template:  
src: “templates/etc/csync2\_node.cfg”  
dest: “/etc/csync2\_{{ hostvars[item][‘ansible\_hostname’] }}.cfg”  
owner: root  
group: root  
backup: no  
with\_items: “{{ groups[csync2\_cluster\_nodes\_group] }}”  
`

And my template looks like this:

`nossl * *; group {{ hostvars[item]['ansible_hostname'] }} { {% for host in groups[csync2_cluster_nodes_group] %} {% if host != hostvars[item]['ansible_nodename'] %} host ({{ host }}); {% else %} host {{ host }}; {% endif %} {% endfor %} key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

This works correctly to generate template files like this:

`group app1 { host app1.service.com; host (app2.service.com); host (app3.service.com); key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

The problem is that this configuration is causing race conditions, so I need to chain the configurations. What I mean by this is that I need the app1 configuration file to look similar to

`group app1 { host app1.service.com; host (app2.service.com); key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

And the app2 config to look like:

`group app2 { host app2.service.com; host (app3.service.com); key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

And the app3 config to look like:

`group app3 { host app3.service.com; host (app1.service.com); key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

The best way to do this, so far as I can tell, is to utilize the index of the host within the template. The problem is that I’m not sure what the syntax would be to do so. I would like, in the config file, to do something like (Pseudo code since I don’t know the syntax for this)

`nossl * *; group {{ hostvars[item]['ansible_hostname'] }} { {% for host in groups[csync2_cluster_nodes_group] %} {% if host != hostvars[item]['ansible_nodename'] %} {# This "item" isn't the current "host", so check to see if this is the last item in the group #} {% if group.last == item %} {# this is the last host in the group, so pull the FIRST host from the group #} host ({{ hostvars[groups['app'][0]]['ansible_nodename'] }}); {# OK, this isn't the last host in the group, so pull the NEXT host from the group #} {% else %} host ({{ hostvars[groups['app'][groups.app.index(host)+1]]['ansible_nodename'] }}); {% endif %} {% else %} host {{ host }}; {% endif %} {% endfor %} key /etc/csync2/csync2.key; include /home; exclude *.log; exclude *.swp; exclude /home/ansible; auto younger; }`

I hope I’m explaining the problem clearly enough. I’m sure this is possible to achieve, but I’m just stuck on the proper syntax for achieving it.

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [March 27, 2017, 9:31pm UTC](https://forum.ansible.com/t/loop-through-inventory-group-and-reference-index-of-host/24072/2 "2017-03-27T21:31:40Z")

</div>

Hi Kevin

I'm assuming you're putting a config file for each server on some central server  
(it's not clear where the play is targeted, but it would explain hostvars).

[ even so, maybe you can replace:

&nbsp;&nbsp;&nbsp;&nbsp;hostvars[item]['ansible\_hostname']

with just

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item

? ]

It looks like you want each template to include the group member, plus the next  
member (unless it's the last, in which case go back to the first).

I've committed my share of template logic crimes, so this is from  
bitter experience: Jinja2 is limited for a good reason.

Why not just set a csync2\_backup\_member = x host var for each host?

It's pretty easy to see what's going on from glancing at the inventory that way,  
and you might find you need that information elsewhere sometime too  
(e.g. rolling upgrades or similar). And the template becomes trivial  
and readable.

Granted, you need to explicitly set a hostvar each time you add a  
host, but I promise  
future generations of sysadmins (or you in 3 months) will thank you  
for the clarity.
