I'm using Ansible 2.9 and AWX 11. I have a fleet of servers, some of which can be logically segmented by a tag that follows a pattern like GUID_1234567890
. There is an arbitrary number of servers represented by each unique GUID_*
tag. In addition to the GUID_*
tag, a server will be tagged with either foo
or bar
.
In more concrete terms, I have 2,000 servers, 1,000 of which are tagged with 80 unique GUID_*
tags. Within each of those 80 unique GUID_*
groups of servers, I have to restart the servers tagged with foo
, but not the servers tagged with bar
. Furthermore, I have to reboot the foo
servers serially if they have the same GUID_*
tag.
I can launch a playbook with a host pattern like this: hosts: GUID_*:&foo
and get all of the GUID_
tagged foo
hosts. However, if the playbook's serial:
option is anything except 1
, foo servers will be restarted in parallel, most likely multiple foo servers within the same GUID_
tag group. When performed serially, the playbook can take upwards of a day to complete. I'd like to use Ansible's forking to run a fork of a playbook for each of the 80 groups of GUID_*
hosts, but each fork must call a playbook that itself runs as serial:1
against the foo
servers.
Is there a way to start with large set of hosts, but then create parallel workers that execute serial: 1
playbooks for a subset of hosts?
It's not possible to achieve the goal in a single playbook. A dedicated playbook for each group is needed if you want to process the groups in parallel. Use Ansible to create the code.
"Smaller subsets of hosts"
Given the inventory to simplify the testing
Create a dictionary of all GUID_* and a list of hosts both in particular GUID_x and foo groups. For example
gives
The same dictionary can be created without patterns
Q: "Create parallel workers that execute serial: 1 playbooks for a subset of hosts."
A: Use Ansible templates to create the code. For example, given the role
The templates
and the playbook
create the files with the code
Then, running the wrapper gives