Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 603
Xiong Chiamiov Avatar asked Dec 16 '16 23:12

Xiong Chiamiov


People also ask

How do you handle long running tasks in Ansible?

For a long running task use Ansible's Asynchronous mode to effectively background the task. Then follow it up with another task that checks the status of the backgrounded task.

How do you add delays in Ansible?

To pause/wait/sleep per host, use the ansible. builtin. wait_for module. You can use ctrl+c if you wish to advance a pause earlier than it is set to expire or if you need to abort a playbook run entirely.

What is poll interval in Ansible?

Ansible Poll Keyword with Ansible async By default Ansible would track the status of the async task every 10 seconds. If you think 10 seconds polling is too frequent and you want Ansible to test the status of the job every 60 seconds It is possible.


2 Answers

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.

like image 152
John Avatar answered Oct 08 '22 04:10

John


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).

like image 37
halpdoge Avatar answered Oct 08 '22 04:10

halpdoge