# Templated file used as variable?

**URL:** <https://forum.ansible.com/t/templated-file-used-as-variable/15862>\
**Category:** Ansible Project\
**Created:** [August 5, 2014, 7:43pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862 "2014-08-05T19:43:57Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 5, 2014, 7:43pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/1 "2014-08-05T19:43:57Z")

</div>

How can I use the results from jinja2-templated file into a variable without some hack to write a file out and read it in again?

I’m using the ec2 module to create new EC2 instances. For this module, you can specify a multi-line string for the user\_data field. I’d like to use a template to create the string to use for this field. How can I do this?

The template module doesn’t seem to fit because it wants to write to an absolute destination at the target host, but I don’t want to write a file, I just need the templated output to use in a variable to pass along to the ec2 module.

I can write the data with {{ jinja2 variables }} directly in a playbook, but I want to re-use the same template for multiple playbooks that set up different instances with different values.

Tried the lookup(‘file’, ‘my-user-data.yml’) but it does not appear to be parsed by jinja2.

Perhaps I’m missing something obvious…?

---

<div class="post-metadata">

**Author:** ![Amr\_Ali](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@Amr\_Ali](https://forum.ansible.com/u/Amr_Ali)\
**Post date:** [August 6, 2014, 12:17am UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/2 "2014-08-06T00:17:46Z")

</div>

Why not just use a variables file, along with include\_vars.. you can even use a group or hosts var file..

What kind of "templating" options are you looking into using?

---

<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:** [August 6, 2014, 3:06pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/3 "2014-08-06T15:06:18Z")

</div>

“Tried the lookup(‘file’, ‘my-user-data.yml’) but it does not appear to be parsed by jinja2”

Not sure why this would be the case but would need to see the playbook.

Needs to be surrounded by “{{ }}” to evaluate of course, which may be part of the problem.

---

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 6, 2014, 11:24pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/4 "2014-08-06T23:24:59Z")

</div>

I created a simple example to demonstrate at [https://github.com/tdaws/ansible-templated-file-to-var-example](https://github.com/tdaws/ansible-templated-file-to-var-example). To try it directly, you can git clone [https://github.com/tdaws/ansible-templated-file-to-var-example](https://github.com/tdaws/ansible-templated-file-to-var-example) && run-me.sh  
Or you can browse the files directly. The run-me.sh script just shows what command I use to call the test.

Output contains the {{ }} notation instead of the replacement values desired:

TASK: [testrole | Test multiline templated var] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
ok: [localhost] =\> {  
“msg”: “#testfile.yml\nvar\_tests:\n - name: var\_from\_playbook\n v: {{ var\_from\_playbook }}\n\n - name: var\_from\_role\n v: {{ var\_from\_role }}”  
}

---

<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:** [August 7, 2014, 9:23pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/5 "2014-08-07T21:23:03Z")

</div>

The lookup plugin with “file” can’t be used to interpolate variables and read them back in.

Read the docs on the “include\_vars” module and you may be a bit happier, and it eliminates the overcomplex lookup attempt.

---

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 7, 2014, 10:09pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/6 "2014-08-07T22:09:03Z")

</div>

include\_vars helps by making a chunk of work re-usable; thanks! However in my use case, I would like to include text in one file into the variable file to finally be included in a task. I’ve updated the git repository to reflect this setup with use of include\_vars. The problem is that the output from dumping one multiline variable into another file in YAML format doesn’t indent each line to comply with the YAML multiline format.

The actual use case here is the use of the ec2 module to create new instances, and I am setting the user\_data field to some cloud-init YAML for use in the initial provisioning of CoreOS (I would prefer to use Ansible, but some of it can only be done as part of this cloudinit process). I want to write files during this process that are included directly in the cloud-config YAML, and so I would prefer to have those files as separate files in my Ansible setup, such as “bashrc.yml” for example, and include these inside a “cloudinit.yml” file that constructs the final text to use for the user\_data variable.

I found an awkward way to deal with this, though it does at least work. One can use the Jinja2 indent filter as I have in the code:

multilinevar\_from\_included\_varfile: |  
var\_tests:

- name: include some script in yaml format

script: |  
{{ script\_content\*\*|indent(4)\*\* }}"

If anyone knows of a cleaner way to do this I’d love to hear it.

Output from updated test without using the Jinja2 ‘indent’ filter:

var\_tests:

- name: var\_from\_playbook  
v: var\_from\_playbook\_VALUE

- name: var\_from\_role  
v: var\_from\_role\_VALUE

- name: include some script in yaml format  
script: #!/bin/bash  
echo this is my script!  
echo notice that the lines in the final output are not indented currently to be parsed correctly in the task file

---

<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:** [August 8, 2014, 2:45pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/7 "2014-08-08T14:45:34Z")

</div>

I’m sorry, I found your use case too confusing for me to understand - no offense implied - with what you were doing with lookup plugins.

I can’t help you explore it further.

This may just be the case of a mailing list making it hard to communicate, but things like "The problem is that the output from dumping one multiline variable into another file in YAML format doesn’t indent each line to comply with the YAML multiline format. " don’t make sense to me.

Embedding YAML in YAML isn’t really a thing, normally you would just keep a datastructure inside the YAML.

In ansible, you can also use the template module to dump YAML on demand like so:

“{{ foo | to\_yaml }}”

Which is really great if you have a datastructure.

You can also

“{{ foo | to\_json }}”

I hope this helps somewhat.

---

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 8, 2014, 9:30pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/8 "2014-08-08T21:30:33Z")

