Posted: 2023-07-24 21:50:19 by Alasdair Keyes
When I was first getting into Ansible, I read this article https://www.jeffgeerling.com/blog/2017/adding-strings-array-ansible by Jeff Geerling on how to add items to arrays a playbook using Jinja2 and I ended up incorporating it into my playbooks.
It's worth reading the article but essentially the code is...
hosts: localhost
connection: local
gather_facts: false
vars:
my_messages: []
tasks:
- name: Add to array
ansible.builtin.set_fact:
my_messages: "{{ my_messages }} + ['Message added to array: {{ item }}']"
loop:
- element one
- something else
- 3
- false
- name: Display messages
ansible.builtin.debug:
var: my_messages
This produced the following debug output
ok: [127.0.0.1] => {
"my_messages": [
"Message added to array: element one",
"Message added to array: something else",
"Message added to array: 3",
"Message added to array: False"
]
}
I found this useful for any post-run reminders. The debug block was added at the end of the playbook and could prompt me to perform any other tasks that might be required.
After I upgraded from Debian Bullseye (11) to Bookworm (12) this feature was now no-longer working correctly. The code wouldn't error but the output would be one continuous string including the []
characters.
ok: [127.0.0.1] => {
"my_messages": "[] + [ 'Message added to array: element one' ] + [ 'Message added to array: something else' ] + [ 'Message added to array: 3' ] + [ 'Message added to array: False' ]"
}
The change has occurred somewhere between Ansible 2.10.7 (with Jinja 2.11.3) and Ansible 2.14.3 (with Jinja 3.1.2).
To resolve this, the correct code is now...
hosts: localhost
connection: local
gather_facts: false
vars:
my_messages: []
tasks:
- name: Add to array
ansible.builtin.set_fact:
my_messages: "{{ my_messages + ['Message added to array: ' + item | string] }}"
loop:
- element one
- something else
- 3
- false
- name: Display messages
ansible.builtin.debug:
var: my_messages
The only line that has changed is the my_messages:
fact setting.
The array manipulation is now performed entirely within the {{ }}
Jinja2 tags. This has a couple of knock-on effects that you will need to be aware of...
You cannot use a loop variable with {{ item }}
method as you will be using tags within tags and Ansible will throw an undefined variable error. You will have to concatenate your string/variables using the +
operator.
Because you are not using the {{ }}
tags (because of point 1) but instead the concatenation operator +
. It expects that you are only concatenating strings. As such you will need to ensure that any variables being joined are strings. If they are not, convert them with the | string
modifier.
The second example shows both these methods being used to work correctly with later versions of Ansible/Jinja2
Depending on your use-case it's a little more messy, but won't take too much effort to convert.
If you found this useful, please feel free to donate via bitcoin to 1NT2ErDzLDBPB8CDLk6j1qUdT6FmxkMmNz
© Alasdair Keyes
I'm now available for IT consultancy and software development services - Cloudee LTD.
Happy user of Digital Ocean (Affiliate link)