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: minio does not support user-defined MinIO group names.
- A role default such as
minio_cluster: minio makes 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_cluster
minio_cluster
redis_cluster
mysql_cluster
kafka_cluster
- A non-member host should leave only the current play. Later plays in
deploy.yml must 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
minio group.
- 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.yml
pgsql.yml, pgsql-rm.yml
minio.yml, minio-rm.yml
redis.yml, redis-rm.yml
mysql.yml
kafka.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-check with 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_host is 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.
Problem
Several Pigsty deployment playbooks intentionally use
hosts: allso 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:
MinIO has a related membership problem:
hosts: miniodoes not support user-defined MinIO group names.minio_cluster: miniomakes the variable unsuitable as a host-membership marker, because unrelated hosts may inherit it.Expected behavior
pg_clusterminio_clusterredis_clustermysql_clusterkafka_clusterdeploy.ymlmust remain reachable.*_seq, node number, or role should fail explicitly inside the module's existing identity validation instead of silently skipping the host.miniogroup.Proposed minimal change
Use a compact play-level gate on broad module entry points:
Keep the corresponding role/block-level
when: <cluster> is definedas 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.ymlcurrently runsnode_idandpg_remove, not the fullpg_idrole. 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.ymlExplicit-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
hostvarsor inventory groups should be reviewed separately.Acceptance criteria
--syntax-checkwith Ansible 2.9 and the current supported Ansible version.meta: end_hostis play-local.