# How to use a Python expression instead of a Jinja expression in changed\_when?

**URL:** <https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412>\
**Category:** Ansible Project\
**Created:** [September 3, 2013, 5:18pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412 "2013-09-03T17:18:42Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nicolas\_Grilly](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@Nicolas\_Grilly](https://forum.ansible.com/u/Nicolas_Grilly)\
**Post date:** [September 3, 2013, 5:18pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/1 "2013-09-03T17:18:42Z")

</div>

Hello,

changed\_when is extremely useful and a very nice addition to Ansible!

I’m wondering how to use a Python expression instead of a Jinja expression in changed\_when?

On a more general level, the documentation is not very explicit about the kind of expression (Python and/or Jinja) accepted by Ansible playbooks.

I’m curious to know what are the reasons for pushing the Jinja more restricted syntax over the Python syntax?

Nicolas

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 3, 2013, 8:50pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/2 "2013-09-03T20:50:22Z")

</div>

You can only use Jinja2 expressions.

Why? We don’t want playbooks to become arbitrary Python hackjobs. Ansible is not a Python tool – something that is only appealing to Python developers. Rather, it’s a tool that is written in Python.

Jinja2 templating allows us direct access to all of our variables with reasonable constrains without allowing you to do things like “os.system()” in the middle of an operation.

---

<div class="post-metadata">

**Author:** ![Nicolas\_Grilly1](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nicolas\_Grilly1](https://forum.ansible.com/u/Nicolas_Grilly1)\
**Post date:** [September 3, 2013, 11:02pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/3 "2013-09-03T23:02:20Z")

</div>

> You can only use Jinja2 expressions.

Thank you Michael for this confirmation.

Why? We don't want playbooks to become arbitrary Python hackjobs.

> Ansible is not a Python tool -- something that is only appealing to Python  
> developers. Rather, it's a tool that is written in Python.

Ansible is not a Python tool, but it's neither a Jinja tool 🙂

I would argue that very few developers outside the Python ecosystem know  
Jinja, which makes playbooks with Jinja expressions even more "Pythonesque"  
than playbooks with Python expressions.

It definitely makes sense to restrict Python to Ansible internals as much  
as possible, and not let it "bleed" into the public API. (It was the reason  
behind the pull request I made a few months ago to remove Python specific  
quoting from Ansible playbooks.)

Yet, playbooks still need an expression language, and whatever syntax is  
used, Jinja or Python's one, they are both a "foreign" syntax into Ansible  
playbooks. I'm not sure to understand why a Ruby or a Perl developer would  
be more comfortable with Jinja's syntax than Python's one:  
- Jinja's syntax is less documented than Python's syntax which has  
excellent documentation.  
- Jinja's syntax is perfect for a templating engine, but I doubt it's a  
good fit for an orchestration tool. Python's syntax is more general and  
closer to what people use in mainstream languages (Java, C, JavaScript,  
Ruby, Perl, PHP, etc.).

Jinja2 templating allows us direct access to all of our variables with

> reasonable constrains without allowing you to do things like "os.system()"  
> in the middle of an operation.

I understand this argument in theory. But is it a problem in practice (i.e.  
having someone abusing the playbook expressions and breaking Ansible  
expected behavior)?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 4, 2013, 12:29pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/4 "2013-09-04T12:29:50Z")

</div>

it’s only a problem if you try to program in your playbooks, which is against the entire aesthetic of Ansible.

If there are cases where you think we need to document things more, the documentation is an open source project that is easy to contribute to:

docsite/latest/rst/\*.rst in the checkout.

It should only be used for simple expressions.

---

<div class="post-metadata">

**Author:** ![Nicolas\_Grilly1](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nicolas\_Grilly1](https://forum.ansible.com/u/Nicolas_Grilly1)\
**Post date:** [September 4, 2013, 2:05pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/5 "2013-09-04T14:05:30Z")

</div>

Hello Michael,

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 4, 2013, 3:03pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/6 "2013-09-04T15:03:07Z")

</div>

Yep, Jinja2 expressions are basically Python unless you’re trying to do any kind of advanced Python.

I’d rather explain what they look like than for people to have to think they need to learn a lot of details of the templating system.

---

<div class="post-metadata">

**Author:** ![Nicolas\_Grilly1](https://avatars.discourse-cdn.com/v4/letter/n/d9b06d/32.png) [@Nicolas\_Grilly1](https://forum.ansible.com/u/Nicolas_Grilly1)\
**Post date:** [September 4, 2013, 3:16pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/7 "2013-09-04T15:16:43Z")

</div>

\<[http://www.vocationcity.com/&gt](http://www.vocationcity.com/&gt);  
Would you accept a pull request that replaces:

\*"This is easy to do in Ansible, with the when clause, which actually is a  
Python expression."

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 4, 2013, 3:49pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/8 "2013-09-04T15:49:43Z")

</div>

Sure!

It should also give some examples, but I think it already does.

when: foo == 12

when: foo == “cat”

Note: things like list comprehensions, a Python programming feature, are not supported

etc

---

<div class="post-metadata">

**Author:** ![Nicolas\_Grilly](https://avatars.discourse-cdn.com/v4/letter/n/77aa72/32.png) [@Nicolas\_Grilly](https://forum.ansible.com/u/Nicolas_Grilly)\
**Post date:** [September 5, 2013, 7:47pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/9 "2013-09-05T19:47:22Z")

</div>

Hello Michael,

Pull request here: [https://github.com/ansible/ansible/pull/4040](https://github.com/ansible/ansible/pull/4040)

🙂

---

<div class="post-metadata">

**Author:** ![Kevin\_Montuori](https://avatars.discourse-cdn.com/v4/letter/k/bbce88/32.png) [@Kevin\_Montuori](https://forum.ansible.com/u/Kevin_Montuori)\
**Post date:** [September 5, 2013, 8:27pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/10 "2013-09-05T20:27:47Z")

</div>

Given this (and perhaps I'm not familiar enough with Jinja2), how do you  
craft a play that takes into account, say, the presence of a row in a  
database? In salt I'd do something like:

psql -c "create extension if not exists adminpack":  
&nbsp;&nbsp;cmd.run:  
&nbsp;&nbsp;&nbsp;&nbsp;- onlyif: "[ $(psql -tc \"select count(\*)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from pg\_extension  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where extname='adminpack'\") == 0 ]"

Is there an Ansible analog?

(I do realize that the test isn't absolutely necessary in this  
particular example but I hope the intention is clear.)

k.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [September 5, 2013, 8:34pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/11 "2013-09-05T20:34:35Z")

</div>

I’d be very inclined to use a register statement to make the test and then use the when statement.

Let’s not mention that other tool here, least I tell you what I really think of it 🙂

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [September 5, 2013, 9:41pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/12 "2013-09-05T21:41:30Z")

</div>

you can use a shell/command task +registered variable or even the pipe  
lookup plugin

---

<div class="post-metadata">

**Author:** ![Eric4](https://avatars.discourse-cdn.com/v4/letter/e/bbe5ce/32.png) [@Eric4](https://forum.ansible.com/u/Eric4)\
**Post date:** [October 17, 2017, 7:42pm UTC](https://forum.ansible.com/t/how-to-use-a-python-expression-instead-of-a-jinja-expression-in-changed-when/13412/13 "2017-10-17T19:42:37Z")

</div>

How do you escape single quotes?
