# Iterating over a list in a dictionary within a Jinja2 template

**URL:** <https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960>\
**Category:** Ansible Project\
**Created:** [December 8, 2015, 10:57am UTC](https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960 "2015-12-08T10:57:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmacrae](https://avatars.discourse-cdn.com/v4/letter/c/2acd7d/32.png) [@cmacrae](https://forum.ansible.com/u/cmacrae)\
**Post date:** [December 8, 2015, 10:57am UTC](https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960/1 "2015-12-08T10:57:23Z")

</div>

Hi guys,

I’ve got something I’d really like some help on, not just the solution, but the understanding and perhaps any related documentation/articles.

I’m writing a role for deployment of Hubot.  
To define bots to be deployed, I’m using a dictionary, like so:

`  
hubot\_bots:  
testbot:  
owner: ‘Bot Wrangler [bw@example.com](mailto:bw@example.com)’  
name: Hubot  
descr: Delightfully aware robutt  
adapter: rocketchat  
environment:

- rocketchat\_room: GENERAL
- rocketchat\_user: Hubot
- rocketchat\_password: Hubot  
`

Using ‘with\_items’ I can iterate over items in ‘hubot\_bots’, like ‘testbot’ here, and create resources, such as directories named after the key ‘testbot’ and then run commands accessing the values using ‘item.value.owner’ and ‘item.value.adapter’, etc.

Now, for each of these bot definitions, I want to deploy a Systemd service file, for management of each bot process.  
Within this template, I want to refer to some of the values as defined above, including iterating over each key/value in the ‘environment’ list.

I tried my best the other evening with a few combinations of ‘with\_dict’ and ‘with\_nested’ and felt I was making some progress, but definitely not getting the desired results, nor understanding how it was working.

Here’s the task I’m deploying the template with:

`

- name: Deploy service files for each Hubot  
template:  
src: hubot.service.j2  
dest: /usr/lib/systemd/system/hubot-{{ item.key }}.service  
owner: root  
group: root  
mode: 0644  
with\_dict: hubot\_bots

`

And here’s the template I’m using:

`  
[Unit]  
Description=Hubot-{{ item }}  
Requires=network.target  
After=network.target

[Service]  
Type=simple  
WorkingDirectory={{ hubot\_village\_path }}/{{ item }}  
User={{ hubot\_admin\_user }}

Restart=always  
RestartSec=10

{% for env in item.value.environment %}  
Environment={{ env|upper}}={{ env.value }}  
{% endfor %}

ExecStart={{ hubot\_village\_path }}/{{ item }}/bin/hubot --adapter {{ item.value.adapter }}

[Install]  
WantedBy=multi-user.target

`

As you can see, I want to refer to each bot defined under ‘hubot\_bots’ and then some other values.

Would anyone be able to point me in the right direction on how to get the desired outcome, and understand how this works.  
Any documentation or articles would be great. I’m still grasping concepts with YAML structures and the Jinja2 template engine - I’d love to learn as much as I can about it, as I can see it can be very powerful.

So, thank you so much in advance if anyone can help me on this!

Kind Regards,  
Calum

---

<div class="post-metadata">

**Author:** ![Mike\_Biancaniello](https://avatars.discourse-cdn.com/v4/letter/m/dec6dc/32.png) [@Mike\_Biancaniello](https://forum.ansible.com/u/Mike_Biancaniello)\
**Post date:** [December 8, 2015, 3:06pm UTC](https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960/2 "2015-12-08T15:06:07Z")

</div>

First, in your j2, you can’t ever reference `item` without `item.key` or `item.value`.

However, I think your amin problem is that your first iteration is a dict (not a list) and the second is a list of dicts without deterministic keys.

Try this:

`

hubot\_bots:  
testbot:  
owner: ‘Bot Wrangler [b...@example.com](mailto:b...@example.com)’  
name: Hubot  
descr: Delightfully aware robutt  
adapter: rocketchat  
environment:

- key: rocketchat\_room  
value: GENERAL
- key: rocketchat\_user  
value: Hubot
- key: rocketchat\_password  
value: Hubot  
`

or:

`hubot_bots: testbot: owner: 'Bot Wrangler <b...@example.com>' name: Hubot descr: Delightfully aware robutt adapter: rocketchat environment: rocketchat_room: GENERAL rocketchat_user: Hubot rocketchat_password: Hubot`

You could also go with with\_items and change the vars to:

`  
hubot\_bots:

- label: testbot  
owner: ‘Bot Wrangler [b...@example.com](mailto:b...@example.com)’  
name: Hubot  
descr: Delightfully aware robutt  
adapter: rocketchat  
environment:  
rocketchat\_room: GENERAL  
rocketchat\_user: Hubot  
rocketchat\_password: Hubot  
`

---

<div class="post-metadata">

**Author:** ![cmacrae](https://avatars.discourse-cdn.com/v4/letter/c/2acd7d/32.png) [@cmacrae](https://forum.ansible.com/u/cmacrae)\
**Post date:** [December 11, 2015, 2:51pm UTC](https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960/3 "2015-12-11T14:51:51Z")

</div>

Thanks Mike! I’ll take a go at using this 🙂

---

<div class="post-metadata">

**Author:** ![cmacrae](https://avatars.discourse-cdn.com/v4/letter/c/2acd7d/32.png) [@cmacrae](https://forum.ansible.com/u/cmacrae)\
**Post date:** [December 14, 2015, 3:38pm UTC](https://forum.ansible.com/t/iterating-over-a-list-in-a-dictionary-within-a-jinja2-template/19960/4 "2015-12-14T15:38:38Z")

</div>

So, I solved what I wanted to do 🙂  
For anyone interested, here’s how I got it working:

Bot definition looks like this:

`

hubot\_bots:  
testbot:  
owner: ‘Bot Wrangler \<[bw@example.com](mailto:bw@example.com)\>’  
name: Hubot  
descr: Delightfully aware robutt  
adapter: rocketchat  
environment:

- rocketchat\_room: GENERAL
- rocketchat\_user: Hubot
- rocketchat\_password: Hubot

`

Task that deploys the template which reads the above values, looks like this:

`

- name: Deploy service files for each Hubot  
template:  
src: hubot.service.j2  
dest: /usr/lib/systemd/system/hubot-{{ item.key }}.service  
owner: root  
group: root  
mode: 0644  
with\_dict: hubot\_bots  
`

And finally, the Jinja2 code that does what I need (the significant part being the for loops):

`  
[Unit]  
Description=Hubot-{{ item.key }}  
Requires=network.target  
After=network.target

[Service]  
Type=simple  
WorkingDirectory={{ hubot\_village\_path }}/{{ item.key }}  
User={{ hubot\_admin\_user }}

Restart=always  
RestartSec=10

{% for env in item.value.environment %}  
{% for k, v in env.items() %}  
Environment={{ k |upper }}={{ v }}  
{% endfor %}  
{% endfor %}

ExecStart={{ hubot\_village\_path }}/{{ item.key }}/bin/hubot --adapter {{ item.value.adapter }}

[Install]  
WantedBy=multi-user.target  
`

Hope this helps anyone that stumbles upon it!
