Repository navigation
feat(e2e): heal corrupted leaked_credential_check_rule state; clean up create-only resources - #331
Open
vaishakdinesh wants to merge 1 commit into
Open
vaishakdinesh wants to merge 1 commit into
vaishakdinesh wants to merge 1 commit into
Conversation
…p create-only resources
Two related e2e harness robustness fixes, both live-tested against v5.19.0
(all 5 steps passed, 0 unmatched drift):
1. healCorruptedLeakedCredentialCheckRuleState: detects and repairs a known
v4 provider bug where cloudflare_leaked_credential_check_rule's Read()
silently zeroes id/username/password to null instead of erroring when
the tracked resource no longer matches reality (e.g. deleted outside
Terraform), permanently breaking every subsequent Update() with
"required missing detection ID". Runs after v4 init, before v4 plan;
no-op if the resource is healthy or not in state. The identical bug
exists in content_scanning_expression's Read() too, but that resource
has no tf-migrate migrator/testdata so it's out of scope here.
2. cleanupCreateOnlyResources (Step 5): after a fully successful run,
parses the already-captured v5 plan text for resources with a pure
"will be created" action (no moved {} or import {} block protecting
them) and destroys exactly those, leaving the real v4 base and every
adopted v5 resource untouched. Insurance against resources with no v4
counterpart silently accumulating duplicates across repeated runs,
since v5-side state is never persisted between invocations. Opt out
with --keep-created. Deliberately parses plan TEXT rather than
`terraform show -json <planfile>`: the JSON form always marshals the
full prior state, so one unrelated resource elsewhere in state with a
stale schema makes the whole call fail even though the actual -target
plan succeeded. Confirmed working live: destroyed 7 genuinely
create-only resources (zone/account singletons and conditional
zone_setting instances) while correctly leaving leaked_credential_check_rule
and all moved/import-protected resources untouched.
Both include unit tests for their safety-critical pure logic (text
parsing, import-block protection, state corruption detection).
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.
Summary
Two related e2e harness robustness fixes, both live-tested end-to-end against v5.19.0 (all 5 steps passed, 0 unmatched drift).
1. Heal corrupted
leaked_credential_check_rulestateRoot cause (confirmed directly in the v4 provider source,
internal/framework/service/leaked_credential_check_rule/resource.go):Read()lists all detection patterns and loops looking for one matching state'sid. If none match (e.g. because the real pattern was deleted outside Terraform), it does not error — it silently writes a zero-value result back to state, leavingid/username/passwordallnull. Every subsequentUpdate()then fails with"required missing detection ID", and the resource can never recover on its own.This surfaced in the supportability-matrix CI workflow after a manually-deleted duplicate detection pattern left the real, shared v4 state corrupted — every run from that point on failed at the v4-apply step.
The identical anti-pattern exists in
content_scanning_expression'sRead()too (same "doesn't offer a single get operation" comment, same no-match handling), but that resource has no tf-migrate migrator/testdata, so it's out of scope here.Fix:
healCorruptedLeakedCredentialCheckRuleStateruns after v4 init, before v4 plan. It checks this one resource's state for theid == nullcorruption signature and removes the entry if found, so the next plan/apply cleanly recreates it instead of repeatedly failing. No-op if the resource is healthy or not present in state.2. Clean up create-only resources (Step 5)
Problem: v5-side Terraform state is never persisted between runs by design (see
e2e/SUPPORTABILITY_MATRIX.md§11) — resources adopted via amoved {}block are always safely re-associated with their real ID regardless, but resources with no v4 counterpart at all have no such anchor. Every run creates them fresh, and since nothing records that creation, the next run has no way to know they already exist. Left unchecked, this silently accumulates duplicates until some account-level quota is exhausted (the mechanism behind a prior Access Policy / Gateway Certificate quota incident, documented in the matrix doc).Fix: after a fully successful run,
cleanupCreateOnlyResourcesparses the already-captured v5 plan text for resources with a pure"will be created"action, excludes anything protected by amoved {}orimport {}block, andterraform destroys exactly what's left. Opt out with--keep-created.Deliberately parses plan text rather than
terraform show -json <planfile>: the JSON form always marshals the entire prior state, so a single unrelated resource elsewhere in state with a stale/incompatible schema makes the whole call fail outright — even though the actual-target-scoped plan/apply succeeded cleanly. Text parsing has no such problem.Confirmed live: destroyed 7 genuinely create-only resources (zone/account-level singletons and conditionally-created
zone_settinginstances) while correctly leavingleaked_credential_check_ruleand all moved/import-protected resources untouched.Testing
go build ./...,go vet ./...— cleango test ./...— all pass, including new unit tests covering the safety-critical pure logic (plan-text parsing, import-block protection, state-corruption detection)