How can I show progress for a long-running Ansible task?

I have a some Ansible tasks that perform unfortunately long operations - things like running an synchronization operation with an S3 folder. It's not always clear if they're progressing, or just stuck (or the ssh connection has died), so it would be nice to have some sort of progress output displayed. If the command's stdout/stderr was directly displayed, I'd see that, but Ansible captures the output.

Piping output back is a difficult problem for Ansible to solve in its current form. But are there any Ansible tricks I can use to provide some sort of indication that things are still moving?

Current ticket is https://github.com/ansible/ansible/issues/4870


Solution 1:

I came across this problem today on OSX, where I was running a docker shell command which took a long time to build and there was no output whilst it built. It was very frustrating to not understand whether the command had hung or was just progressing slowly.

I decided to pipe the output (and error) of the shell command to a port, which could then be listened to via netcat in a separate terminal.

myplaybook.yml

- name: run some long-running task and pipe to a port
  shell: myLongRunningApp > /dev/tcp/localhost/4000 2>&1

And in a separate terminal window:

$ nc -lk 4000
Output from my
long
running
app will appear here

Note that I pipe the error output to the same port; I could as easily pipe to a different port.

Also, I ended up setting a variable called nc_port which will allow for changing the port in case that port is in use. The ansible task then looks like:

  shell: myLongRunningApp > /dev/tcp/localhost/{{nc_port}} 2>&1

Note that the command myLongRunningApp is being executed on localhost (i.e. that's the host set in the inventory) which is why I listen to localhost with nc.

Solution 2:

Ansible has since implemented the following:

---
# Requires ansible 1.8+
- name: 'YUM - async task'
  yum:
    name: docker-io
    state: installed
  async: 1000
  poll: 0
  register: yum_sleeper

- name: 'YUM - check on async task'
  async_status:
    jid: "{{ yum_sleeper.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 30

For further information, see the official documentation on the topic (make sure you're selecting your version of Ansible).