Stabilize Terraform plan fingerprints across UI hint ordering #108

Merged
gitchegumi merged 1 commit from kiyi/terraform-plan-fingerprint into main 2026-10-15 21:59:01 -05:00
Member

Terraform can reorder relevant_attributes UI hints between otherwise identical plans, causing a false approval-fingerprint mismatch. Private Terraform apply run 71 stopped before apply with a different fingerprint from passing plan run 70, despite the same source, workflows v1.42.0 binding and eight-create public summary. The mismatch guard correctly prevented mutation.

Reproduction: five credential-free Terraform 1.16.5 mocked Vault exports produced three different outer orders of the same three relevant attributes. All other exported fields were identical. Terraform defines these attributes as an unordered set of UI hints; its JSON exporter attempts to sort the output using indexes into the original unsorted slice. This reproduces a false mismatch without retrieving either live plan; live acceptance still remains required.

Normalize only that outer metadata list before hashing. Retain every member, field and duplicate, preserve attribute-path and all other list order, and continue binding variables, prior state, configuration, values/unknown markers, drift, checks and resource changes. Keep exact source/fingerprint approval, plan/action guards, name-absence checks, private saved-plan apply and confidentiality. No workflow/job/status names or caller inputs change.

Validation at 88ab4f4: the six-permutation regression fails against the old implementation and passes with the fix. All 37 identity/delivery/state/approval/confidentiality tests pass, including changed hint content, membership, duplicates, ordered input values, prior state and real plan changes. Native staged Gitleaks 8.30.1 and diff checks passed. All Terraform execution used existing mocked providers; no real local plan/apply, credentials or live APIs. Hosted checks remain required.

After review/checks/merge, publish and promote one release to stable-v1, then start a fresh owning identity plan and review its new fingerprint before a separately approved apply. Fingerprints from runs 70/71 must not be reused across this fingerprint-contract change. No workflow retry is dispatched by this PR.

Terraform can reorder `relevant_attributes` UI hints between otherwise identical plans, causing a false approval-fingerprint mismatch. Private Terraform apply run 71 stopped before apply with a different fingerprint from passing plan run 70, despite the same source, workflows v1.42.0 binding and eight-create public summary. The mismatch guard correctly prevented mutation. Reproduction: five credential-free Terraform 1.16.5 mocked Vault exports produced three different outer orders of the same three relevant attributes. All other exported fields were identical. [Terraform defines these attributes as an unordered set of UI hints](https://github.com/hashicorp/terraform/blob/v1.16.5/internal/plans/plan.go); its [JSON exporter](https://github.com/hashicorp/terraform/blob/v1.16.5/internal/command/jsonplan/plan.go) attempts to sort the output using indexes into the original unsorted slice. This reproduces a false mismatch without retrieving either live plan; live acceptance still remains required. Normalize only that outer metadata list before hashing. Retain every member, field and duplicate, preserve attribute-path and all other list order, and continue binding variables, prior state, configuration, values/unknown markers, drift, checks and resource changes. Keep exact source/fingerprint approval, plan/action guards, name-absence checks, private saved-plan apply and confidentiality. No workflow/job/status names or caller inputs change. Validation at 88ab4f4: the six-permutation regression fails against the old implementation and passes with the fix. All 37 identity/delivery/state/approval/confidentiality tests pass, including changed hint content, membership, duplicates, ordered input values, prior state and real plan changes. Native staged Gitleaks 8.30.1 and diff checks passed. All Terraform execution used existing mocked providers; no real local plan/apply, credentials or live APIs. Hosted checks remain required. After review/checks/merge, publish and promote one release to stable-v1, then start a fresh owning identity plan and review its new fingerprint before a separately approved apply. Fingerprints from runs 70/71 must not be reused across this fingerprint-contract change. No workflow retry is dispatched by this PR.
Stabilize Terraform plan fingerprints across UI hint ordering
All checks were successful
Workflow acceptance / acceptance (pull_request) Successful in 1m40s
Repository security / security-1 (pull_request) Successful in 6m55s
Library checks / tests (pull_request) Successful in 8m3s
88ab4f44b2
portegumi approved these changes 2026-10-15 21:49:47 -05:00
portegumi left a comment

Source review at 88ab4f44b2: approved. plan_summary normalizes only the top-level relevant_attributes outer list using a canonical JSON sort key; it retains each hint, duplicates, nested attribute-path order, and the rest of the plan in the hash. The approval guard still binds the source SHA and fresh plan fingerprint before applying the private saved plan; resource/action and identity creation guards remain unchanged. Inspected regression tests for all six hint permutations, changed hint contents/membership/duplicates, ordered input values, changed prior state/resource changes, and apply mismatch. HashiCorp's pinned Terraform 1.16.5 source describes these as UI-only hints and states their order is unimportant, supporting this narrowly scoped normalization. This PR does not alter UDS deployment packaging, policy/admission, or routing ownership. Hosted Workflow acceptance, Repository security, and Library checks were pending at review time; I did not independently run tests or a live plan/apply. Approval is source-only and does not satisfy required CI or authorize a merge. After release/promotion, obtain a new owning plan and fresh approval fingerprint; do not reuse pre-change fingerprints.

CI at submission: pending. This is a source-review approval, not a scan verdict; required checks still block merge.

Source review at 88ab4f44b2971526c06cd5e0c4bc2f621153c5e9: approved. `plan_summary` normalizes only the top-level `relevant_attributes` outer list using a canonical JSON sort key; it retains each hint, duplicates, nested attribute-path order, and the rest of the plan in the hash. The approval guard still binds the source SHA and fresh plan fingerprint before applying the private saved plan; resource/action and identity creation guards remain unchanged. Inspected regression tests for all six hint permutations, changed hint contents/membership/duplicates, ordered input values, changed prior state/resource changes, and apply mismatch. HashiCorp's pinned Terraform 1.16.5 source describes these as UI-only hints and states their order is unimportant, supporting this narrowly scoped normalization. This PR does not alter UDS deployment packaging, policy/admission, or routing ownership. Hosted Workflow acceptance, Repository security, and Library checks were pending at review time; I did not independently run tests or a live plan/apply. Approval is source-only and does not satisfy required CI or authorize a merge. After release/promotion, obtain a new owning plan and fresh approval fingerprint; do not reuse pre-change fingerprints. CI at submission: pending. This is a source-review approval, not a scan verdict; required checks still block merge.
kiyi added this to the Homelab Roadmap project 2026-10-15 21:50:59 -05:00
gitchegumi deleted branch kiyi/terraform-plan-fingerprint 2026-10-15 21:59:01 -05:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Homelab/workflows!108
No description provided.