Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I test jinja2 templates in ansible?

Sometimes I need to test some jinja2 templates that I use in my ansible roles. What is the simplest way for doing this?

For example, I have a template (test.j2):

{% if users is defined and users %}
{% for user in users %}{{ user }}
{% endfor %}
{% endif %}

and vars (in group_vars/all):

---
users:
  - Mike
  - Smith
  - Klara
  - Alex
like image 588
Alex Avatar asked Feb 15 '16 11:02

Alex


People also ask

Does Ansible use Jinja2 template?

Ansible uses Jinja2 templating to enable dynamic expressions and access to variables and facts. You can use templating with the template module.

What is the main advantage purpose of using Jinja2 template within Ansible?

Jinja2 templates are simple template files that store variables that can change from time to time. When Playbooks are executed, these variables get replaced by actual values defined in Ansible Playbooks. This way, templating offers an efficient and flexible solution to create or alter configuration file with ease.


3 Answers

At this time exists 4 different variants:

1_Online (using https://cryptic-cliffs-32040.herokuapp.com/)
Based on jinja2-live-parser code.

Example

2_Interactive (using python and library jinja2, PyYaml)

import yaml from jinja2 import Template >>> template = Template(""" ... {% if users is defined and users %} ... {% for user in users %}{{ user }} ... {% endfor %} ... {% endif %} ... """) >>> values = yaml.load(""" ... --- ... users: ...   - Mike ...   - Smith ...   - Klara ...   - Alex ... """) >>> print "{}".format(template.render(values))   Mike Smith Klara Alex 

3_Ansible (using --check)
Create test playbook jinja2test.yml:

--- - hosts: 127.0.0.1   tasks:   - name: Test jinja2template     template: src=test.j2 dest=test.conf 

and run it:

ansible-playbook jinja2test.yml --check --diff --connection=local 

sample output:

PLAY [127.0.0.1] **************************************************************  GATHERING FACTS ***************************************************************  ok: [127.0.0.1]  TASK: [Test jinja2template] *************************************************** --- before: test.conf +++ after: /Users/user/ansible/test.j2 @@ -0,0 +1,4 @@ +Mike +Smith +Klara +Alex  changed: [127.0.0.1]  PLAY RECAP ******************************************************************** 127.0.0.1                  : ok=2    changed=1    unreachable=0    failed=0 

4_Ansible (using -m template) thanks for @artburkart

Make a file called test.txt.j2

{% if users is defined and users %} {% for user in users %} {{ user }} {% endfor %} {% endif %} 

Call ansible like so:

ansible all -i "localhost," -c local -m template -a "src=test.txt.j2 dest=./test.txt" --extra-vars='{"users": ["Mike", "Smith", "Klara", "Alex"]}' 

It will output a file called test.txt in the current directory, which will contain the output of the evaluated test.txt.j2 template.

I understand this doesn't directly use a vars file, but I think it's the simplest way to test a template without using any external dependencies. Also, I believe there are some differences between what the jinja2 library provides and what ansible provides, so using ansible directly circumvents any discrepancies. When the JSON that is fed to --extra-vars satisfies your needs, you can convert it to YAML and be on your way.

like image 177
Alex Avatar answered Oct 06 '22 12:10

Alex


If you have a jinja2 template called test.j2 and a vars file located at group_vars/all.yml, then you can test the template with the following command:

ansible all -i localhost, -c local -m template -a "src=test.j2 dest=./test.txt" --extra-vars=@group_vars/all.yml

It will output a file called test.txt in the current directory, which will contain the output of the evaluated test.j2 template.

I think this is the simplest way to test a template without using any external dependencies. Also, there are differences between what the jinja2 library provides and what ansible provides, so using ansible directly circumvents any discrepancies. It's also possible to test ad-hoc variables without making an additional vars file by using JSON:

ansible all -i "localhost," -c local -m template -a "src=test.j2 dest=./test.txt" --extra-vars='{"users": ["Mike", "Smith", "Klara", "Alex"]}'
like image 39
artburkart Avatar answered Oct 06 '22 10:10

artburkart


You can use the debug module

tasks: 
- name: show templating results
  debug:
   msg: "{{ lookup('template', 'template-test.j2') }}"
like image 41
Maoz Zadok Avatar answered Oct 06 '22 12:10

Maoz Zadok