# Jinja2 for loop in templates

**URL:** <https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113>\
**Category:** Ansible Project\
**Tags:** ubuntu\
**Created:** [November 30, 2012, 10:42am UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113 "2012-11-30T10:42:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark\_Maas](https://avatars.discourse-cdn.com/v4/letter/m/7c8e57/32.png) [@Mark\_Maas](https://forum.ansible.com/u/Mark_Maas)\
**Post date:** [November 30, 2012, 10:42am UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/1 "2012-11-30T10:42:23Z")

</div>

Hi List,

I’m currently trying to roll out a default /etc/apt/sources.list and add “deb” lines to it for specific hosts.

The template sources.j2 looks like this:

> #############################################################
> 
> ################### OFFICIAL UBUNTU REPOS ###################
> 
> #############################################################
> 
> ###### Ubuntu Main Repos
> 
> deb [http://nl.archive.ubuntu.com/ubuntu/](http://nl.archive.ubuntu.com/ubuntu/) {{ ansible\_distribution\_release }} main restricted universe multiverse
> 
> ###### Ubuntu Update Repos
> 
> deb [http://nl.archive.ubuntu.com/ubuntu/](http://nl.archive.ubuntu.com/ubuntu/) {{ ansible\_distribution\_release }}-security main restricted universe multiverse
> 
> deb [http://nl.archive.ubuntu.com/ubuntu/](http://nl.archive.ubuntu.com/ubuntu/) {{ ansible\_distribution\_release }}-updates main restricted universe multiverse
> 
> ###### Ubuntu Partner Repo
> 
> deb [http://archive.canonical.com/ubuntu](http://archive.canonical.com/ubuntu) {{ ansible\_distribution\_release }} partner
> 
> deb-src [http://archive.canonical.com/ubuntu](http://archive.canonical.com/ubuntu) {{ ansible\_distribution\_release }} partner
> 
> ###### Ubuntu Opsview Repo
> 
> deb [https://XXXXXX:XXXXXXXX@downloads.opsview.com/opsview-commercial/latest/apt](https://XXXXXX:XXXXXXXX@downloads.opsview.com/opsview-commercial/latest/apt) {{ ansible\_distribution\_release }} main
> 
> {% for item in extra-apt-lines %}
> 
> {{ item }}
> 
> {% endfor %}

And one of the host\_vars has this added to it:

> * * *
> 
> extra-apt-lines:
> 
> - deb [http://oss.oracle.com/debian](http://oss.oracle.com/debian) unstable main non-free

The task itself, ofcourse:

> * * *
> 
> - name: APT | Kopieer apt-sources config
> 
> action: template src=~/playbooks/templates/sources.j2 dest=/etc/apt/sources.list owner=root group=root mode=0644
> 
> notify:
> 
> - reload apt
> 
> tags:
> 
> - apt

When I run this, I get this error message:

> fatal: [xmgtansible] =\> {‘msg’: “unsupported operand type(s) for -: ‘Undefined’ and ‘Undefined’”, ‘failed’: True}

I’m trying to base this of: [http://jinja.pocoo.org/docs/templates/](http://jinja.pocoo.org/docs/templates/)  
Any suggestions?

Thanks!  
Mark

---

<div class="post-metadata">

**Author:** ![Daniel\_Hokka\_Zakriss](https://avatars.discourse-cdn.com/v4/letter/d/f05b48/32.png) [@Daniel\_Hokka\_Zakriss](https://forum.ansible.com/u/Daniel_Hokka_Zakriss)\
**Post date:** [November 30, 2012, 10:48am UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/2 "2012-11-30T10:48:01Z")

</div>

Hi,

Mark Maas wrote:

> Hi List,
> 
> I'm currently trying to roll out a default /etc/apt/sources.list and add  
> "deb" lines to it for specific hosts.
> 
> The template sources.j2 looks like this:
> 
> \<snip\>  
> {% for item in extra-apt-lines %}

You can't have - in variable names. It's an operator. Name it  
extra\_apt\_lines or something instead, and things should be fine.

---

<div class="post-metadata">

**Author:** ![Mark\_Maas](https://avatars.discourse-cdn.com/v4/letter/m/7c8e57/32.png) [@Mark\_Maas](https://forum.ansible.com/u/Mark_Maas)\
**Post date:** [November 30, 2012, 11:00am UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/3 "2012-11-30T11:00:53Z")

</div>

Oh my. That simple a fix huh? Thanks! Good catch!

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [December 4, 2012, 7:52pm UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/4 "2012-12-04T19:52:56Z")

</div>

> > The template sources.j2 looks like this:

> > {% for item in extra-apt-lines %}
> 
> You can’t have - in variable names. It’s an operator. Name it  
> extra\_apt\_lines or something instead, and things should be fine.

Sorry for hijacking the thread, but looks like it already have been resolved…

On one of my machines I have bonded network interface that happens to be named “main-net0”. Yes, with a dash in the middle. Now, one of my templates requires IP number of the interface. This means to get the IP I need to address ansible\_main-net2.ipv4.address variable. And this causes the same “unsupported operand type” error.

How can I workaround the problem?

---

<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:** [December 4, 2012, 8:35pm UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/5 "2012-12-04T20:35:42Z")

</div>

You can't have those in variable names, and it's a little weird to do  
with Ansible's shorthand templating, but nothing wrong with:

{{ hostvars[$inventory\_hostname]["whatever variable name you  
want"]["some subkey"] }}

Should work.

Though IMHO the setup module should replace any "-" or "." with "\_" to  
simplify this problem.

---

<div class="post-metadata">

**Author:** ![Arie\_Skliarouk](https://avatars.discourse-cdn.com/v4/letter/a/edb3f5/32.png) [@Arie\_Skliarouk](https://forum.ansible.com/u/Arie_Skliarouk)\
**Post date:** [December 10, 2012, 12:22pm UTC](https://forum.ansible.com/t/jinja2-for-loop-in-templates/12113/6 "2012-12-10T12:22:34Z")

</div>

{% set mainnet0\_ip = hostvars[inventory\_hostname][“ansible\_main-net0”][“ipv4”][“address”] %}

worked perfectly, thank you!
