how to append to a list in jinja2 for ansible

I didn't like any of the answers, they feel too hacky (having to worry about outputting None, or spurious whitespace using other techniques), but I think I've found a solution that works well. I took inspiration from this answer on a related question and realized that you can call set multiple times for the same variable and seemingly not incur any penalty.

It's still a tad hacky, because I don't think it's intended to work like this (then again, several design decisions in Jinja make me scratch my head, so who knows).

{% set server_ip = server_ip.append({{ ip }}:{{ port }}) %}

Interestingly, while the value is indeed appended to server_ip, the return value of that append (which we now know very well is None) isn't assigned back to server_ip on the LHS. Which led me to discover that the LHS side of the statement seems to be a no-op.

So you can also do this and the append works:

{% set tmp = server_ip.append({{ ip }}:{{ port }}) %}

Yet, if you print tmp, nothing shows up. Go figure.


Try below code:

{% set port = '1234' %}
{% set server_ip = [] %}
{% for ip in host_ip  %}
{{ server_ip.append( ip+":"+port ) }}
{% endfor %}
{{ server_ip|join(',') }}

You ll get:

192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234


That worked for me:

- set_fact:
    devices: >-
      {% for ip in host_ip %}{{ ip }}:1234{% if not loop.last %},{% endif %}{% endfor %}

If you still want to use do then add

jinja2_extensions = jinja2.ext.do

to your ansible config file and change

{% do server_ip.append({{ ip }}:{{ port }}) %}` to `{% do server_ip.append({ip:port}) %}`