In Ansible, I have a list of strings that I want to join with newline characters to create a string, that when written to a file, becomes a series of lines. However, when I use the join() filter, it works on the inner list, the characters in the strings, and not on the outer list, the strings themselves. Here's my sample code:
# Usage: ansible-playbook tst3.yaml --limit <GRP> --- - hosts: all remote_user: root tasks: - name: Create the list set_fact: my_item: "{{ item }}" with_items: - "One fish" - "Two fish" - "Red fish" - "Blue fish" register: my_item_result - name: Extract items and turn into a list set_fact: my_list: "{{ my_item_result.results | map(attribute='ansible_facts.my_item') | list }}" - name: Examine the list debug: msg: "{{ my_list }}" - name: Concatenate the public keys set_fact: my_joined_list: "{{ item | join('\n') }}" with_items: - "{{ my_list }}" - name: Examine the joined string debug: msg: "{{ my_joined_list }}"
I want to get output that looks like:
One fish Two fish Red fish Blue Fish
What I get instead is:
TASK: [Examine the joined string] ********************************************* ok: [hana-np-11.cisco.com] => { "msg": "B\nl\nu\ne\n \nf\ni\ns\nh" } ok: [hana-np-12.cisco.com] => { "msg": "B\nl\nu\ne\n \nf\ni\ns\nh" } ok: [hana-np-13.cisco.com] => { "msg": "B\nl\nu\ne\n \nf\ni\ns\nh" } ok: [hana-np-14.cisco.com] => { "msg": "B\nl\nu\ne\n \nf\ni\ns\nh" } ok: [hana-np-15.cisco.com] => { "msg": "B\nl\nu\ne\n \nf\ni\ns\nh" }
How do I properly concatenate a list of strings with the newline character?
This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.
For Ansible, nearly every YAML file starts with a list. Each item in the list is a list of key/value pairs, commonly called a “hash” or a “dictionary”. So, we need to know how to write lists and dictionaries in YAML. There's another small quirk to YAML.
Filters in Ansible are from Jinja2, and are used for transforming data inside a template expression. Jinja2 ships with many filters. See builtin filters in the official Jinja2 template documentation.
Solution
join
filter works on lists, so apply it to your list:
- name: Concatenate the public keys set_fact: my_joined_list: "{{ my_list | join('\n') }}"
Explanation
While my_list
in your example is a list, when you use with_items
, in each iterationitem
is a string. Strings are treated as lists of characters, thus join
splits them.
It’s like in any language: when you have a loop for i in (one, two, three)
and refer to i
inside the loop, you get only one value for each iteration, not the whole set.
Remarks
Don’t use debug
module, but copy
with content
to have\n
rendered as newline.
The way you create a list is pretty cumbersome. All you need is (quotation marks are also not necessary):
- name: Create the list set_fact: my_list: - "One fish" - "Two fish" - "Red fish" - "Blue fish"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With