Is it possible to run task with loop async?

Viewed 31

I have a huge ansible playbook and I have a task, which is using an array (from values) and run the same command for each element in array.

For example (this is just example, I know that I can use one line command!):

packages:
  vim:
    dev:
      version: x.x
    qa:
      version: x.x
  redis:
    dev:
      version: x.x
    qa:
      version: x.x
  ...

And I have a task which is installing these packages:

- name: Install Packages
  include_tasks: tasks/install-packages.yml
  loop: "{{ lookup('dict', packages) }}"
  loop_control:
    loop_var: item

and

- name: "Install {{ item.key }} package"
  command: >
    apt-get install {{ item.key }} ...
  environment:
    ...
  retries: 3
  delay: 5
  register: result
  until: result.rc == 0

My question is - is it possible to run the last step in threads?

As I understand - first of all I need to split packages array and run task in async mode.

In this example - apt-get install vim and apt-get install redis should start installing simultaneously.

Is it possible? Or maybe there can be some another solution?

The main goal of it - speed up package installation (for this example).

1 Answers

I found solution here

#####################
# main.yml
#####################
- name: Run items asynchronously in batch of two items
  vars:
    sleep_durations:
      - 1
      - 2
      - 3
      - 4
      - 5
    durations: "{{ item }}"
   include_tasks: execute_batch.yml
   loop: "{{ sleep_durations | batch(2) | list }}"

#####################
# execute_batch.yml
#####################
- name: Async sleeping for batched_items
  ansible.builtin.command: sleep {{ async_item }}
  async: 45
  poll: 0
  loop: "{{ durations }}"
  loop_control:
    loop_var: "async_item"
  register: async_results

- name: Check sync status
  async_status:
    jid: "{{ async_result_item.ansible_job_id }}"
  loop: "{{ async_results.results }}"
  loop_control:
    loop_var: "async_result_item"
  register: async_poll_results
  until: async_poll_results.finished
  retries: 30
Related