Repository navigation
fix(infra): discover every managed GCP zone and fail closed on empty Ansible role groups - #2408
Merged
Peyton-Spencer merged 3 commits intoSep 28, 2026
Conversation
…Ansible role groups
There was a problem hiding this comment.
Ditto Review · Beta
Review completed for bac0066bdf6877aaf30b7e1eab19acaa286aacd1.
No actionable findings in the reviewed files. This is not an approval or proof that the PR is bug-free.
Configure Ditto Review. Inference is billed through your Ditto Router endpoint; targeted verification is included during beta.
Peyton-Spencer
approved these changes
Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #547. Implements zone discovery, per-host IAP zones, the empty-group guard and multi-zone CI fixtures. Remaining: supporting and documenting a short-lived
gcloudaccess-token workflow next to ADC.auth_kind: applicationis set directly ininventory/gcp.yml, and options set in the file take precedence overGCP_AUTH_KIND/GCP_ACCESS_TOKEN, so this needs its own design decision.Problem
infra/ansible/inventory/gcp.ymlonly listedus-central1-a. Terraform (stacks/gcp-platform) also places the legacy prod screener inus-central1-c(var.screener_prod_zone) and spreads the regional screener MIG overus-central1-a/b/c/f(var.screener_fleet_zones), so the inventory silently left those hosts out. Everygroup_vars/role_*.ymlalso hard-codedgcp_zone: us-central1-afor the IAP ProxyCommand, so even a discovered host outside zone a would tunnel to the wrong zone. A play whose group matches no hosts is skipped and the run exits 0, so a missing host looked like a successful converge.Change
inventory/gcp.ymlnow lists exactly the fourus-central1zones Terraform uses, and addsgcp_zone: zonetocompose, so each host's IAP tunnel uses its instance's own zone.gcp_zonefrom all tengroup_vars/role_*.yml. Both static fallback inventories (validator-static.yml,screener-capacity-static.yml) now setgcp_zone: us-central1-aper host. This matches Terraform'svar.zone. A host with no zone now fails when the variable is templated instead of falling back to zone a.playbooks/require-hosts.ymlruns first in everygcp-*.ymlplaybook (import_playbookwithrequired_groupset to the group that playbook targets). It fails when that group has no hosts. It targetslocalhost:alland intersects with the play's hosts, so it also runs under--limitand catches a limit that falls outside the group.assertruns on the controller and connects to no host. A--limitnaming an absent host already fails in ansible-core ("leaves us with no hosts to target").tests/gcp-inventory/: instance-shaped hosts in zones a/b/c/f, aconstructedconfig that replaysgcp.yml'skeyed_groups/compose, and the realgroup_varsvia a symlink.tests/gcp-inventory.ymlchecks four things:gcp.ymlzones equal the quoted zone literals instacks/gcp-platform/*.tf; the fixture's compose/keyed_groups equalgcp.yml's; every host'sgcp_zoneequals its instance zone and its ProxyCommand says--zone=<that zone>(e.g.us-central1-cforditto-screener-prod); and the guard accepts a multi-zone group. The newinfra-ci.ymlstep also requires the guard to fail on an empty group and on a--limitoutside the group. Nothing calls GCP.Verification
All commands were run from
infra/ansiblewithuvx --from ansible-core==2.21.2:ansible-inventory -i tests/gcp-inventory --graph:role_platform_app,role_screener, androle_screener_fleet(b1, f1) were grouped as expected.ansible-playbook -i tests/gcp-inventory tests/gcp-inventory.yml: passed (localhost ok=4, 4 fixture hosts ok=1).origin/main'sinventory/gcp.ymlfailed withinventory/gcp.yml zones ['us-central1-a'] != Terraform zones [...]. Withgcp_zonecompose removed, it failed. With a staticgcp_zonere-added torole_screener.yml, it still passed, which confirms the composed host var takes precedence.ansible-playbook -i tests/gcp-inventory playbooks/require-hosts.yml -e required_group=role_validator_prod: exit 2, "role_validator_prod resolved to no hosts".... -e required_group=role_screener --limit ditto-platform-prod: exit 2.--limit ditto-screener-prod: exit 0, and no host was contacted.ansible-playbook -i inventory/validator-static.yml playbooks/gcp-screener.yml: failed at the guard before any host play.ansible -i inventory/{validator,screener-capacity}-static.yml all -m debug -a var=ansible_ssh_common_args: both rendered--zone=us-central1-a.bash -euo pipefail: exit 0.ansible-playbook --syntax-check -i inventory/validator-static.ymlon every playbook in the CI list, plusgcp-pg.yml,gcp-coding-hosted-runtime.ymlandtests/gcp-inventory.yml: all passed.python3 tests/test_docker_apt_key_pin.py: OK.ansible-playbook --check -i tests/coding-hosted-postgres-inventory.yml tests/coding-hosted-postgres.yml: failed=0.