How to use a Python expression instead of a Jinja expression in changed_when?

1,246 views
Skip to first unread message

Nicolas Grilly

unread,
Sep 3, 2013, 1:18:42 PM9/3/13
to ansible...@googlegroups.com
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

Michael DeHaan

unread,
Sep 3, 2013, 4:50:22 PM9/3/13
to ansible...@googlegroups.com
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.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Nicolas Grilly

unread,
Sep 3, 2013, 7:02:20 PM9/3/13
to ansible...@googlegroups.com
On Tue, Sep 3, 2013 at 10:50 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
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)?

Michael DeHaan

unread,
Sep 4, 2013, 8:29:50 AM9/4/13
to ansible...@googlegroups.com
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.









--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Grilly

unread,
Sep 4, 2013, 10:05:30 AM9/4/13
to ansible...@googlegroups.com
Hello Michael,

On Wed, Sep 4, 2013 at 2:29 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
it's only a problem if you try to program in your playbooks, which is against the entire aesthetic of Ansible.

Now I understand your argument for the Jinja syntax. Playbooks must stay simple, and are not meant for programming, which explains the choice of the Jinja syntax for expressions, and the progressive deprecation of the Python syntax. Programming must be done in modules, in whatever languages I'm comfortable with. 

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.

I started this discussion after re-reading the documentation that says expressions use the Python syntax:

First time in the "Conditional Execution" section [1]:
This is easy to do in Ansible, with the when clause, which actually is a Python expression.  

Second time in the "Running a task in check mode" [2]:
To achieve this use the always_run clause on the task. Its value is a Python expression, just like the when clause.

Is the documentation correct? "Python" must be replaced by "Jinja" in both cases?

Thanks :)

Michael DeHaan

unread,
Sep 4, 2013, 11:03:07 AM9/4/13
to ansible...@googlegroups.com
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.




--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Grilly

unread,
Sep 4, 2013, 11:16:43 AM9/4/13
to ansible...@googlegroups.com
On Wed, Sep 4, 2013 at 5:03 PM, Michael DeHaan <mic...@ansibleworks.com> wrote:
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.

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."

by something like:

"This is easy to in Ansible, with the when clause, which actually is a Jinja expression. Jinja expressions are similar to Python and documented here: ..."

I'm pushing this because I spent some time trying to understand why my Python expressions were not working. I understood the syntax used was Jinja only after reading Ansible's source and reading your answers in this discussion.

Michael DeHaan

unread,
Sep 4, 2013, 11:49:43 AM9/4/13
to ansible...@googlegroups.com
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





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nicolas Grilly

unread,
Sep 5, 2013, 3:47:22 PM9/5/13
to ansible...@googlegroups.com
Hello Michael,


:)

Kevin Montuori

unread,
Sep 5, 2013, 4:27:47 PM9/5/13
to ansible...@googlegroups.com

On Tue, Sep 3, 2013, at 16:50, Michael DeHaan wrote:

> You can only use Jinja2 expressions.

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":
cmd.run:
- onlyif: "[ $(psql -tc \"select count(*)
from pg_extension
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.

--
Kevin Montuori
mont...@gmail.com

Michael DeHaan

unread,
Sep 5, 2013, 4:34:35 PM9/5/13
to ansible...@googlegroups.com
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 :)









--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Brian Coca

unread,
Sep 5, 2013, 5:41:30 PM9/5/13
to ansible...@googlegroups.com
you can use a shell/command task +registered variable or even the pipe lookup plugin


--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Eric

unread,
Oct 17, 2017, 3:42:38 PM10/17/17
to Ansible Project
How do you escape single quotes?
Reply all
Reply to author
Forward
0 new messages