271

How do I see stdout for ansible-playbook commands? -v only shows ansible output, not the individual commands. It would be great if I could figure out how to do this immediately, so if something fails or hangs I can see why.

e.g.

- name: print to stdout action: command echo "hello" 

would print

TASK: [print variable] ******************************************************** hello 
2

6 Answers 6

256

I think you can register the result to a variable, then print with debug.

- name: print to stdout command: echo "hello" register: hello - debug: msg="{{ hello.stdout }}" - debug: msg="{{ hello.stderr }}" 
5
  • 34
    Additionally, you can debug a variable directly with - debug: var=hello. Sometimes this is more helpful for multiline output or Ansible module output (rather than command/shell output). Commented Mar 8, 2014 at 3:03
  • 4
    I had trouble getting Java output using this. The fix is to redirect all of Java's output to stdout: shell: java -version 2>&1 Commented Jan 6, 2015 at 17:27
  • 36
    that's a lot better nothing, but you only get the stdout message after the command has successfully completed. I was having an issue where ansible would appear to hang. The reason was that I was using the wrong username for an rsync command, which spooled the interactive password request, which just hanged ansible. It was very difficult to debug - but if I could see stdout in realtime, I would have immediately realised what I'd done wrong. I would LOVE this functionality, if possible. Commented Feb 9, 2015 at 4:31
  • 16
    while this works, it means ansible makes debugging really hard. Let's imagine the first task never terminates (perhaps it is foolishly waiting for user input)... the user would never know! Moreover, the register module, or whatever it is doesn't produce objects that have the stdout or stderr variable set.... so it's really bad that we don't just get the output by default :| Commented Jul 10, 2015 at 10:47
  • Make sure the command you're running has a timeout, or use the ansible async to force a timeout. Then you should be prompted something is wrong and see the previous output. Commented Sep 6, 2020 at 15:30
167

Instead of stdout I would suggest using stdout_lines. For multiline output this is much nicer, e.g.

- hosts: all tasks: - name: Run ls.sh and output "ls /" script: ls.sh register: out - debug: var=out.stdout_lines 

gives

TASK: [debug var=out.stdout_lines] ******************************************** ok: [local] => { "var": { "out.stdout_lines": [ "total 61", "lrwxrwxrwx 1 root root 7 Feb 15 2015 bin -> usr/bin", "drwxr-xr-x 6 root root 1024 Aug 24 22:08 boot", "drwxr-xr-x 22 root root 3580 Sep 8 18:41 dev", [...] "drwxr-xr-x 9 root root 4096 Aug 25 19:14 usr", "drwxr-xr-x 13 root root 4096 Feb 25 2015 var" ] } } 

Regarding real time output for debugging purposes there is a closed bug report https://github.com/ansible/ansible/issues/3887#issuecomment-54672569 discussing the reasons why this is not possible and will not be implemented.

5
  • 28
    +1 for linking the "real time output" bug. Commented Nov 26, 2015 at 0:29
  • If I want to send out.stdout_lines (as body of Ansible mail task), how can I send it so it does NOT look like this when email is received? [u'total 61', u'lrwxrwxrwx 1 root root 7 Feb 15 2015 bin -> usr/bin', u'drwxr-xr-x 6 root root 1024 Aug 24 22:08 boot', u'.....'] I want it to look like this, as seen on terminal Commented Mar 10, 2017 at 21:35
  • fatal: [127.0.0.1]: FAILED! => {"reason": "Syntax Error while loading YAML.\n did not find expected <document start>\n\nThe error appears to be in...syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Run ls.sh and output \"ls /\"\n^ here\n"} Commented Aug 15, 2019 at 16:28
  • Make sure you use command instead of script on the new versions of Ansible. Commented Sep 2, 2021 at 14:34
  • +1 for register: out I'm appropriating that for all my taks. Commented Aug 26, 2022 at 7:07
33

I found using the minimal stdout_callback with ansible-playbook gave similar output to using ad-hoc ansible.

In your ansible.cfg (Note that I'm on OS X so modify the callback_plugins path to suit your install)

stdout_callback = minimal callback_plugins = /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/plugins/callback 

So that a task such as this

--- - hosts: example tasks: - name: Say hi command: echo "hi ..." 

Gives output like this, like an ad-hoc command would

example | SUCCESS | rc=0 >> hi ... 

I'm using ansible-playbook 2.2.1.0

2
  • Nice callback plugin, simple post-processing can extract standard output only. Commented Jun 27, 2017 at 9:43
  • So useful not to have to pollute the play with registered variables. Then again, it is an external dependency and a dumb generic variable like out would serve to minimise pollution. Commented Aug 26, 2022 at 7:06
11

If you really want to watch the output in realtime, there is a hacky way around it, at least for the ansible shell module.

In whatever shell script wraps your call to ansible, touch and tail a log file in a background job. Then redirect the ansible shell command's output to append to that log file. You need to make sure you kill the background tail job after ansible finishes, or it will be left dangling.

For example, in a bash script that calls ansible:

set -m touch /tmp/debug.log && tail -f /tmp/debug.log & ansible-playbook ... call playbook here kill %1 # ensure the background tail job is stopped 

Then in some ansible role:

- name: Run a script and print stdout/stderr shell: bash -c "/run/something.sh 2>&1 >> /tmp/debug.log" 
4
  • 3
    very interesting and creative. thanks for the insight. looks like i can apply the technique to other things so that's pretty neat. Commented Jul 23, 2020 at 22:54
  • 4
    Honestly this is the only correct answer here... Commented Oct 9, 2020 at 11:59
  • 1
    @MoatazElmasry I had the same issue with puppet bolt. This worked like a charm. Commented Jan 28, 2021 at 5:46
  • Puppet bolt now has an experiential feature for live streaming! ospassist.puppet.com/hc/en-us/articles/… Commented Nov 11, 2021 at 22:48
3

I've found that just killing a stuck process on the remote via ssh gives back the stdout. I find thats shorter than writing workarounds that won't be used in the final playbook anyways:

kill -9 PID

2
  • 1
    but what if the process is only appearing to hang because ansible doesn't output anything and is in fact chugging along? Commented Feb 24, 2021 at 16:52
  • Yeah what is stuck if your're flying blind in this case? Imagine a CI build process that normally takes 5 hours and while you thought it was running for 5 hours that run of it was actually just stuck. That's a lot of lost time. Commented Nov 11, 2021 at 22:50
2

Another way to get stdout of a command is to add more verbosity with -vvv. You don't have to write debug tasks, and it gives you good and viewable (JSON on multiple lines) output for everything. The only downside is that it speaks a lot (ssh log in, privilege escalation, ...).

1
  • 1
    -vv is enough to see stderr of ansible command actions. Commented Feb 2, 2024 at 13:59

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.