Adam Kotwasinski
Adam Kotwasinski

Reputation: 4564

Running multiple Ansible steps in parallel

Let's say I have a long playbook that is composed of several largely independent steps (I use it to deploy my test code):

    # steps for service 1
    - file:
        # setup config dir for service1
    - template:
        # setup config file for service1
    - community.docker.docker_image:
        # get the image1
    - community.docker.docker_container:
        # have the image1 started

    # steps for service 2
    - file:
        # setup config dir for service2
    - template:
        # setup config file 1 for service2
    - template:
        # setup config file 2 for service2
    - community.docker.docker_image:
        # get the image2
    - community.docker.docker_container:
        # have the image2 started

    # steps for service 3
    - file:
        # setup config dir for service3
    - template:
        # setup config file 1 for service3
    - template:
        # setup config file 2 for service3
    - community.docker.docker_image:
        # get the image3
    - community.docker.docker_container:
        # have the image3 started

Obviously when I run it, it runs each of the steps sequentially, taking a bit of time. Is it possible to somehow make Ansible run each "fat block" (for service1, service2, service3) in parallel in an easy fashion? Basically something to "group" them into a "function" that could then be started and waited for.

In other words, how to make Ansible-equivalent of:

block1 & # does service1 stuff
block2 & # does service2 stuff
block3 & # does service3 stuff
wait; wait; wait

(I'm a total newbie to Ansible so it's possible I'm missing some reogranisation knowledge).

Upvotes: 1

Views: 203

Answers (1)

U880D
U880D

Reputation: 12142

As already discussed within the comments there is only the possibility to run concurrently: poll = 0 for tasks.

If you want to run multiple tasks in a playbook concurrently, use async with poll set to 0. When you set poll: 0, Ansible starts the task and immediately moves on to the next task without waiting for a result.

Together with that and in order to decrease the overall runtime of your playbook, you could organize it task centric instead of service centric.

vars:

  service_list:
    - service1
    - service2
    - service3

tasks:

# Prepare

- name: Setup config dir for services
  file:
    path: /dir/{{ item }}/
    state: directory
  loop: "{{ service_list }}"

- name: Copy config files for services
  template:
    src: templates/{{ item }}.j2
    dest: /dir/{{ item }}
  loop: "{{ service_list }}"

# Long running tasks, could probably be an include_

- name: "Download the image {{ service_list[0] }}"
  community.docker.docker_image:
    name: "{{ service_list[0] }}"
    source: pull
    pull: true
  async: 600
  poll: 0

- name: "Download the image {{ service_list[1] }}"
  community.docker.docker_image:
    name: "{{ service_list[1] }}"
    source: pull
    pull: true
  async: 600
  poll: 0

- name: "Download the image {{ service_list[2] }}"
  community.docker.docker_image:
    name: "{{ service_list[2] }}"
    source: pull
    pull: true
  async: 600
  poll: 0

# Wait or check

- name: # Needs to be defined
  ...

# Start

- community.docker.docker_container:
    name: "{{ item }}"
    image: "{{ item }}"
  loop: "{{ service_list }}"

Upvotes: 1

Related Questions