Bug Description
Stage 1 builds its default routes from the first entry of stage-0's widget-config map:
# gemini-stage-1/load_balancer.tf:110 — GSUITE default route
path_prefix_rewrite = "/us/home/cid/${data.terraform_remote_state.stage_0.outputs.gemini_apps_widget_ids[keys(data.terraform_remote_state.stage_0.outputs.gemini_apps_widget_ids)[0]]}?hl=en_US"
# gemini-stage-1/load_balancer.tf:143 — THIRD_PARTY fallback redirect
path_redirect = ".../cid/${data.terraform_remote_state.stage_0.outputs.gemini_apps_widget_ids[keys(data.terraform_remote_state.stage_0.outputs.gemini_apps_widget_ids)[0]]}&hl=en_US"
gemini_apps_widget_ids (gemini-stage-0/outputs.tf:149-152) is a comprehension over the widget configs, so it is {} when no applications exist — and gemini_apps itself defaults to {} (gemini-stage-0/variables.tf:335-349). keys({}) is the empty list, and indexing [0] into it fails at plan time with Invalid index / "the collection has no elements". There is no length(...) > 0 guard and no try(), so it is unconditional for that configuration, not a runtime edge case.
An empty application map is a reachable state, not a hypothetical. Stage-0 applies cleanly with no applications — every application resource is driven by for_each over the map — and deploy.sh tolerates it explicitly: configure_gemini_apps() returns early with "No applications generated." when the operator declines to create one. So an operator can finish stage-0, move to stage 1, and hit a plan-time crash whose message says nothing about the actual cause.
Environment and Deployment Context
- Stellar Engine Version/Commit:
main at commit f64ce6cd (re-verified 2026-08-10)
- Deployment Type:
- FAST Stage (if applicable): N/A — this is a blueprint, not a FAST stage
- Affected Component:
blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/load_balancer.tf:110
blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/load_balancer.tf:143
blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/outputs.tf:149-152 (the map)
blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf:335-349 (default = {})
- Terraform Version:
1.12.2 (pinned by deploy.sh via tfenv; stage-1 declares no required_version)
- GCP Provider Version:
hashicorp/google >= 5.0 (stage-1 declared constraint)
Steps to Reproduce
- Apply
gemini-stage-0 with gemini_apps = {} — or decline to create an application in the wizard.
- Configure
gemini-stage-1 and run terraform plan.
- The plan fails on the
keys(...)[0] index.
Expected Behavior
Either stage 1 refuses early with a clear message — "stage 0 has no Gemini applications; create one before deploying the front end" — or it plans and omits the default route.
Actual Behavior
terraform plan fails on the keys(...)[0] index before any resource is evaluated. The message names the index expression, not the missing application, so it gives no hint that the fix is to create an application in stage 0.
Relevant Logs and Errors
Expected error (from source inspection; not captured from a run):
Error: Invalid index
on load_balancer.tf line 110, in resource "google_compute_region_url_map" "gemini_enterprise_load_balancer":
110: path_prefix_rewrite = "/us/home/cid/${data.terraform_remote_state.stage_0.outputs.gemini_apps_widget_ids[keys(...)[0]]}?hl=en_US"
The given key does not identify an element in this collection value: the collection has no
elements.
Suggested Fix
Guard both expressions: a local holding the first key with a length(...) > 0 ? ... : "" fallback, plus a precondition on the url map stating the requirement. The precondition is the valuable half — it turns a confusing index error into the actual instruction.
Additional Context
Read from source; confirmed against main @ f64ce6cd, 2026-08-10.
Bug Description
Stage 1 builds its default routes from the first entry of stage-0's widget-config map:
gemini_apps_widget_ids(gemini-stage-0/outputs.tf:149-152) is a comprehension over the widget configs, so it is{}when no applications exist — andgemini_appsitself defaults to{}(gemini-stage-0/variables.tf:335-349).keys({})is the empty list, and indexing[0]into it fails at plan time withInvalid index/ "the collection has no elements". There is nolength(...) > 0guard and notry(), so it is unconditional for that configuration, not a runtime edge case.An empty application map is a reachable state, not a hypothetical. Stage-0 applies cleanly with no applications — every application resource is driven by
for_eachover the map — anddeploy.shtolerates it explicitly:configure_gemini_apps()returns early with "No applications generated." when the operator declines to create one. So an operator can finish stage-0, move to stage 1, and hit a plan-time crash whose message says nothing about the actual cause.Environment and Deployment Context
mainat commitf64ce6cd(re-verified 2026-08-10)blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/load_balancer.tf:110blueprints/fedramp-high/gemini-enterprise/gemini-stage-1/load_balancer.tf:143blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/outputs.tf:149-152(the map)blueprints/fedramp-high/gemini-enterprise/gemini-stage-0/variables.tf:335-349(default = {})1.12.2(pinned bydeploy.shvia tfenv; stage-1 declares norequired_version)hashicorp/google >= 5.0(stage-1 declared constraint)Steps to Reproduce
gemini-stage-0withgemini_apps = {}— or decline to create an application in the wizard.gemini-stage-1and runterraform plan.keys(...)[0]index.Expected Behavior
Either stage 1 refuses early with a clear message — "stage 0 has no Gemini applications; create one before deploying the front end" — or it plans and omits the default route.
Actual Behavior
terraform planfails on thekeys(...)[0]index before any resource is evaluated. The message names the index expression, not the missing application, so it gives no hint that the fix is to create an application in stage 0.Relevant Logs and Errors
Expected error (from source inspection; not captured from a run):
Suggested Fix
Guard both expressions: a
localholding the first key with alength(...) > 0 ? ... : ""fallback, plus apreconditionon the url map stating the requirement. The precondition is the valuable half — it turns a confusing index error into the actual instruction.Additional Context
Read from source; confirmed against
main@f64ce6cd, 2026-08-10.