# Parsing playbooks with full Jinja templating

**URL:** <https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413>\
**Category:** Ansible Project\
**Created:** [February 2, 2015, 12:15am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413 "2015-02-02T00:15:47Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 12:15am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/1 "2015-02-02T00:15:47Z")

</div>

Hi Ansible developers,

I’ve been wondering about something. Ansible’s syntax for module arguments is key=value parameters, all on a single line. This then needs to be parsed, and the key=value elements properly separated.

Wouldn’t it be much nicer if the module parameters were also just written in YAML syntax? For example:

- hosts: all  
tasks:
- name: blah  
yum:
- name: package
- state: installed

And it might even be an idea to pass the playbook through Jinja first, allowing things like:

- name: blah  
yum:  
{% for pkg in packages %}
- name: “{{ pkg }}”
- state: installed  
{% endfor %}

We would not need the “when:” conditional, or the shlex module to split key=value pairs. This would allow taking full advantage of Jinja’s templating features.

Could this be an idea for Ansible 2.0?

Regards,  
Anand

---

<div class="post-metadata">

**Author:** ![Tom\_Bamford](https://avatars.discourse-cdn.com/v4/letter/t/c2a13f/32.png) [@Tom\_Bamford](https://forum.ansible.com/u/Tom_Bamford)\
**Post date:** [February 2, 2015, 12:24am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/2 "2015-02-02T00:24:46Z")

</div>

Hi Anand

You actually can (and I prefer to) write your playbooks with that kind of plain YAML syntax. e.g.

```auto
- hosts: localhost
  tasks:
    - name: blah
      yum:
        name:
          - mypackage
          - otherpackage
        state: present
    - name: blurh
      copy:
        src: myfile
        dest: /tmp/myfile
        mode: 0640
        owner: me

```

It gets more interesting with the shell and command modules

```auto
- hosts: localhost
  tasks:
    - name: run this
      shell: mycommand
      args:
        creates: /tmp/artefact
        chdir: /path/to/dir
        executable: /bin/bash

```

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 12:33am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/3 "2015-02-02T00:33:54Z")

</div>

Thanks Tom! I didn’t realise it was already possible! So I can also use Jinja functions in a playbook to include/exclude some parameters based on facts?

---

<div class="post-metadata">

**Author:** ![Giovanni\_Tirloni](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Giovanni\_Tirloni](https://forum.ansible.com/u/Giovanni_Tirloni)\
**Post date:** [February 2, 2015, 12:34am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/4 "2015-02-02T00:34:03Z")

</div>

Same here. Otherwise I've found sometimes I have to decide which one to  
use, where to put quotes, etc. I just go 100% YAML and the INI files.

Ansible's syntax with the equal signs is more concise but I don't mind  
the extra lines with YAML.

Giovanni

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 9:58am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/5 "2015-02-02T09:58:30Z")

</div>

Hi Tom,

I just tried the syntax you suggested.

My very simple playbook is:

- hosts: myhost  
tasks:
- name: install packages  
yum:  
name:
- screen
- tmux  
state: installed

However, when I run this, I get an errors:

SUDO-SUCCESS-ziubbkxxzglhrtsmdmekoixffubflanc  
Traceback (most recent call last):  
File “/tmp/ansible-tmp-1422870182.84-7050423984136/yum”, line 2402, in   
main()  
File “/tmp/ansible-tmp-1422870182.84-7050423984136/yum”, line 832, in main  
disablerepo, disable\_gpg\_check)  
File “/tmp/ansible-tmp-1422870182.84-7050423984136/yum”, line 717, in ensure  
items = pkgspec.split(‘,’)  
AttributeError: ‘list’ object has no attribute ‘split’

Are you certain that plain YAML syntax works for modules?

---

<div class="post-metadata">