</div>

Michael, no need to apologize, you’ve already helped a lot, thank you!

One thing that would really help here and is general enough I’m sure it would find use elsewhere as well is to have the template module capable of outputting to a variable rather than a file. That certainly would help me in my case, and I’ve seen cases elsewhere while trying to improve my code for this where it would also have been helpful.

---

<div class="post-metadata">

**Author:** ![Michael\_Peters](https://avatars.discourse-cdn.com/v4/letter/m/c2a13f/32.png) [@Michael\_Peters](https://forum.ansible.com/u/Michael_Peters)\
**Post date:** [August 8, 2014, 9:34pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/9 "2014-08-08T21:34:19Z")

</div>

I don't know if you know this, but variables can themselves be  
templated. You can do this in a set\_fact or even in a variable file  
(group\_vars, host\_vars, var\_files, etc).

For instance:

set\_fact: foo={% if yada %}{{ (blah + baz) / 100 }}{% else %}{{ fiddly  
\* 100 }}{% endif %}

Or in a var file:

foo: {% if yada %}{{ (blah + baz) / 100 }}{% else %}{{ fiddly \* 100  
}}{% endif %}

So what case would a template file accomplish that template  
expressions wouldn't ?

---

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 8, 2014, 9:46pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/10 "2014-08-08T21:46:09Z")

</div>

For example, say I have file, .bashrc that I want to write to my target host during the cloud-init process. In some cases, like with CoreOS which sets files like this one read-only once cloud-init is complete, there are things you can do during cloud-init that you cannot do afterwards (otherwise I’d just use template module as usual). To make this happen with Ansible, I need to include the content of the file within the cloud-init YAML string which is passed in to the user\_data field of the ec2 ansible module. I would like to store a template like bashrc.j2 so I could modify it before it gets used within the user\_data string as part of that cloud\_init text, rather than awkwardly as part of a variable file in YAML format with a bunch of other files.

---

<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:** [August 8, 2014, 11:35pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/11 "2014-08-08T23:35:20Z")

</div>

"One thing that would really help here and is general enough I’m sure it would find use elsewhere as well is to have the template module capable of outputting to a variable rather than a file. That certainly would help me in my case, and I’ve seen cases elsewhere while trying to improve my code for this where it would also have been helpful. "

Yep, as indicated above, you can put templates directly in variable files, so this might not be needed.

---

<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:** [August 11, 2014, 2:45pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/12 "2014-08-11T14:45:07Z")

</div>

Excerpts from AJ Daws's message of 2014-08-08 17:30:33 -0400:

> Michael, no need to apologize, you've already helped a lot, thank you!
> 
> One thing that would really help here and is general enough I'm sure it  
> would find use elsewhere as well is to have the template module capable of  
> outputting to a variable rather than a file. That certainly would help me  
> in my case, and I've seen cases elsewhere while trying to improve my code  
> for this where it would also have been helpful.

There is also a template lookup plugin, no? This should evaluate the  
contents of a template:

&nbsp;&nbsp;&nbsp;&nbsp;{{ lookup('template', 'tmpl.j2') }}

---

<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:** [August 11, 2014, 6:03pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/13 "2014-08-11T18:03:40Z")

</div>

This is a little different. This will _evaluate_ the template at this point when it can.

I don’t recommend it.

---

<div class="post-metadata">

**Author:** ![AJ\_Daws](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@AJ\_Daws](https://forum.ansible.com/u/AJ_Daws)\
**Post date:** [August 15, 2014, 9:34pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/14 "2014-08-15T21:34:08Z")

</div>

This actually sounds like precisely what I was hoping for. Michael, can you let me know why you don’t recommend it? I assume by “evaluate” the template, you mean it will parse it with Jinja2, which seems to make sense…? Thanks for the help!

---

<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:** [August 16, 2014, 3:02pm UTC](https://forum.ansible.com/t/templated-file-used-as-variable/15862/15 "2014-08-16T15:02:35Z")

</div>

Complex templates should be used for laying down files.

In ansible, templates are not units of logic.

Basically it makes things arcane and very difficult to trace, things are meant to be data as much as possible, and only deviate when not possible.
