scripts/generate-federation-iac.go fails on every target/source combination in its default --format=tfvars mode. The iacData struct does not declare three fields that the tfvars templates reference, and Go's text/template treats a missing struct field as an execution error rather than an empty string.
Reproduced on main at 02702a108 (not on a branch):
$ go run scripts/generate-federation-iac.go --target aws --source azure \
--account-name Acme --account-id 123456789012 \
--tenant-id 1111...5555 --output -
Error: render internal/iacfiles/templates/aws-wif.tfvars.tmpl:
template: iac:18:19: executing "iac" at <.CUDlyAPIURL>:
can't evaluate field CUDlyAPIURL in type main.iacData
All five tfvars outputs fail. Each row below was verified by execution:
--target / --source |
template |
fails on |
aws / aws |
aws-cross-account.tfvars.tmpl |
SourceAccountID |
aws / azure |
aws-wif.tfvars.tmpl |
CUDlyAPIURL |
azure / aws |
azure-wif.tfvars.tmpl |
CUDlyAPIURL |
gcp / gcp |
gcp-sa-impersonation.tfvars.tmpl |
CUDlyAPIURL |
gcp / aws |
gcp-wif.tfvars.tmpl |
SourceAccountID |
singleFileTmpl routes six cases, but one is aws-wif-cf-params.json (JSON, not tfvars), so there are five tfvars outputs and all five fail.
Missing fields
iacData (scripts/generate-federation-iac.go:79-94) declares 11 fields. The tfvars templates reference three it does not have:
ContactEmail — referenced by all five tfvars templates
CUDlyAPIURL — referenced by all five
SourceAccountID — referenced by aws-cross-account.tfvars.tmpl and gcp-wif.tfvars.tmpl
Rendering stops at the first missing field, so CUDlyAPIURL masks ContactEmail in most cases. Adding only the field named in the error message will surface the next one.
The trap for whoever fixes this
gcp-wif.tfvars.tmpl fails on a different field depending on --source:
--target gcp --source aws -> gcp-wif.tfvars:22 SourceAccountID
--target gcp --source azure -> gcp-wif.tfvars:44 CUDlyAPIURL
SourceAccountID is reachable on that template only via --source aws. A test covering gcp/azure but not gcp/aws renders successfully and leaves SourceAccountID's wiring entirely unexercised. Cover all six routed combinations, not one per template.
SourceAccountID is also the field most likely to be wired wrong. It is the source account; --account-id is the target. Resolving it to --account-id leaves four of five paths rendering fine while the two SourceAccountID consumers carry a silently wrong value into IaC a customer then applies.
Scope
Affects the standalone generator script only. The server-rendered path uses a different data type that carries these fields, which is why the templates themselves are correct and nothing else is broken. --format=bundle and --format=cf-params were not exercised here and may be unaffected.
Why CI is green
No test executes this script's tfvars paths. internal/iacfiles tests exercise the templates against the server data type, which satisfies every field, so template/struct drift in the script is invisible to them.
Suggested fix
Add the three fields to iacData, populate them in populateData, and add a test that runs each routed --target/--source combination through the real --format=tfvars path and asserts a successful render plus the presence of the key fields. That test is what stops this recurring: the gap is not the missing fields but that no test drives the script end to end.
No silent fallbacks — if a value cannot be determined, fail with an explicit error naming the missing flag rather than emitting an empty or guessed value into generated IaC.
Keep the fix to those three fields and the coverage that catches the drift. Do not restructure the script or unify the two data types under this issue.
Found while reviewing #1691; split out from LeanerCloud/cloud-commitments-platform#153 because that issue tracks hardening drift in templates whereas this is a current breakage on main.
scripts/generate-federation-iac.gofails on every target/source combination in its default--format=tfvarsmode. TheiacDatastruct does not declare three fields that the tfvars templates reference, and Go'stext/templatetreats a missing struct field as an execution error rather than an empty string.Reproduced on
mainat02702a108(not on a branch):All five tfvars outputs fail. Each row below was verified by execution:
--target/--sourceaws/awsaws-cross-account.tfvars.tmplSourceAccountIDaws/azureaws-wif.tfvars.tmplCUDlyAPIURLazure/awsazure-wif.tfvars.tmplCUDlyAPIURLgcp/gcpgcp-sa-impersonation.tfvars.tmplCUDlyAPIURLgcp/awsgcp-wif.tfvars.tmplSourceAccountIDsingleFileTmplroutes six cases, but one isaws-wif-cf-params.json(JSON, not tfvars), so there are five tfvars outputs and all five fail.Missing fields
iacData(scripts/generate-federation-iac.go:79-94) declares 11 fields. The tfvars templates reference three it does not have:ContactEmail— referenced by all five tfvars templatesCUDlyAPIURL— referenced by all fiveSourceAccountID— referenced byaws-cross-account.tfvars.tmplandgcp-wif.tfvars.tmplRendering stops at the first missing field, so
CUDlyAPIURLmasksContactEmailin most cases. Adding only the field named in the error message will surface the next one.The trap for whoever fixes this
gcp-wif.tfvars.tmplfails on a different field depending on--source:SourceAccountIDis reachable on that template only via--source aws. A test coveringgcp/azurebut notgcp/awsrenders successfully and leavesSourceAccountID's wiring entirely unexercised. Cover all six routed combinations, not one per template.SourceAccountIDis also the field most likely to be wired wrong. It is the source account;--account-idis the target. Resolving it to--account-idleaves four of five paths rendering fine while the twoSourceAccountIDconsumers carry a silently wrong value into IaC a customer then applies.Scope
Affects the standalone generator script only. The server-rendered path uses a different data type that carries these fields, which is why the templates themselves are correct and nothing else is broken.
--format=bundleand--format=cf-paramswere not exercised here and may be unaffected.Why CI is green
No test executes this script's tfvars paths.
internal/iacfilestests exercise the templates against the server data type, which satisfies every field, so template/struct drift in the script is invisible to them.Suggested fix
Add the three fields to
iacData, populate them inpopulateData, and add a test that runs each routed--target/--sourcecombination through the real--format=tfvarspath and asserts a successful render plus the presence of the key fields. That test is what stops this recurring: the gap is not the missing fields but that no test drives the script end to end.No silent fallbacks — if a value cannot be determined, fail with an explicit error naming the missing flag rather than emitting an empty or guessed value into generated IaC.
Keep the fix to those three fields and the coverage that catches the drift. Do not restructure the script or unify the two data types under this issue.
Found while reviewing #1691; split out from LeanerCloud/cloud-commitments-platform#153 because that issue tracks hardening drift in templates whereas this is a current breakage on
main.