Prevent broad Ansible playbooks from entering module roles on unrelated hosts
@Vonng is already working on this.
Since Aug 9, 2026.
- Dominant language
- Shell
- Stars
- 5.7k
- Forks
- 384
- Avg merge
- 2h 36m
- Merged PRs (30d)
- 2
Description
Problem
Several Pigsty deployment playbooks intentionally use hosts: all so that module membership can be selected from inventory variables. In a mixed inventory, however, hosts that do not belong to a module may still enter or partially evaluate that module's role/tasks.
A practical example is an inventory that defines MinIO hosts but no PostgreSQL cluster. Running the broad deployment playbook can reach PostgreSQL identity/task evaluation on a MinIO-only host and fail with errors such as:
Error while resolving value for 'pg_instance': 'pg_cluster' is undefined
Task failed: 'item' is undefined
MinIO has a related membership problem:
- A fixed inventory group name such as
hosts: miniodoes not support user-defined MinIO group names. - A role default such as
minio_cluster: miniomakes the variable unsuitable as a host-membership marker, because unrelated hosts may inherit it.
Expected behavior
- A broad module play should operate only on hosts where the corresponding cluster marker is explicitly defined:
pg_clusterminio_clusterredis_clustermysql_clusterkafka_cluster
- A non-member host should leave only the current play. Later plays in
deploy.ymlmust remain reachable. - Membership filtering should check only the cluster marker. Missing instance identity such as
*_seq, node number, or role should fail explicitly inside the module's existing identity validation instead of silently skipping the host. - Custom MinIO inventory group names should work without requiring a hard-coded
miniogroup. - The implementation must remain compatible with Ansible 2.9.
Proposed minimal change
Use a compact play-level gate on broad module entry points:
pre_tasks: [ { name: skip non-pgsql hosts, meta: end_host, when: pg_cluster is not defined, tags: always } ]
Keep the corresponding role/block-level when: <cluster> is defined as a second safety layer for execution paths that bypass pre-tasks, such as --start-at-task.
Where a destructive role does not already run a dedicated identity role, add one small fail-fast assertion before any removal task. For example, pgsql-rm.yml currently runs node_id and pg_remove, not the full pg_id role. The removal role should validate only the local identity it requires rather than introducing cluster-wide topology checks that could block cleanup of a degraded cluster.
Likely broad-entry surfaces include:
deploy.yml(MinIO and PostgreSQL plays)slim.ymlpgsql.yml,pgsql-rm.ymlminio.yml,minio-rm.ymlredis.yml,redis-rm.ymlmysql.ymlkafka.yml,kafka-rm.yml
Explicit-target operational playbooks such as PostgreSQL user/database/PITR workflows, strict removal workflows, and fixed-group plays such as ETCD should retain their existing contracts unless they independently exhibit the same broad-entry behavior.
This issue is limited to play/role entry filtering. Task-local loops that intentionally traverse hostvars or inventory groups should be reviewed separately.
Acceptance criteria
- All affected playbooks pass
--syntax-checkwith Ansible 2.9 and the current supported Ansible version. - In a synthetic mixed inventory, a non-member host exits the current module play without failure.
- A later play still runs on that host, confirming that
meta: end_hostis play-local. - Role/block-level guards prevent execution when pre-tasks are bypassed.
- A host with a cluster marker but missing required instance identity fails at the first identity assertion.
- No new validation framework or broad role refactor is introduced.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.