0

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
Nicholas
  • 3,286
  • 5
  • 27
  • 35
  • I'm trying to loop over groups of hosts, by availability zones, one at a time. So all of my us-east-1a first, and then 1b... etc. – Nicholas Nov 03 '17 at 13:40
  • `by availability zones, one at a time` – Nicholas Nov 03 '17 at 13:44
  • Help to be clearer if I'm missing something, but I am simply trying to run the same role against a `group of hosts`, one at a time. So instead of clumping the above into three different runs... I would like to filter the hosts out for targeted availability zones, at each iteration. – Nicholas Nov 03 '17 at 13:47
  • Have you tried to dynamically build an inventory group and reference this group in the next playbook? (see http://docs.ansible.com/ansible/latest/list_of_inventory_modules.html) – Max Nov 04 '17 at 13:46

2 Answers2

2

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".

techraf
  • 64,883
  • 27
  • 193
  • 198
  • OK... I think this accomplishes what I am looking for. Yeah I caught the `host` issue and edited it. The `us-east-1a` is a filter for a group of hosts. I don't need them to run serially, just in chunks as I think your answer accomplishes here. – Nicholas Nov 03 '17 at 15:13
0

Will host patterns do the job?:

- name: run on us-east-1a
  hosts: us-east-1a,us-east-1b,us-east-1c
  roles:
    - my-role

Update: @techraf has opened my eyes with his comment – host pattern alone will not do the job.
It will just concatenate all hosts from all groups.
But in a predictable way, which in some cases can be used to iterate hosts in every group separately.
See this answer for details.

Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • I can check that... will that group them one at a time? – Nicholas Nov 03 '17 at 15:08
  • It should. At least for Ansible 2.3 it was the case. – Konstantin Suvorov Nov 03 '17 at 15:09
  • I would have to add extra tags... so it would look something like this... `hosts:"tag_Name_value:&us-east-1a,tag_Name_value:&us-east-1b"` – Nicholas Nov 03 '17 at 15:14
  • @KonstantinSuvorov "*will that group them one at a time?*" - "*It should.*" -- how come? It will create a set of hosts from a concatenation of the three groups and run against this result, not sequentially against hosts in each of the groups. – techraf Nov 04 '17 at 00:20
  • Thanks for opening my eyes. It will create a "sorted" set: all hosts from first group, then all hosts from second group and so on. – Konstantin Suvorov Nov 04 '17 at 08:02