Tfpluginfw client re-merges spec.initProvider after Create, unlike tfpluginsdk
- Dominant language
- Go
- Stars
- 481
- Forks
- 131
- Avg merge
- 2d 1h
- Merged PRs (30d)
- 11
Description
### What happened?
`spec.initProvider` is documented to only seed values on a resource's initial Create, and to never be enforced afterwards. In the `tfpluginfw` external client, `GetMergedParameters` merges `initProvider` into the resource's config on every reconcile, gated only on the provider-wide Management Policies flag, not on whether the resource already exists.
So any field left unset in `forProvider` (specifically so it can be managed at runtime by the external system) has its `initProvider` value re-applied forever, discarding changes the external system has since set.
The other client `tfpluginsdk` already solves this correctly via `ignored_tfpluginsdk.go` (`filterInitExclusiveDiffs`/`getTerraformIgnoreChanges`), which only ignores those diffs once the resource exists, `tfpluginfw` has no equivalent.
It seems there was a note here to fix this https://github.com/crossplane/upjet/commit/4835bbe it has been since fixed for `tfpluginsdk` but not for `tfpluginfw`.
### How can we reproduce it?
1. Use any Plugin-Framework-based resource with an `Optional+Computed` list/set attribute (e.g. AWS `cognitoidp` `UserPoolClient.supportedIdentityProviders`).
2. Set that field only in `spec.initProvider` (e.g. `["COGNITO"]`), leave it unset in `spec.forProvider`.
3. Let the resource create successfully.
4. Add a value to that field directly in AWS (e.g. `aws cognito-idp update-user-pool-client ... --supported-identity-providers COGNITO MySSO`).
5. Wait for the next Crossplane reconcile.
6. Observe the field revert to the `initProvider` value (`["COGNITO"]`), confirmed via `UpdatedExternalResource` events and the external system's value resetting, even with `LateInitialize` excluded from `spec.managementPolicies`.
I do have something that could be a fix (powers of current AI and all) but I don't want to suggest this unless it is welcome.
Thank you!
Contributor guide
Research direction
Start by locating the tfpluginfw implementation of GetMergedParameters and compare its handling of initProvider with ignored_tfpluginsdk.go, especially filterInitExclusiveDiffs and getTerraformIgnoreChanges. Reproduce the Optional+Computed scenario described in the issue, then verify that an existing resource keeps externally added values instead of reapplying initProvider on reconciliation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100