# support passing new variables directly to the template module, but not only

**URL:** <https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089>\
**Category:** Ansible Project\
**Created:** [August 31, 2014, 3:16pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089 "2014-08-31T15:16:30Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Akos\_Vandra](https://avatars.discourse-cdn.com/v4/letter/a/8baadc/32.png) [@Akos\_Vandra](https://forum.ansible.com/u/Akos_Vandra)\
**Post date:** [August 31, 2014, 3:16pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/1 "2014-08-31T15:16:30Z")

</div>

Hello everyone!

I was asked to bring this up in the email list as well. Please see  
issues #8733 and #4546 for the origins of this email.

Just encountered the problem reported in #4546  
Due to openSSL not being able to accept extendedusagetypes from the  
command line, only from config files, I need to generate a temporary  
configuration file, so I would need to do something similar to this:

- template: src=openssl\_config.j2 dest=/tmp/openssl.cnf  
&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;usage: serverAuth  
- name: sign client csrs  
&nbsp;&nbsp;shell: openssl req -in {{item}} -config /tmp/openssl.cnf..... [sign items]  
&nbsp;&nbsp;with\_items: server\_certs

- template: src=openssl\_config.j2 dest=/tmp/openssl.cnf  
&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;usage: clientAuth  
- name: sign server csrs  
&nbsp;&nbsp;shell: openssl req -in {{item}} -config /tmp/openssl.cnf .....  
&nbsp;&nbsp;with\_items: client\_certs

Without being able to manipulate the usage variable passed to the  
template, one can not reuse the config template.

Of course this could be worked around by putting the two tasks into a  
different file, and then including it with parameters (which is  
supported btw), but it seems silly that one needs to do that if one  
wants to reuse the template.

I'd like to see the ability to pass in extra variables not implemented  
in the template module, but globally, so that one could include extra  
variables to \*any\* module, just like the when, or changed\_when, etc.  
work.

Regards,  
&nbsp;&nbsp;Akos Vandra

There was another comment to about 3 weeks ago from @iraksdale

""  
Have to agree with @claco here. I'm using a template to output  
multiple files based on a with\_dict loop, and semantically it kind of  
sucks to use item.key or item.value all over the template - doesn't  
make them very reusable.

It would be nice to define "service\_name" or "hostname" variables or  
whatever in the playbook where it's easy to see their relationship to  
the variable being looped, and have the templates use {{service\_name}}  
instead of having to put "whatever\_{{item.key}}" in the templates.

It really hinders the reuse of templates, because it marries them to a  
particular playbook structure, and the passthrough to the file module  
could be preserved if you just added a template\_vars argument that  
would make its contents available to the template.

As a new user to ansible, I'd say the lack of this is really  
counterintuitive. Is it possible to reconsider this decision? I think  
it adds a lot to the reusability & understandability of templates.  
""

Regards,  
&nbsp;&nbsp;Akos Vandra

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 2, 2014, 10:52pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/2 "2014-09-02T22:52:40Z")

</div>

Small request - when referencing tickets, hyperlinks keep me from copying and pasting every link and then clicking on them, and several thousand other people from doing the same 🙂 … I looked them up and summarized here.

