Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support upgrading resource state #42

Closed
paddycarver opened this issue Jun 4, 2021 · 1 comment · Fixed by #292
Closed

Support upgrading resource state #42

paddycarver opened this issue Jun 4, 2021 · 1 comment · Fixed by #292
Assignees
Labels
enhancement New feature or request sdkv2-parity Issues tracking feature parity with terraform-plugin-sdk v2 and PRs working towards it.
Milestone

Comments

@paddycarver
Copy link
Contributor

Module version

N/A

Use-cases

Sometimes resource schemas change over time and need massaging to be converted to the new format. This isn't usually needed; a refresh should update everything nicely. But if some values can't be populated by refresh, or refresh can't run without some values, and those values need to be migrate to a new data type or format, then provider-assisted state upgrades are necessary.

We should offer an optional method on resource types to support this callback.

Attempted Solutions

N/A

Proposal

Add an optional method on the Resource interface that lets providers modify the state when Terraform calls UpgradeResourceState.

@paddycarver paddycarver added the enhancement New feature or request label Jun 4, 2021
@paddycarver paddycarver added this to the v0.2.0 milestone Jun 4, 2021
@paddycarver paddycarver removed this from the v0.3.0 milestone Aug 30, 2021
@paddycarver paddycarver added the sdkv2-parity Issues tracking feature parity with terraform-plugin-sdk v2 and PRs working towards it. label Sep 9, 2021
@bflad bflad self-assigned this Nov 29, 2021
bflad added a commit that referenced this issue Nov 29, 2021
@bflad bflad added this to the v0.6.0 milestone Jan 11, 2022
bflad added a commit that referenced this issue Feb 17, 2022
…pgradeResourceState RPC

Reference: #42
Reference: #262
Reference: hashicorp/terraform-provider-corner#44

Terraform CLI version 0.12 through 0.14 support protocol version 5 and require the `UpgradeResourceStateResponse` type `UpgradedState` type `Msgpack` field. To support downgraded framework providers via terraform-plugin-mux `tf6to5server`, the `RawState` type `JSON` field cannot simply be passed through like the previous implementation. This change will parse the `RawState` and output it via the `tfprotov6.NewDynamicValue()` function, which will always set the `Msgpack` field.

Similar logic would have already been required as part of the larger effort to support resource versioning and upgrading resource state over time.

Passthrough of the same state of an invalid resource type should not have been previously allowed, since the provider did not implement the resource type. Regardless, Terraform CLI should not have reached this point since `GetProviderSchema` would not have returned the resource type anyways for other resource operations.

