# passing arguments to template

**URL:** <https://forum.ansible.com/t/passing-arguments-to-template/12964>\
**Category:** Ansible Project\
**Created:** [June 15, 2013, 1:46pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964 "2013-06-15T13:46:30Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![javawebdeveloper](https://avatars.discourse-cdn.com/v4/letter/j/ba8739/32.png) [@javawebdeveloper](https://forum.ansible.com/u/javawebdeveloper)\
**Post date:** [June 15, 2013, 1:46pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/1 "2013-06-15T13:46:30Z")

</div>

Hello all!  
I would like to do the following:

- name: Setup apache config for site  
template: src=generic\_site.j2 dest=/etc/apache2/sites-available/{{ item }} group=root owner=root  
with\_items: ${sites}

#sites: [[website1.com](http://website1.com), [website2.com](http://website2.com)]

This works to generate both sites in the correct location. However, I want to refer to the {{ item }} value in the template:

\<VirtualHost \*:80\>  
ServerAdmin [xxx@xxx.com](mailto:xxx@xxx.com)  
ServerName {{ item }}  
ServerAlias {{ item }}

DocumentRoot /var/www/{{ item }}

Options FollowSymLinks AllowOverride None

\<Directory “/var/www/{{ item }}”\>  
Options Indexes FollowSymLinks MultiViews  
AllowOverride None  
Order allow,deny  
allow from all

ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/  
\<Directory “/usr/lib/cgi-bin”\>  
AllowOverride None  
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch  
Order allow,deny  
Allow from all

ErrorLog ${APACHE\_LOG\_DIR}/{{ item }}/error.log

# Possible values include: debug, info, notice, warn, error, crit,

# alert, emerg.

LogLevel warn

CustomLog ${APACHE\_LOG\_DIR}/{{ item }}/access.log combined

Is there anyway to do this? I have only found that you can refer to the {{item}} in the values of the template (src/dest), but not inside the template. I appreciate any help in advance!

Thanks,  
Brent

---

<div class="post-metadata">

**Author:** ![pancho\_horrillo](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@pancho\_horrillo](https://forum.ansible.com/u/pancho_horrillo)\
**Post date:** [September 1, 2013, 5:53am UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/2 "2013-09-01T05:53:12Z")

</div>

Hi, there!

I came across the same core difficulty a couple of days ago, and  
thanks to the insight provided by a work mate (thanks, Carlos!), we  
figured out a way to do this.

There seems to be no way to pass parameters or alter the context in  
any way to the template module. But using Jinja2 template  
inheritance, we can do what is needed with minimal fuss. Let me show  
you how:

tasks/main.yml:  
- name: Copy some templates over:  
&nbsp;&nbsp;template:  
&nbsp;&nbsp;&nbsp;&nbsp;src={{ item }}.conf.j2  
&nbsp;&nbsp;&nbsp;&nbsp;dest=/etc/apache/sites-available/{{ item }}.conf  
&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;- site1.com  
&nbsp;&nbsp;&nbsp;&nbsp;- site2.com  
&nbsp;&nbsp;&nbsp;&nbsp;- site3.com

As you can see, we have one template file for each of the sites, but  
fear not! They are pretty small ones.  
The main content lives in a base template:

files/base/site.conf.j2:  
# {{ ansible\_managed }}  
\<VirtualHost \*:80\>  
&nbsp;&nbsp;&nbsp;&nbsp;ServerAdmin xxx@xxx.com  
&nbsp;&nbsp;&nbsp;&nbsp;ServerName {% block name %}FIXME.com{% endblock name %}  
&nbsp;&nbsp;&nbsp;&nbsp;ServerAlias {{ self.name() }}

&nbsp;&nbsp;&nbsp;&nbsp;DocumentRoot /var/www/{{ self.name() }}  
...

And the particulars of each site live on separate files:

files/site1.com.conf.j2:  
{% extends "base/site.conf.j2" %}  
{% block name %}site1.com{% endblock name %}

files/site2.com.conf.j2:  
{% extends "base/site.conf.j2" %}  
{% block name %}site2.com{% endblock name %}

files/site3.com.conf.j2:  
{% extends "base/site.conf.j2" %}  
{% block name %}site3.com{% endblock name %}

See [http://jinja.pocoo.org/docs/templates/#template-inheritance](http://jinja.pocoo.org/docs/templates/#template-inheritance) for  
the gory details.

Hope that it helps. But if anybody has a better solution, I'd love to  
hear about it.

Happy hacking,

---

<div class="post-metadata">

**Author:** ![David\_Karban](https://avatars.discourse-cdn.com/v4/letter/d/90db22/32.png) [@David\_Karban](https://forum.ansible.com/u/David_Karban)\
**Post date:** [September 1, 2013, 6:17am UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/3 "2013-09-01T06:17:56Z")

</div>

Hi,

---

<div class="post-metadata">

**Author:** ![James\_Cammarata1](https://avatars.discourse-cdn.com/v4/letter/j/d26b3c/32.png) [@James\_Cammarata1](https://forum.ansible.com/u/James_Cammarata1)\
**Post date:** [September 1, 2013, 6:49am UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/4 "2013-09-01T06:49:37Z")

</div>

You’re mixing up your syntax there a bit. When you specify the module options in regular YAML syntax, you need to do it like this:

- name: Copy some templates over:  
template:  
src: {{ item }}.conf.j2  
dest: /etc/apache/sites-available/{{ item }}.conf  
with\_items:
- [site1.com](http://site1.com/)
- [site2.com](http://site2.com/)
- [site3.com](http://site3.com/)

If you want to just carry them onto the next line, use the YAML line continuation synax:

- name: Copy some templates over:  
template: \>  
src={{ item }}.conf.j2 \>  
dest=/etc/apache/sites-available/{{ item }}.conf  
with\_items:
- [site1.com](http://site1.com/)
- [site2.com](http://site2.com/)
- [site3.com](http://site3.com/)

---

<div class="post-metadata">

**Author:** ![pancho\_horrillo](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@pancho\_horrillo](https://forum.ansible.com/u/pancho_horrillo)\
**Post date:** [September 2, 2013, 1:34pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/5 "2013-09-02T13:34:56Z")

</div>

> Hi,
> 
> >

Hello!

> > Is there anyway to do this? I have only found that you can refer to the  
> > {{item}} in the values of the template (src/dest), but not inside the  
> > template. I appreciate any help in advance!
> 
> what version of Ansible do you use? Just used {{ item }} inside template  
> yesterday without problem on 1.3 from git.

I was using release 1.2.3.  
So, great news that 1.3 can do it.

Thanks!

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 2, 2013, 2:43pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/6 "2013-09-02T14:43:36Z")

</div>

I should point out you can avoid needing the template inheritance by just leveraging the {{ item }} variable inside the template (with if statements if you like, too).

---

<div class="post-metadata">

**Author:** ![pancho\_horrillo](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@pancho\_horrillo](https://forum.ansible.com/u/pancho_horrillo)\
**Post date:** [September 2, 2013, 3:04pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/7 "2013-09-02T15:04:36Z")

</div>

Replying to myself:

[...]

> > what version of Ansible do you use? Just used {{ item }} inside template  
> > yesterday without problem on 1.3 from git.
> 
> I was using release 1.2.3.

I just checked with 1.2.3, and it works too! I guess that I was more  
thick than usual when I did the test...

---

<div class="post-metadata">

**Author:** ![pancho\_horrillo](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@pancho\_horrillo](https://forum.ansible.com/u/pancho_horrillo)\
**Post date:** [September 2, 2013, 3:07pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/8 "2013-09-02T15:07:33Z")

</div>

It works, thanks! I must have made a mistake when I first tried to set it up.

Is it documented somewhere?

Thanks again.

Cheers,

---

<div class="post-metadata">

**Author:** ![pancho\_horrillo](https://avatars.discourse-cdn.com/v4/letter/p/ebca7d/32.png) [@pancho\_horrillo](https://forum.ansible.com/u/pancho_horrillo)\
**Post date:** [September 2, 2013, 3:16pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/9 "2013-09-02T15:16:29Z")

</div>

Hi!

Thanks for pointing this out to me, James!

However, I was shocked, because all my playbooks are written like  
that, and they work OK.  
So I've been digging a bit. It seems that ansible loads the playbook  
using yaml.load\_safe().  
I've written a simple python script that, using the same method,  
manages to read the YAML as desired:

file: load-and-dump-yaml  
#!/usr/bin/env python2

import yaml

doc = '''

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [September 2, 2013, 3:20pm UTC](https://forum.ansible.com/t/passing-arguments-to-template/12964/10 "2013-09-02T15:20:06Z")

</div>

Excerpts from pancho horrillo's message of 2013-09-02 11:16:29 -0400:

> As you can see, the "value" to the template "key" is OK.
> 
> I guess that the yaml parser that ships with python2 is a bit lax.

PyYAML seems to treat this the same as if you'd used the '\>' line  
continuation marker, probably because there's no other reasonable  
interpretation of this in YAML.

Haven't bother to look and see if this is actually in the YAML spec,  
but, for what it's worth, yamllint.com also seems fine with it.
