Ansible: How to run one Task Host by Host?

Solution 1:

If you don't want any parallelism in performing the steps in your playbook, set the fork level to 1:

ansible-playbook --forks=1 ...

You can also put this in your ansible cfg file:

[defaults]
forks=1

but if you want it on an individual basis, use the command line option above.

EDIT:

serial: 1 does something completely different: that is like running the playbook for each host in turn, waiting for completion of the complete playbook before moving on to the next host. forks=1 means run the first task in a play on one host before running the same task on the next host, so the first task will be run for each host before the next task is touched.

So you want forks=1 for just one play; unfortunately that is not currently possible.

Solution 2:

You can run a single task in serial (i.e. host-by-host) by adding throttle: 1 to it.

Example:

---

- hosts: all
  tasks:
      - name: wait in parallel
        command: sleep 20
      - name: wait  in serial
        command: sleep 30
        throttle: 1

References:

  • Using keywords to control execution
  • Playbook Keywords: Tasks

NB: throttle was introduced in Ansible 2.9


Solution 3:

There's a workaround to this problem - one can pass list of hosts (or a group) to with_items, and then use delegate_to with this list. This way task will be executed host by host.

For example:

- name: start and enable rabbitmq (run task host by host)
  service:
    name: "rabbitmq-server"
    state: "started"
    enabled: true
  delegate_to: "{{ item }}"
  with_items: "{{ groups['rabbitmq-cluster'] }}"
  run_once: true