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