mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-10 12:47:04 +00:00
A role read its application_id from its own vars/main.yml, which sits
below host facts in Ansible's precedence. test-e2e-playwright loads the
tested role's vars/main.yml with include_vars and no name:, so that
role's application_id and domain land as facts and outlive the loop. The
Playwright stage runs in 02_server, the workstation stage after it, so
every later role that resolves lookup('config', application_id, ...) from
role vars asked under the last tested role's id.
A local compose deploy died on it: desk-agnt-claude looked for
services.agnt-claude under applications['web-svc-mirror'] and aborted the
play, taking four more desk roles and the whole destructor stage with it.
Ten roles resolve a config path this way; a three-argument lookup in any
of them would have returned another application's value silently instead
of failing.
Binding application_id as an include param puts it above the leaked fact.
The value is not invented: role_entry.app is the application_id the role
itself declares, and this is the same immunity the web-app roles already
have by passing application_id on their own include_tasks.
A negative control reproduced the leak and then defeated it: a probe role
declaring application_id in its own vars saw the foreign value after an
include_vars, and saw its own once the include carried the param. All 183
roles that declare an application_id declare it identical to their
directory name, and this include site has exactly one caller, so the
binding changes nothing else.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>