Captain Blammo
Captain Blammo

Reputation: 1897

Run an imported Ansible playbook for each unique value in a set of host vars

I've got a playbook which needs to run against my entire inventory, with a list of hostnames as an extra variable (target_hosts).

The hosts in target_hosts all have a group_id hostvar defined on them. I use the whole inventory because some ancillary hosts which correspond to the group_id var need per-group configuration to match in one section.

There will often be multiple group_id values associated with the hosts in the target_hosts list. I need to select the correct inventory group of ancillary hosts and import/run a playbook to configure both sets of servers partway through the main playbook.

This is what I currently do:

include_playbook: group-configure.yaml
vars:
  src_hosts: "group-{{ group_id }}-ancillary-1"
  dest_hosts: "{{ target_hosts }}"

I currently have to manually separate the target_hosts by group_id manually, then run the main playbook once for each. This has tons of unnecessary overhead.

What I really want to execute is this:

for each group of hosts from `target_hosts` with the same `group_id` hostvar:
  import and run group-configure.yaml with:
    src_hosts: "ancillary-{{ group_id }}"
    target_hosts: restricted to those with that value of `group_id`'

How can I do this? If the current way this is structured won't work, what's the best alternative approach?

Upvotes: 0

Views: 1422

Answers (1)

mdaniel
mdaniel

Reputation: 33223

I am pretty sure the add_host: combined with groupby is what you are looking for, which will allow you to roll up those hosts by their attribute, and then run the playbook against them as if that group was defined already:

- hosts: localhost
  connection: local
  gather_facts: no
  become: no
  vars:
    list_of_name_groups: >-
        {%- set results = [] -%}
        {%- for g_id, items in (dict(hostvars) | dict2items | groupby("value.group_id")) -%}
        {%- for hostname in (items | map(attribute="key") | list) -%}
        {%- set _ = results.append({"group_id": g_id, "hostname": hostname}) -%}
        {%- endfor -%}
        {%- endfor -%}
        {{ results }}
  tasks:
  - add_host:
      name: '{{ item.hostname }}'
      groups: ancillary-{{ item.group_id }}
    with_items: '{{ list_of_name_groups }}'

- hosts: ancillary-my-awesome-groupid
  # etc etc

Upvotes: 2

Related Questions