Search code examples
amazon-ec2ansibleansible-inventory

Filter hosts using a variable from with_items in ansible


I have the following set up for Ansible, and I would like to parameterize a filter that will loop, and filter out specific hosts.

- name: run on hosts
  hosts: "{{ item }}"

  roles: 
    - directory/role-name

  with_items:
    - us-east-1a
    - us-east-1b
    - us-east-1c

The result would be that the role called role-name would be first run on us-east-1a hosts, then us-east-1b... etc.

The above simple errors out with

ERROR! 'with_items' is not a valid attribute for a Play

Is there a way to accomplish what I am trying to do, which is chunking my host list into groups, and running the same role against them, one at a time?

The following achieves the result I am looking for, but is clunky, and not dynamic in length.

- name: run on us-east-1a
  hosts: "us-east-1a"
  roles:
    - my-role


- name: run on us-east-1b
  hosts: "us-east-1b"
  roles:
    - my-role


- name: run on us-east-1c
  hosts: "us-east-1c"
  roles:
    - my-role

Solution

  • I think the only way to (1) have a common code and (2) serialise play execution per group of hosts (with targets inside a group running in parallel) would be to split your playbook into two:

    playbook-main.yml

    ---
    - import_playbook: playbook-sub.yml
      vars:
        host_group_to_run: us-east-1a
    - import_playbook: playbook-sub.yml
      vars:
        host_group_to_run: us-east-1b
    - import_playbook: playbook-sub.yml
      vars:
        host_group_to_run: us-east-1c
    

    playbook-sub.yml

    - hosts: "{{ host_group_to_run }}"
      roles:
        - my-role
    
      # other common code
    

    If you wanted to serialise per host, then there is a serial declaration that might be used in conjunction with this suggestion, but despite your comments and edit, it's unclear because once you refer to us-east-1a as a "host" in singular form, other times as a "group of hosts" or an "availability zone".