passing arguments to template

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, 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
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

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:
  template:
    src={{ item }}.conf.j2
    dest=/etc/apache/sites-available/{{ item }}.conf
  with_items:
    - site1.com
    - site2.com
    - 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>
    ServerAdmin xxx@xxx.com
    ServerName {% block name %}FIXME.com{% endblock name %}
    ServerAlias {{ self.name() }}

    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 for
the gory details.

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

Happy hacking,

Hi,

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
  • site2.com
  • 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
  • site2.com
  • site3.com

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!

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).

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...

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

Is it documented somewhere?

Thanks again.

Cheers,

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 = '''

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.