Hi team.
In case a resource managed from terraform is deleted manually (external to terraform), I want the apply operation to recreate the resource. One thing I thought of doing is to set the ID to nil, and in the update function call create in case the ID is nil. The question is if there is a more familiar way to implement this functionality?
Another thing to mention - I’m using terraform-plugin-framework to write the provider.
Hi @OrNovo,
During the planning phase Terraform asks the provider to perform two separate operations:
- Refreshing (“Read” in the framework API) should check for any changes made outside of Terraform and return an updated object representing the current state of the remote object. This is where Terraform detects a change made outside of Terraform.
- Planning (either built-in behavior or “plan modifiers” in the framework) should compare the desired state (“config”) with the prior state and return a planned new object describing how to reconcile those two inputs. This is where Terraform responds to any changes detected in the refresh step, because the prior state is the result from refreshing.
Since you are specifically worried about the case where the object is deleted outside of Terraform, the way to handle that is for the Read operation to return a null object if it finds that the object is missing, because null is how Terraform represents “does not exist”. The entire object must be null to represent not existing; setting just the id to null isn’t sufficient because Terraform Core doesn’t treat the “id” attribute in any special way here.
If you make your Read behave in that way then the built-in behavior of the plugin framework should handle the planning step for you: it will notice that the prior state is null but the desired state isn’t, and so will return something derived from the desired state as the planned new state, and Terraform Core will record that as a “create” action, which you can then handle during the apply phase as normal.
(The old SDKv2 did handle this by setting the id to the empty string, but that was a convention implemented inside the SDK itself, making the SDK return a null object to Terraform Core. The framework models the Terraform provider protocol more directly, so it doesn’t have this same special case.)
Hi @apparentlymart!
Thanks for answering.
I tried two things -
resp.State.Set(ctx, nil)
resp.State.RemoveResource(ctx)
The first approach didn’t work, not sure why, but the second one worked as accepted.
#2 would be the recommended method for removing that resource. If you tried #1 I would’ve expected an error to be returned explaining to use State.RemoveResource
: terraform-plugin-framework/tfsdk/state.go at f200629c5c701ec34f246bc5200afb59b3842b40 · hashicorp/terraform-plugin-framework · GitHub