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