Combine Ansible async with retries

Viewed 1224

Ok, now I have a really tricky case with Ansible. I need to run my task asynchronously with retries (i.e. with until loop) and then fail task if timeout exceeds. So both two parameters must control my play: retries count (play fails if retry count exceeded) and timeout (play fails if timeout exceeded).

I can implement each strategy separately:

- name: My shell task with retries
  shell: set -o pipefail && ./myscript.sh 2>&1 | tee -a "{{mylogfile}}"
  args:
    chdir: "{{myscript_dir}}/"
    executable: /bin/bash
  register: my_job
  until: my_job is succeeded
  retries: "{{test_retries}}"
  delay: 0

or with async:

- name: My async shell task
  shell: set -o pipefail && ./myscript.sh 2>&1 | tee -a "{{mylogfile}}"
  args:
    chdir: "{{myscript_dir}}/"
    executable: /bin/bash
  register: my_job
  async: "{{test_timeout}}"
  poll: 0

- name: Tracking for async shell task
  wait_for:
    path: "{{mylogfile}}"
    search_regex: '^.*Done in \S+'
    timeout: "{{test_timeout}}"
  ignore_errors: yes
  register: result

The second task parses previous task log until the job is finished - i.e. searches "Done in x seconds" string. Maybe it's not the best practice and I should use async_status but can't find how to set timeout with it (it's only have retries for checking job status which is pretty silly for me).

Sooo... Can I combine both strategies to control my task both with retries count and timeout?

UPD: I tried to run both until and async for shell module and surprisingly my play doesn't fail but retries doesn't work. The task was just started as fire-and-forget task and executed only one time without retries. So this is not an option.

- name: My shell task with retries and async
  shell: set -o pipefail && ./myscript.sh 2>&1 | tee -a "{{mylogfile}}"
  args:
    chdir: "{{myscript_dir}}/"
    executable: /bin/bash
  register: my_job
  until: my_job is succeeded
  retries: "{{test_retries}}"
  delay: 0
  async: "{{test_timeout}}"
  poll: 0

- name: My async shell task
  wait_for:
    path: "{{mylogfile}}"
    search_regex: '^.*Done in \S+'
    timeout: "{{test_timeout}}"
  ignore_errors: yes
  register: result
1 Answers

Have you tried using retries and delay together?

- name: Checking the build status 1
  async_status:
    jid: "{{ job1.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 10
  delay: 1
  when: job1.ansible_job_id is defined

This will check the async status 10 times with a 1 second interval and it will fail if during the 10 seconds the "until" conditions is not satisfied

Related