**Author:** ![Giovanni\_Tirloni](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Giovanni\_Tirloni](https://forum.ansible.com/u/Giovanni_Tirloni)\
**Post date:** [February 2, 2015, 10:10am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/6 "2015-02-02T10:10:31Z")

</div>

- hosts: myhost  
&nbsp;&nbsp;tasks:  
&nbsp;&nbsp;&nbsp;&nbsp;- name: install packages  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yum:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name: "{{ item }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state: latest  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- screen  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- tmux

Useful reading:  
[http://docs.ansible.com/playbooks\_loops.html](http://docs.ansible.com/playbooks_loops.html)

Giovanni

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 10:34am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/7 "2015-02-02T10:34:31Z")

</div>

Hi Giovanni,

Your suggestion works. But I think what I was trying to say is that Ansible’s playbook syntax is mixed. Wouldn’t it be cool if it were pure YAML, with Jinja templating? Then it would allow something like:

- hosts: myhost  
tasks:
- name: install packages  
yum:  
name:
- tmux
- screen  
{% if ansible\_distribution\_major\_version == ‘6’ %}
- lsof  
{% endif %}

Instead of inventing ansible-specific loops, we could just use the power of Jinja templating.

---

<div class="post-metadata">

**Author:** ![Giovanni\_Tirloni](https://avatars.discourse-cdn.com/v4/letter/g/71c47a/32.png) [@Giovanni\_Tirloni](https://forum.ansible.com/u/Giovanni_Tirloni)\
**Post date:** [February 2, 2015, 11:19am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/8 "2015-02-02T11:19:08Z")

</div>

As an Ansible newbie, I have struggled with understanding where it's  
Ansible or Jinja2 doing the parsing. So I can surely related to that. On  
the other hand, Ansible tries to be simple and the looping constructs,  
IMHO, are easy to work with and have a concise syntax.

I don't have enough experience with Ansible to suggest where it should  
go next.

In my so far very limited knowledge of Ansible, I would suggest  
encapsulating these things in different roles (e.g. common\_debian,  
common\_centos6, common\_centos7). It seems more idiomatic in Ansible,  
based on the examples I've seen so far.

Giovanni

---

<div class="post-metadata">

**Author:** ![Tom\_Bamford](https://avatars.discourse-cdn.com/v4/letter/t/c2a13f/32.png) [@Tom\_Bamford](https://forum.ansible.com/u/Tom_Bamford)\
**Post date:** [February 2, 2015, 11:48am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/9 "2015-02-02T11:48:18Z")

</div>

Hi Anand

Are you sure your indenting is correct? Here’s an example from one of my role task files, known working with Ansible v1.8.2 (packages trimmed for brevity)

```auto
---
- name: Install packages (apt)
  apt:
    pkg:
      - bash-completion
      - bind9utils
      - vim-nox
      - zsh
    state: present
  when: ansible_os_family == 'Debian'

- name: Install packages (yum)
  yum:
    name:
      - bind-utils
      - byobu
      - vim-enhanced
      - zsh
    state: present
  when: ansible_os_family == 'RedHat'

```

​

---

<div class="post-metadata">

**Author:** ![Tom\_Bamford](https://avatars.discourse-cdn.com/v4/letter/t/c2a13f/32.png) [@Tom\_Bamford](https://forum.ansible.com/u/Tom_Bamford)\
**Post date:** [February 2, 2015, 11:52am UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/10 "2015-02-02T11:52:26Z")

</div>

Jinja templating doesn’t work in playbooks in that way. Lots of variable constructs are actually parsed with jinja2, so you can do stuff like

```auto
- set_fact:
    myvar: "{% if something %}this{% else %}that{% endif %}"

```

As Giovanni mentioned, there are numerous looping constructs for things like task repetition. Playbooks are declarative, so it wouldn’t really be right to build them from a template.

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 3:13pm UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/11 "2015-02-02T15:13:04Z")

</div>

Hello Tom,

I am certain that my syntax and indentation is correct. I have created a test role, called packages, and in the main.yml file of the tasks directory of this role, I have:

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 3:17pm UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/12 "2015-02-02T15:17:20Z")

</div>

As an Ansible newbie, I have struggled with understanding where it's

> Ansible or Jinja2 doing the parsing. So I can surely related to that. On  
> the other hand, Ansible tries to be simple and the looping constructs,  
> IMHO, are easy to work with and have a concise syntax.

Hi Giovanni,

My thinking is similar. Ansible playbooks are parsed in a strange way. Some  
parts of it are plain YAML, whereas other parts are run through the Jinja2  
templating engine. This is confusing.

I was reading Salt documentation, and saw that Salt's state files are just  
plain YAML, but the entire YAML file is passed through Jinja2, so that any  
loops and other variable things are done by Jinja2, and this is  
conceptually neater than Ansible's current mix of Jinja2 and Ansible's own  
declarative language.

---

<div class="post-metadata">

**Author:** ![Anand\_Buddhdev2](https://avatars.discourse-cdn.com/v4/letter/a/48db29/32.png) [@Anand\_Buddhdev2](https://forum.ansible.com/u/Anand_Buddhdev2)\
**Post date:** [February 2, 2015, 3:21pm UTC](https://forum.ansible.com/t/parsing-playbooks-with-full-jinja-templating/17413/13 "2015-02-02T15:21:35Z")

</div>

Hi Tom,

> Jinja templating doesn’t work in playbooks in that way. Lots of variable  
> constructs are actually parsed with jinja2, so you can do stuff like
> 
> - set\_fact:  
> &nbsp;&nbsp;&nbsp;&nbsp;myvar: "{% if something %}this{% else %}that{% endif %}"
> 
> As Giovanni mentioned, there are numerous looping constructs for things  
> like task repetition. Playbooks are declarative, so it wouldn’t really be  
> right to build them from a template.

I understand this, and it is exactly what I am trying to discuss here. Why  
can't one build a playbook from a template? I think plain YAML is just fine  
for declarative statements. Or am I missing a use case?
