# Howto execute ansible one host group at a time?

**URL:** <https://forum.ansible.com/t/howto-execute-ansible-one-host-group-at-a-time/45168>\
**Category:** Get Help\
**Tags:** galaxy-ng\
**Created:** [January 24, 2026, 10:38am UTC](https://forum.ansible.com/t/howto-execute-ansible-one-host-group-at-a-time/45168 "2026-01-24T10:38:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![S1lverhead](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/s1lverhead/32/10170_2.png) [@S1lverhead](https://forum.ansible.com/u/S1lverhead)\
**Post date:** [January 24, 2026, 10:38am UTC](https://forum.ansible.com/t/howto-execute-ansible-one-host-group-at-a-time/45168/1 "2026-01-24T10:38:52Z")

</div>

hi,

I have a problem with Ansible 2.16.3(and can’t perform upgrade to newer version in an easy way) I didn’t expect to face.

I have playbooks I need to execute on multiple host groups but only one host group(HG) at a time(dependencies between services).

- Hosts in HG2(50 hosts) can be executed after all hosts in HG1(20) finished.
- Hosts in HG3(600 hosts) can be executed after all hosts in HG2(50 hosts) finished.
- etc till Hex

I have ANSIBLE\_FORKS set to 300 (infra limit).  
It would be good keep it due to total number of hosts that must be handled.

**Problem:**  
ANSIBLE\_FORKS allows execution of HG1 and HG2 and part of HG3 in parallel to match total 300 and keeps rolling.

**Things explored:**

- keyword serial but see no option to limit to “one HG at a time up to limit ANSIBLE\_FORKS”.
- –limit CLI parameter - doesn’t seem to work.
- keyword delegate - works for one host only
- import\_task but by the time this is evaluated it’s already running on multiple HGs.
- execution strategies available in default installation
- host group parameter for play using “HG1:HG2:HG3” and “HG1 HG2 HG3”. In documentation I see no mention of “ansible waits for one HG to finish before next one starts”

**Things I’d like to avoid:**

- I have a bash script to control Ansible execution. I’d like to avoid running Ansible multiple times in a for loop one HG at a time. It’s stupid to control execution strategy of Ansible from Bash script :-/
- Writing a ton of short plays in one file for every single HG.
- using serial and listing it like snippet below. We are talking 20HGs and bunch of different ansible plays.

```auto
 strategy: linear
  hosts:
    - group1
    - group2
    - group3
  serial:
    - "{{ groups['group1'] | count }}"
    - "{{ groups['group2'] | count }}"
    - "{{ groups['group3'] | count }}"

```

**Things I’m thinking about:**

- could tags solve this?
- could a custom execution strategy solve this? Is it available on Ansible galaxy or somewhere else? Can someone draft it if it must be written?
- any other ideas?

Can someone suggest a solution?

What am I missing?

I can’t believe it I can’t find an explicit way to tell ansible “execute next host group once first finished”

thank you, Honza

---

<div class="post-metadata">

**Author:** ![kks](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/kks/32/10352_2.png) [@kks](https://forum.ansible.com/u/kks)\
**Post date:** [January 24, 2026, 10:58am UTC](https://forum.ansible.com/t/howto-execute-ansible-one-host-group-at-a-time/45168/2 "2026-01-24T10:58:36Z")

</div>

You can have several plays inside playbook and this is something that might be helful in this case.

This is what comes to mind.

```auto
---
- name: Run on group 1
  ansible.builtin.import_playbook: playbook.yml
  vars:
    hosts: group1
- name: Run on group 2
  ansible.builtin.import_playbook: playbook.yml
  vars:
    hosts: group1

---
# playbook.yml
- name: Run tasks
  hosts: "{{ hosts }}"
  tasks: 
    ....

```

Did not try this to be honest.

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [January 24, 2026, 8:33pm UTC](https://forum.ansible.com/t/howto-execute-ansible-one-host-group-at-a-time/45168/3 "2026-01-24T20:33:05Z")

</div>

Q: _ **“How to execute Ansible one host group at a time ?”** _

A: Put the code into a role(s) and import them conditionally. For example, given the trivial role _test_

```console
shell > cat roles/test/tasks/main.yml 

```

```yaml
- debug:
    msg: "Running at {{ inventory_hostname }}"

```

, the inventory

```ini
[HG1]
host_10
host_11

[HG2]
host_20
host_21

[HG3]
host_30
host_31

```

, and the playbook

```yaml
- name: Import roles conditionally.
  hosts: all

  tasks:

    - import_role:
        name: test
      when: inventory_hostname in groups.HG1

    - import_role:
        name: test
      when: inventory_hostname in groups.HG2

    - import_role:
        name: test
      when: inventory_hostname in groups.HG3

```

The play runs as expected

```yaml
PLAY [Import roles conditionally.] **********************************************************************************

TASK [test : debug] *************************************************************************************************
ok: [host_10] => 
    msg: Running at host_10
ok: [host_11] => 
    msg: Running at host_11

TASK [test : debug] *************************************************************************************************
ok: [host_20] => 
    msg: Running at host_20
ok: [host_21] => 
    msg: Running at host_21

TASK [test : debug] *************************************************************************************************
ok: [host_30] => 
    msg: Running at host_30
ok: [host_31] => 
    msg: Running at host_31

PLAY RECAP **********************************************************************************************************
host_10 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_11 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_20 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_21 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_30 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_31 : ok=1 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0

```

Q: _ **“Would loop work?”** _

A: Yes, it would. But, in the loop, you have to use _include\_role_ instead of the _import\_role_. See the difference between the static and dynamic use of the [roles](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_reuse_roles.html#roles). Create the file _include\_role.yml_

```yaml
- include_role:
    name: test
  when: inventory_hostname in groups[item]

```

and iterate the groups’ list

```yaml
- name: Include roles conditionally.
  hosts: all
  
  tasks:

    - include_tasks: include_role.yml
      loop: [HG1, HG2, HG3]

```

The play runs as expected

```yaml
PLAY [Include roles conditionally.] *********************************************************************************

TASK [include_tasks] ************************************************************************************************
included: /export/scratch/vbotka/vbotka.ansible_qa/tasks/so-79874782/include_role.yml for host_10, host_11, host_20, host_21, host_30, host_31 => (item=HG1)
included: /export/scratch/vbotka/vbotka.ansible_qa/tasks/so-79874782/include_role.yml for host_10, host_11, host_20, host_21, host_30, host_31 => (item=HG2)
included: /export/scratch/vbotka/vbotka.ansible_qa/tasks/so-79874782/include_role.yml for host_10, host_11, host_20, host_21, host_30, host_31 => (item=HG3)

TASK [include_role : test] ******************************************************************************************
included: test for host_10, host_11

TASK [test : debug] *************************************************************************************************
ok: [host_10] => 
    msg: Running at host_10
ok: [host_11] => 
    msg: Running at host_11

TASK [include_role : test] ******************************************************************************************
included: test for host_20, host_21

TASK [test : debug] *************************************************************************************************
ok: [host_20] => 
    msg: Running at host_20
ok: [host_21] => 
    msg: Running at host_21

TASK [include_role : test] ******************************************************************************************
included: test for host_30, host_31

TASK [test : debug] *************************************************************************************************
ok: [host_31] => 
    msg: Running at host_31
ok: [host_30] => 
    msg: Running at host_30

PLAY RECAP **********************************************************************************************************
host_10 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_11 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_20 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_21 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_30 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0   
host_31 : ok=5 changed=0 unreachable=0 failed=0 skipped=2 rescued=0 ignored=0

```

[source code](https://github.com/vbotka/ansible_qa/tree/master/tasks/so-79874782)