Verified via integration testing of terraform-plugin-mux `tf6to5server`, which previously returned a non-descript `EOF` error.
bflad added a commit that referenced this issue Feb 22, 2022
…pgradeResourceState RPC (#263)

Reference: #42
Reference: #262
Reference: hashicorp/terraform-provider-corner#44

Terraform CLI version 0.12 through 0.14 support protocol version 5 and require the `UpgradeResourceStateResponse` type `UpgradedState` type `Msgpack` field. To support downgraded framework providers via terraform-plugin-mux `tf6to5server`, the `RawState` type `JSON` field cannot simply be passed through like the previous implementation. This change will parse the `RawState` and output it via the `tfprotov6.NewDynamicValue()` function, which will always set the `Msgpack` field.

Similar logic would have already been required as part of the larger effort to support resource versioning and upgrading resource state over time.

Passthrough of the same state of an invalid resource type should not have been previously allowed, since the provider did not implement the resource type. Regardless, Terraform CLI should not have reached this point since `GetProviderSchema` would not have returned the resource type anyways for other resource operations.

Verified via integration testing of terraform-plugin-mux `tf6to5server`, which previously returned a non-descript `EOF` error.
@bflad bflad modified the milestones: v0.6.0, v0.7.0 Mar 10, 2022
bflad added a commit that referenced this issue Apr 13, 2022
bflad added a commit that referenced this issue Apr 18, 2022
Reference: #42
Reference: #228

Support provider defined `UpgradeResourceState` RPC handling, by introducing an optional `ResourceWithUpgradeState` interface type, with an `UpgradeState` method. Each underlying state version upgrade implementation is expected to consume the prior state, perform any necessary data manipulations, then respond with the upgraded state.

This framework implementation differs from the terraform-plugin-sdk implementation:

- State upgraders are specified via a mapping, rather than a slice with underlying version field. This should prevent certain classes of coding issues.
- State upgraders must be wholly contained from the prior state version to the current schema version. The framework does not loop through each successive version because attempting to recreate the `tfprotov6.RawState` for each intermediate version request would be very problematic. For example, terraform-plugin-go does not implement functionality for marshalling a `RawState`. Provider developers can use their own coding techniques to reduce code duplications when multiple versions need the same logic.
- Specifying the full prior schema is now an optional implementation detail. Working with the lower level data types is more challenging, however this has been a repeated feature request.

There are some quirks and potential future enhancements to the framework `UpgradeResourceState` handling:

- Past and current versions Terraform CLI will call `UpgradeResourceState` even if the state version matches the current schema version. This implementation keeps the framework's prior logic to roundtrip the existing state into the upgraded state. It may be possible to stop this Terraform CLI behavior with protocol version 6, although the logic would need to remain for backwards compatibility.
- It may be possible to help provider developers simplify logic by attempting to automatically populate compatible parts of the upgraded state from the prior state. This can potentially be done at a later time.
bflad added a commit that referenced this issue Apr 19, 2022
Reference: #42
Reference: #228

Support provider defined `UpgradeResourceState` RPC handling, by introducing an optional `ResourceWithUpgradeState` interface type, with an `UpgradeState` method. Each underlying state version upgrade implementation is expected to consume the prior state, perform any necessary data manipulations, then respond with the upgraded state.

This framework implementation differs from the terraform-plugin-sdk implementation:

- State upgraders are specified via a mapping, rather than a slice with underlying version field. This should prevent certain classes of coding issues.
- State upgraders must be wholly contained from the prior state version to the current schema version. The framework does not loop through each successive version because attempting to recreate the `tfprotov6.RawState` for each intermediate version request would be very problematic. For example, terraform-plugin-go does not implement functionality for marshalling a `RawState`. Provider developers can use their own coding techniques to reduce code duplications when multiple versions need the same logic.
- Specifying the full prior schema is now an optional implementation detail. Working with the lower level data types is more challenging, however this has been a repeated feature request.

There are some quirks and potential future enhancements to the framework `UpgradeResourceState` handling:

- Past and current versions Terraform CLI will call `UpgradeResourceState` even if the state version matches the current schema version. This implementation keeps the framework's prior logic to roundtrip the existing state into the upgraded state. It may be possible to stop this Terraform CLI behavior with protocol version 6, although the logic would need to remain for backwards compatibility.
- It may be possible to help provider developers simplify logic by attempting to automatically populate compatible parts of the upgraded state from the prior state. This can potentially be done at a later time.
bflad added a commit that referenced this issue Apr 20, 2022
bflad added a commit to hashicorp/terraform-website that referenced this issue Apr 21, 2022
bflad added a commit that referenced this issue Apr 21, 2022
Reference: #42
Reference: #228

Support provider defined `UpgradeResourceState` RPC handling, by introducing an optional `ResourceWithUpgradeState` interface type, with an `UpgradeState` method. Each underlying state version upgrade implementation is expected to consume the prior state, perform any necessary data manipulations, then respond with the upgraded state.

This framework implementation differs from the terraform-plugin-sdk implementation:

- State upgraders are specified via a mapping, rather than a slice with underlying version field. This should prevent certain classes of coding issues.
- State upgraders must be wholly contained from the prior state version to the current schema version. The framework does not loop through each successive version because attempting to recreate the `tfprotov6.RawState` for each intermediate version request would be very problematic. For example, terraform-plugin-go does not implement functionality for marshalling a `RawState`. Provider developers can use their own coding techniques to reduce code duplications when multiple versions need the same logic.
- Specifying the full prior schema is now an optional implementation detail. Working with the lower level data types is more challenging, however this has been a repeated feature request.

There are some quirks and potential future enhancements to the framework `UpgradeResourceState` handling:

- Past and current versions Terraform CLI will call `UpgradeResourceState` even if the state version matches the current schema version. This implementation keeps the framework's prior logic to roundtrip the existing state into the upgraded state. It may be possible to stop this Terraform CLI behavior with protocol version 6, although the logic would need to remain for backwards compatibility.
- It may be possible to help provider developers simplify logic by attempting to automatically populate compatible parts of the upgraded state from the prior state. This can potentially be done at a later time.
thiskevinwang pushed a commit to hashicorp/terraform-docs-common that referenced this issue Apr 29, 2022
@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request sdkv2-parity Issues tracking feature parity with terraform-plugin-sdk v2 and PRs working towards it.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants