Run Long-Running Ansible Tasks Without Timeout

The Problem

fatal: [server]: FAILED! => {"msg": "Timeout (12s) waiting for privilege escalation prompt"}

Or tasks that take 30+ minutes (updates, backups, compilations) timing out.

Solution: async & poll

- name: Run long database backup (up to 1 hour)
  ansible.builtin.command: /usr/local/bin/backup-database.sh
  async: 3600    # Max runtime: 1 hour
  poll: 30       # Check every 30 seconds

Fire and Forget (poll: 0)

- name: Start background process
  ansible.builtin.command: /opt/app/rebuild-index.sh
  async: 7200
  poll: 0
  register: background_job

- name: Do other tasks while waiting...
  ansible.builtin.debug:
    msg: "Index rebuild is running in the background"

- name: Check on the background job
  ansible.builtin.async_status:
    jid: "{{ background_job.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 60
  delay: 30

Parallel Long Tasks

- name: Update all servers (fire and forget)
  ansible.builtin.apt:
    upgrade: dist
  async: 3600
  poll: 0
  register: update_job

- name: Wait for all updates to finish
  ansible.builtin.async_status:
    jid: "{{ update_job.ansible_job_id }}"
  register: update_result
  until: update_result.finished
  retries: 120
  delay: 30

Common Patterns

With Timeout Increase

- name: Large file transfer
  ansible.builtin.copy:
    src: /local/large-file.tar.gz
    dest: /remote/large-file.tar.gz
  async: 1800
  poll: 10
  timeout: 1800  # SSH timeout

Check Multiple Background Jobs

- name: Start jobs on all hosts
  ansible.builtin.command: "/opt/heavy-task.sh"
  async: 3600
  poll: 0
  register: heavy_tasks

- name: Wait for all to complete
  ansible.builtin.async_status:
    jid: "{{ item.ansible_job_id }}"
  register: async_results
  until: async_results.finished
  retries: 120
  delay: 15
  loop: "{{ heavy_tasks.results }}"

Limits

  • async doesn't work with become on some connection types
  • Not all modules support async
  • Fire-and-forget tasks (poll: 0) won't report failures unless you check

Conclusion

Use async + poll for any task over 30 seconds. Fire-and-forget (poll: 0) with async_status checks is the most efficient pattern for truly long tasks.