Possible variable/conditional improvement proposal - thoughts?

So I think a lot about how to keep ansible as simple as it can
possibly be. The one place I think we can do better, but it's hard to
sometimes, is in how we handle variables and conditional operations.
I want to keep making this better.

For me at least, I think is is frequently somewhat confusing that we
have a simplified variable syntax in playbooks (also templates) but
that templates mainly use Jinja2 in examples.

I personally find the simplified template syntax very useful for
things like ${foo} or $foo but hard for complex things.

We will not be allowing Jinja2 operations of complexity in playbooks,
and running Jinja2 as often as we run our templating engine would be a
little sluggish anyway (we allow some lazy evaluation).

However, given all of this, I'm wondering.

What if {{ foo }} in playbooks just *worked* like jinja2, and you
/could/ put python statements in there?

We would obviously need to limit what you could do to data structures
an regular expressions only, but if one could say

{{ hostvars['asdf.example.com']['ansible_some_fact'] }}

while that is less beautiful, it would elimiate a large class of
variable concerns.

And this could also be allowed in conditionals, perhaps also
eliminating a class of conditional concerns, where the statement could
evaluate down to True or False

when: {{ (x > 52) }}

when: {{ y }}

when: {{ z in some_list }}

I think this may take a bit of a trick to implement well, though it
may also be possible to engage Jinja2 without the looping/other
constructs and tune to where performance is reasonable.

What do people think?

If this were the case we obviously leave $x and such in for backwards
compatibility (we must) but would probably move in 1.2 to keeping all
of your examples using the new way, and snapshotting the docs by
version.

So I think a lot about how to keep ansible as simple as it can
possibly be. The one place I think we can do better, but it's hard to
sometimes, is in how we handle variables and conditional operations.
I want to keep making this better.

As a new user, I think my be interested in my opinion :), and I
totally agree on this. This is the only thing I find confusing and
which is causing me a lot of mistakes, while templates, playbooks,
inventory files are very easy to understand and use (for the time
being at least :))

We will not be allowing Jinja2 operations of complexity in playbooks,
and running Jinja2 as often as we run our templating engine would be a
little sluggish anyway (we allow some lazy evaluation).

However, given all of this, I'm wondering.

What if {{ foo }} in playbooks just *worked* like jinja2, and you
/could/ put python statements in there?

We would obviously need to limit what you could do to data structures
an regular expressions only, but if one could say

{{ hostvars['asdf.example.com']['ansible_some_fact'] }}

Could you use list comprehension to create list variables, like?:

    vars:
        facts: {{ [ host['ansible_some_fact'] for host in
hostvars.values() ] }}

And this could also be allowed in conditionals, perhaps also
eliminating a class of conditional concerns, where the statement could
evaluate down to True or False

when: {{ (x > 52) }}

when: {{ y }}

when: {{ z in some_list }}

I also like this syntax.

.a.

I’m very, very much in favor of the {{ }} idea.
Conditionals (and expressions) is one of the top 2-3 re-occurring issues I have encountered that have impacted my prototyping exercise. (As we speak I’m trying to express some logic that needs to update a schema, and spending way more time doing so than I should).

BUT, if this is done, please do so uniformly, so these expressions are valid everywhere i.e. as arguments to when, as parameters to modules, includes etc. and can uniformly involve inventory/group/host/fact/localfact variables.

Could you use list comprehension to create list variables, like?:

    vars:
        facts: {{ [ host['ansible_some_fact'] for host in
hostvars.values() ] }}

Yep, I don't see why not.

Thankfully we have a standard template function so it will be
uniformly available everywhere variables can be used now.

The one catch is currently our template infrastructure evaluates
repeatedly, so it keeps working until it has no more work to do.

This means it would do:

* process ${old_style} until it can do ${old_style} no more
* one last Jinja2 pass (or somewhat like Jinja2 eval)

Mixing old style and new style would probably be "right out", such
that if we detected "{{" in a string, we wouldn't go down the "old"
route.

We could probably even make it configurable to shut the old style off,
for people that wanted to ensure consistency.

+1000

I end up needing more “logic” in the lines, and end up writing templates that are single line shell scripts to make things work.

This would be much preferable.

Would very much like this, allowing for elegant and readable tweaks to get around site specific special cases. Some concern that this might let 'code' creep into our playbooks, but you suggest there is some effective way to limit what is allowed.

K

Little late to the discussion but I really like this idea.

Great!

I am thinking this will be one of the first things I do for when 1.2
development starts (which will be on 4/3).

OT -- I still plan to try to get "improved callback context" done for
1.1, which will be one of the last features I add prior to the feature
freeze Monday.