terraform-plugin-sdk icon indicating copy to clipboard operation
terraform-plugin-sdk copied to clipboard

Persist existing ResourceDiff from plan during apply

Open skeggse opened this issue 3 years ago • 1 comments

SDK version

github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1

Use-cases

I'd like to make a provider that exposes a variant of the random_shuffle resource, except that it attempts to provide stability when the input field changes. I ran with https://github.com/hashicorp/terraform-provider-random/issues/121, and mostly got an approach that uses CustomizeDiff working. However, I'm finding that I have no way to use the value created during the plan phase - this results in Terraform complaining about an inconsistent final plan:

Error: Provider produced inconsistent final plan

When expanding the plan for stable_subset.res to include new values learned so
far during apply, provider "registry.terraform.io/hashicorp/stable" produced
an invalid new value for .result: planned set element cty.StringVal("b") does
not correlate with any element in actual.

This is a bug in the provider, which should be reported in the provider's own
issue tracker.


Error: Provider produced inconsistent final plan

When expanding the plan for stable_subset.res to include new values learned so
far during apply, provider "registry.terraform.io/hashicorp/stable" produced
an invalid new value for .result: planned set element cty.StringVal("d") does
not correlate with any element in actual.

This is a bug in the provider, which should be reported in the provider's own
issue tracker.

Attempted Solutions

I've looked through all the interfaces I can find in the various helper packages, and got as far as discovering the PlannedPrivate field in the provider messaging implementation before discovering that I couldn't seem use that mechanism from a provider implementation either.

I suspect this is getting complicated by the CreateContext not getting called when the CustomizeDiff hook invokes SetNew; I wouldn't expect this to be the case, but perhaps if I was able to do both it would be possible to work around the problem?

Work-in-progress implementation is here for anyone interested.

Proposal

Prepopulate (opt-in, perhaps?) the schema.ResourceDiff value passed to CustomizeDiff and the Create/Read/Update/Delete family of functions in a schema.Resource based on a previously-generated plan - atop addition to anything already in the state file.

Example:

  1. terraform plan -out tfplan generates a tfplan file that includes the resource-level changes Terraform anticipates
  2. terraform apply tfplan takes the existing tfplan file and passes its content to the provider
  3. the provider exposes the existing diff information in resource-level ResourceDiff objects, so that the provider can avoid duplicate work and maintain stability for random operations.

References

  • #133
  • https://github.com/hashicorp/terraform-provider-random/issues/121

skeggse avatar May 07 '21 09:05 skeggse

Oh, I suppose this isn't strictly necessary for my intended use-case, though it is still really nice to have: we can deterministically derive the result based on a seeded random, and this should produce the same value in plan as during apply.

skeggse avatar Jul 08 '22 19:07 skeggse