Ansible - Print message - debug: msg="line1 \n {{ var2 }} \n line3 with var3 = {{ var3 }}"
Solution 1
As a workaround, I used with_items and it kind of worked for me.
- debug: msg="Installing swarm slave = {{ slave_name }} at {{ slaves_dir }}/{{ slave_name }}"
- debug: msg="Slave properties = {{ item.prop }} [ {{ item.value }} ]"
with_items:
- { prop: 'fsroot', value: "{{ slave_fsroot }}" }
- { prop: 'master', value: "{{ slave_master }}" }
- { prop: 'connectingToMasterAs', value: "{{ slave_user }}" }
- { prop: 'description', value: "{{ slave_desc }}" }
- { prop: 'No.Of.Executors', value: "{{ slave_execs }}" }
- { prop: 'LABELs', value: "{{ slave_labels }}" }
- { prop: 'mode', value: "{{ slave_mode }}" }
tags:
- koba
Solution 2
debug module support array, so you can do like this:
debug:
msg:
- "First line"
- "Second line"
The output:
ok: [node1] => {
"msg": [
"First line",
"Second line"
]
}
Or you can use the method from this answer:
In YAML, how do I break a string over multiple lines?
Solution 3
The most convenient way I found to print multi-line text with debug is:
- name: Print several lines of text
vars:
msg: |
This is the first line.
This is the second line with a variable like {{ inventory_hostname }}.
And here could be more...
debug:
msg: "{{ msg.split('\n') }}"
It splits the message up into an array and debug prints each line as a string. The output is:
ok: [example.com] => {
"msg": [
"This is the first line.",
"This is the second line with a variable like example.com",
"And here could be more...",
""
]
}
Thanks to jhutar.
Solution 4
Pause module:
The most convenient and simple way I found to display a message with formatting (ex: new lines, tabs ...) is to use the pause
module instead of debug
module:
- pause:
seconds: 1
prompt: |
======================
line_1
line_2
======================
You can also include a variable that contains formatting (new lines, tabs...) inside the prompt and it will be displayed as expected:
- name: test
hosts: all
vars:
line3: "\n line_3"
tasks:
- pause:
seconds: 1
prompt: |
/////////////////
line_1
line_2 {{ line3 }}
/////////////////
Tip:
when you want to display an output from a command, and instead of running an extra task to run the command and register the output, you can directly use the pipe lookup inside the prompt and do the job in one shot:
- pause:
seconds: 1
prompt: |
=========================
line_1
{{ lookup('pipe', 'echo "line_2 with \t tab \n line_3 "') }}
line_4
=========================
Extra notes regarding the pause module:
-
If you have multiple hosts, note that the
pause
task will run only once against the first host in the list of hosts.This means that if the variable you want to display exists only in part of the hosts and the first host does not contain that variable then you will get an error.
To avoid such an issue, use
{{ hostvars['my_host']['my_var'] }}
instead of{{ my_var }}
-
Combining
pause
withwhen
conditional might skip the task! Why? Because the task will only run once against the first host which might not conform to the statedwhen
conditions.To avoid this, don't use conditions that constrain the number of hosts! As you don't need it either, because you know that the task will run only once anyway. Also use
hostvars
stated above to make sure you get the needed variable whatever the picked up host is.
Example:
Incorrect:
- name: test
hosts: host1,host2
vars:
display_my_var: true
tasks:
- when: inventory_hostname == 'host2'
set_fact:
my_var: "hi there"
- when:
- display_my_var|bool
- inventory_hostname == 'host2'
pause:
seconds: 1
prompt: |
{{ my_var }}
This example will skip the pause task, because it will choose only the first host host1
and then starts to evaluate conditions, when it finds that host1
is not conforming to the second condition it will skip the task.
Correct:
- name: test
hosts: host1,host2
vars:
display_my_var: true
tasks:
- when: inventory_hostname == 'host2'
set_fact:
my_var: "hi there"
- when: display_my_var|bool
pause:
seconds: 1
prompt: |
{{ hostvars['host2']['my_var'] }}
Another example to display messages where the content depends on the host:
- set_fact:
my_var: "hi from {{ inventory_hostname }}"
- pause:
seconds: 1
prompt: |
{% for host in ansible_play_hosts %}
{{ hostvars[host]['my_var'] }}
{% endfor %}
Solution 5
Suppressing the last empty string of apt
with [:-1]
---
- name: 'apt: update & upgrade'
apt:
update_cache: yes
cache_valid_time: 3600
upgrade: safe
register: apt
- debug: msg={{ apt.stdout.split('\n')[:-1] }}
The above debug:
line results in nice line breaks, due to .split('\n')
, and a suppressed last empty string thanks to [:-1]
; all of which is Python string manipulation, of course.
"msg": [
"Reading package lists...",
"Building dependency tree...",
"Reading state information...",
"Reading extended state information...",
"Initializing package states...",
"Building tag database...",
"No packages will be installed, upgraded, or removed.",
"0 packages upgraded, 0 newly installed, 0 to remove and 0 not upgraded.",
"Need to get 0 B of archives. After unpacking 0 B will be used.",
"Reading package lists...",
"Building dependency tree...",
"Reading state information...",
"Reading extended state information...",
"Initializing package states...",
"Building tag database..."
]
AKS
A Quote on "Quote(s)": For every quote, there exists at least one contradictory quote. - AKS
Updated on March 06, 2020Comments
-
AKS about 4 years
In Ansible (1.9.4) or 2.0.0
I ran the following action:
- debug: msg="line1 \n {{ var2 }} \n line3 with var3 = {{ var3 }}"
$ cat roles/setup_jenkins_slave/tasks/main.yml
- debug: msg="Installing swarm slave = {{ slave_name }} at {{ slaves_dir }}/{{ slave_name }}" tags: - koba - debug: msg="1 == Slave properties = fsroot[ {{ slave_fsroot }} ], master[ {{ slave_master }} ], connectingToMasterAs[ {{ slave_user }} ], description[ {{ slave_desc }} ], No.Of.Executors[ {{ slave_execs }} ], LABELs[ {{ slave_labels }} ], mode[ {{ slave_mode }} ]" tags: - koba - debug: msg="print(2 == Slave properties = \n\nfsroot[ {{ slave_fsroot }} ],\n master[ {{ slave_master }} ],\n connectingToMasterAs[ {{ slave_user }} ],\n description[ {{ slave_desc }} ],\n No.Of.Executors[ {{ slave_execs }} ],\n LABELs[ {{ slave_labels }} ],\n mode[ {{ slave_mode }} ])" tags: - koba
But this is not printing the variable with new lines (for the 3rd debug action)?
-
AKS over 8 yearsI mean, I can use shell or command module and echo them acc. to what I want. I can also use with_lines: <cmd> and us the lines (per line) to print. I can also register the output of command / shell to print these lines with new lines and using register_var.stdout_lines show the lines but within debug action, msg="...\n...\n", I saw somewhere that I can use print ( ) func that it's not giving me an error but also not printing variables per lines (like I wanted). You mentioned sed, where and how can I used sed in "- debug" action?
-
Bruce P over 8 yearsTake a look at the question I linked to.
-
AKS over 8 yearsI see. Using sed with | at the end of whole ansible/ansible-playbook command will defeat the purpose I guess but it'll work as a workaround. Thanks. In the same post, I saw the callback plugin which I'll try next.
-
3cheesewheel almost 8 yearsWould be awesome if the resulting output could be condensed somehow. I'm using this now as a stand-in but what should take up one line takes up seven lines :(
-
AKS over 7 yearsYea. I think it's a JINJA limitation.
-
AKS over 7 yearsShould it be: do something here and then | sed "s#\\\n#\n#" i.e. \\\ vs \\ for the word to be substituted.
-
Prakash almost 6 yearsI was looking for same. Thanks
-
Leo Ufimtsev over 5 yearsAny good way to package the sed into an alias or bash script? like: ansible-playbook ... | sednl
-
guoqiao over 5 yearsGood to know, very convenient. The doc should mention this.
-
AKS almost 5 yearsThanks for sharing @Ejez
-
Tomáš Pospíšek over 4 years@guoqiao - the docs do mention this: there's a corresponding example in the debug_module docu.
-
Fmstrat over 4 yearsBy and far the best answer. I'm surprised there isn't a better way to do this. As a note,
seconds
can be set to0
. -
muru about 4 years@Fmstrat to not much effect. ("Starting in 2.2, if you specify 0 or negative for minutes or seconds, it will wait for 1 second, previously it would wait indefinitely.")
-
andras.tim over 3 yearsyou can use
stdout_lines
instead ofstdout.split('\n')