The first ticket, which we declined as a feature early in our development. Not an issue per say but more of a feature request: [https://github.com/ansible/ansible/issues/4546](https://github.com/ansible/ansible/issues/4546). The ticket on [https://github.com/ansible/ansible/issues/8733](https://github.com/ansible/ansible/issues/8733) is a duplicate of 4546.

Basically I’d like to explore what your particular use case is, so that we can find an idiomatic solution in Ansible, if one exists.

Can we explore what you are modeling? I’m wanting to make sure this shouldn’t be a role, and so on, or that it can’t be done more natively in other ways.

I’m not opposed to the feature, but I’m also wanting to limit having 7000 different ways to set variables and pass them around, and in many cases this would be abused by folks doing “x={{x}}” and not knowing that all the variables are automatically passed down.

It may be that your particular use case does warrant this, but I would like to understand it if possible.

Thanks!

---

<div class="post-metadata">

**Author:** ![Akos\_Vandra](https://avatars.discourse-cdn.com/v4/letter/a/8baadc/32.png) [@Akos\_Vandra](https://forum.ansible.com/u/Akos_Vandra)\
**Post date:** [September 4, 2014, 9:20am UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/3 "2014-09-04T09:20:47Z")

</div>

Hi!

Sorry for not copying hyperlinks, I hate that too - I guess I just got  
too confortable with github doing that for me 🙂

I have written down a few use cases in my previous emails and the  
ticket, but I will summarize them here again for simplicity's sake.  
I have also just encountered another usecase, i'm detailing it as the first one.

The problem with the current setup is that by not being able to pass  
in, rename, or specify how to look up input variables, it hinders  
template reusability.

\*\*\* USE CASE 1 \*\*\*

I have a list of hosts, and for reasons outside the scope of this  
discussion, I need to create a /etc/hosts.d directory containing one  
entry per file, which will be concatenated into one /etc/hosts file by  
an incron job.

So I'd like to do this:

- template: src=foo.j2, dest=/etc/hosts.d/{{item}}  
dns={{hostvars[item].ansible\_hostname}}.vpn  
ip={{hostvars[item].ansible\_tun0.ipv4.address}}  
&nbsp;&nbsp;with\_items: {{ groups["vpn-clients"] }}

And yes, I could use that complicated lookup within the template, but  
would be mixing up layers. The tasks should know how to find out what  
to render, and templates should be dead simple, just render what is  
given to them.  
And I couldn't reuse this template if I'd hardcode the way to look up  
the tunnel0 interface address into them in case I would need (and I  
do) to  
add other interface addresses to the list, like so:

- template: src=foo.j2, dest=/etc/hosts.d/{{item}}  
dns={{hostvars[item].ansible\_hostname}}.public  
ip={{hostvars[item].ansible\_eth0.ipv4.address}}  
&nbsp;&nbsp;with\_items: {{ groups["all"] }}

\*\*\*\* USE CASE 2 \*\*\*\*

Due to openSSL not being able to accept extendedusagetypes from the  
command line, only from config files, I need to generate a temporary  
configuration file, so I would need to do something similar to this:

- template: src=openssl\_config.j2 dest=/tmp/openssl.cnf usage=serverAuth  
- name: sign client csrs  
&nbsp;&nbsp;shell: openssl req -in {{item}} -config /tmp/openssl.cnf..... [sign items]  
&nbsp;&nbsp;with\_items: server\_certs

- template: src=openssl\_config.j2 dest=/tmp/openssl.cnf usage=clientAuth  
- name: sign server csrs  
&nbsp;&nbsp;shell: openssl req -in {{item}} -config /tmp/openssl.cnf .....  
&nbsp;&nbsp;with\_items: client\_certs

\*\*\*\* USE CASE 3 \*\*\*\*

Very similar to Use case 1, it was mentioned by @ iraksdale in the  
first Issue on Gtihub:

Have to agree with @claco here. I'm using a template to output  
multiple files based on a with\_dict loop, and semantically it kind of  
sucks to use item.key or item.value all over the template - doesn't  
make them very reusable.

It would be nice to define "service\_name" or "hostname" variables or  
whatever in the playbook where it's easy to see their relationship to  
the variable being looped, and have the templates use {{service\_name}}  
instead of having to put "whatever\_{{item.key}}" in the templates.

Regards,  
&nbsp;&nbsp;Akos Vandra

---

<div class="post-metadata">

**Author:** ![Akos\_Vandra](https://avatars.discourse-cdn.com/v4/letter/a/8baadc/32.png) [@Akos\_Vandra](https://forum.ansible.com/u/Akos_Vandra)\
**Post date:** [September 4, 2014, 9:26am UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/4 "2014-09-04T09:26:30Z")

</div>

A plus for Use Case 1:

Adding fixed ip addresses like this:

- template: template: src=foo.j2, dest=/etc/hosts.d/localhost  
dns=localhost ip=127.0.0.1

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 5, 2014, 1:23am UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/5 "2014-09-05T01:23:46Z")

</div>

Thanks, I understand #1.

Use case #2 could be handled by:

- set\_fact: mode=‘serverAuth’

- template: …

- set\_fact: mode=‘clientAuth’

- template: …

Though I’d be tempted to use seperate templates and keep it simple.

---

<div class="post-metadata">

**Author:** ![Akos\_Vandra](https://avatars.discourse-cdn.com/v4/letter/a/8baadc/32.png) [@Akos\_Vandra](https://forum.ansible.com/u/Akos_Vandra)\
**Post date:** [September 5, 2014, 11:01am UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/6 "2014-09-05T11:01:06Z")

</div>

Use case 2 could be handled like that, but I feel that is just a  
work-around for a missing feature in ansible. Those two tasks actually  
is one single task that needed to be split into two parts because  
templates cannot receive a set of facts to use.

In fact I was tempted to work around the whole thing by creating a  
task file that included ONLY that one template creation task, and  
included passed the necessary variables to that, which is obviously a  
hack, and also does not work with with\_items, or with\_dict

- include: create\_template.yml foo=bar, baz=raz

Regards,  
&nbsp;&nbsp;Akos Vandra

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 5, 2014, 7:13pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/7 "2014-09-05T19:13:45Z")

</div>

Thanks, I understand the request. We’ll think about it.

---

<div class="post-metadata">

**Author:** ![Evgeny\_Goldin](https://avatars.discourse-cdn.com/v4/letter/e/848f3c/32.png) [@Evgeny\_Goldin](https://forum.ansible.com/u/Evgeny_Goldin)\
**Post date:** [January 21, 2015, 3:57am UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/8 "2015-01-21T03:57:39Z")

</div>

Hi,

Were there any decisions taken since then? I also vote for being able to send variables when generating a template. Other solutions (parametrized roles or extra “set\_fact” calls) look like heavy workarounds to a simple problem.

- template:  
src: …  
dest: …  
vars:  
service: …  
title: …

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [January 21, 2015, 3:01pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/9 "2015-01-21T15:01:12Z")

</div>

Not sure why you don't just set the vars at play level, they would be  
directly accessible by the template.

---

<div class="post-metadata">

**Author:** ![Evgeny\_Goldin](https://avatars.discourse-cdn.com/v4/letter/e/848f3c/32.png) [@Evgeny\_Goldin](https://forum.ansible.com/u/Evgeny_Goldin)\
**Post date:** [January 22, 2015, 2:32pm UTC](https://forum.ansible.com/t/support-passing-new-variables-directly-to-the-template-module-but-not-only/16089/10 "2015-01-22T14:32:12Z")

</div>

Hi,

This is similar to declaring global variables each time before making a function call. I may be wrong but I look at templates similarly. Today you can’t pass any arguments when making a call, only rely on global variables available in a play/role.

If a template is rendered within [with\_dict](https://github.com/evgeny-goldin/playbooks/blob/bab9d8d4ebb6a9d039333f770f79171787021631/playbooks/roles/test-repo/tasks/main.yml#L21) loop - it [ends up](https://github.com/evgeny-goldin/playbooks/blob/7a4ce25e0a3bf9edbb0150d1483861ba3c59a0d3/playbooks/roles/test-repo/templates/Simulation.scala#L8) using {{ item.key }} and {{ item.value }} (yuk!) rather than simpler names, passed into a template on each iteration. So templates are attached to variables naming in a play/role and _aren’t self-contained_, like a good old function. Any time variable names are changed in a play/role - template needs to be updated as well. It would be so much cleaner to say “This template needs variables ‘user’ and ‘account’ to render, pass it in”.

Have a look at Chef:

[http://docs.chef.io/templates.html](http://docs.chef.io/templates.html)

template “/etc/sudoers” do  
…  
variables({

:sudoers\_groups =\> node[:authorization][:sudo][:groups],  
:sudoers\_users =\> node[:authorization][:sudo][:users]  
})  
end

What is cleaner to use in a template - “sudoers\_groups” or “node[:authorization][:sudo][:groups]”? Not to mention what happens if the same template if rendered in different contexts where, say, node[:authorization][:sudo][:groups] is something else.  
Ansible answer to that will be - global “set\_fact” for _every_ variable before “template” call.
