multiline jinja2 lists returned as string?

Hi there, I have some logic that I want to apply when creating assigning a list to a variable.

See my sample playbook below, Ideally i’d like a nice clean way to have a logic based list. the “users” approach works, however it’s always interpreted as a string. The only solution I can think of to fix this one is to store it as a string and then split it later. But I would like to know if it’s possible to return a list somehow. Maybe there’s a different syntax that i’m not aware of. Can anyone offer a better way to do something like below?

`

  • hosts: localhost
    connection: local
    vars:

THIS does not work as it’s interpreted as a string, would have to split in a new var?

is there anything I can do here to keep a similar syntax but return a list?

users: >-
{% set cusers = [‘user1’, ‘user2’] %}
{% if ansible_distribution == “RedHat” %}
{{ cusers.append(‘redhat_user’) }}
{% else %}
{{ cusers.append(‘other_user’) }}
{% endif %}
{{ cusers | list }}

THIS works but a little ugly with the newline

users2: “{% set cusers = [‘user1’, ‘users2’] %}
{% if ansible_distribution == ‘RedHat’ %}
{{ cusers.append(‘redhat_user’) }}
{% else %}
{{ cusers.append(‘other_user’) }}
{% endif %}
{{ cusers }}”

tasks:

  • debug:
    msg: “user: {{ item }}”
    loop: “{{ users2 }}”
    `

Something like this should work

  vars:
    cuser: ['user1', 'user2']
    users: "{{ cuser + ['redhat_user'] if ansible_distribution == 'RedHat' else cuser + ['other_user'] }}"

thanks for the reply, I had also thought of that solution and it’s perfectly viable for my example (thanks). however was looking for something that doesn’t use multiple variables and avoids repetition. My example was just a simple one, in some cases I have more complex jinja statements and the crux of what I was after was how to nicely do complex multiline jinja statements that use lists.

The root of the problem is a bit complicated, and rooted in the fact that historically jinja2 could only return strings. So we have code that attempts to safely convert string representations of python datastructures into actual python data structures.

What appears to be your problem is a bunch of added whitespace caused by the jinja2 templating. The following seems to resolve the problem:

users: >-
{%- set cusers = [‘user1’, ‘user2’] -%}
{%- if ansible_distribution == “RedHat” -%}
{{ cusers.append(‘redhat_user’) }}
{%- else -%}
{{ cusers.append(‘other_user’) }}
{%- endif -%}
{{ cusers | list }}

Notice the use of {%- and -%} which informs jinja2 to strip whitespace. See http://jinja.pocoo.org/docs/dev/templates/

dang, could have sworn I tried that. It works, thanks Matt, that’s exactly what I was looking for!! appreciate it.

Hi there, I have some logic that I want to apply when creating assigning a
list to a variable.

See my sample playbook below, Ideally i'd like a nice clean way to have a
logic based list. the "users" approach works, however it's always
interpreted as a string. The only solution I can think of to fix this one
is to store it as a string and then split it later. But I would like to
know if it's possible to return a list somehow. Maybe there's a different
syntax that i'm not aware of. Can anyone offer a better way to do
something like below?

- hosts: localhost
  connection: local
  vars:
    # THIS does not work as it's interpreted as a string, would have to
split in a new var?
    # is there anything I can do here to keep a similar syntax but return a
list?
    users: >-
      {% set cusers = ['user1', 'user2'] %}
      {% if ansible_distribution == "RedHat" %}
      {{ cusers.append('redhat_user') }}
      {% else %}
      {{ cusers.append('other_user') }}
      {% endif %}
      {{ cusers | list }}
    # THIS works but a little ugly with the newline
    users2: "{% set cusers = ['user1', 'users2'] %}\
             {% if ansible_distribution == 'RedHat' %}\
             {{ cusers.append('redhat_user') }}\
             {% else %}\
             {{ cusers.append('other_user') }}\
             {% endif %}\
             {{ cusers }}"

Another way:

users2: "{{ ['user1', 'users2'] + (ansible_distribution == 'RedHat') | ternary(['redhat_user')], ['other_user']) }}"

V/r,
James Cassell