I want to create a terraform provider.
I'm implementing a resource that doesn't offer an update API route, so the update must result as a delete and a create.
I'm using terraform-plugin-framework, and I need to implement the update function for the given resource.
I can't find a way to make the provider understand that the update operation generates a delete and then a create, in an explicit way in the logs when the resource is used.
Has anyone ever had this problem or knows how to solve it?
Regards
The behavior of replacing an object (deleting the existing object and creating a new one, in either order) is activated by provider logic, but is actually implemented by Terraform Core on the provider's behalf.
To activate that behavior you will need to use Plan Modification, because a provider activates this behavior as part of its response to Terraform Core's request for planning.
If the argument is a string value and the rule for replacement is that any change for a particular argument (regardless of before and after value, as long as they are not equal) requires replacement then you can use the predefined
stringplanmodifier.RequiresReplacemodifier implementation. For example:Sometimes the rule is more subtle, where replacement is required only if the value has changed in a specific way. In that case, there's the more flexible
stringplanmodifier.RequiresReplaceIf, which includes a callback function to specify a custom rule for whether a particular change requires replacement.Attributes of other types have different details -- the framework's schema model is strongly-typed and so uses different modifier implementations for each attribute type -- but the principle is the same regardless of type.
Internally these plan modifiers make changes to the
RequiresReplacefield ofresource.ModifyPlanResponse, which is the plugin framework's model of the response to Terraform Core's request for the provider to create a plan.If the remote API cannot support updating at all -- so therefore any change to any argument requires replacement -- you could instead write a whole-resource plan modifier, which then gives you direct access to the aforementioned
resource.ModifyPlanResponseobject and to the entire resource prior state and configuration so that you can write just one rule for the entire resource type, rather than having to write an individual rule for each attribute.Regardless of how you achieve it, the end result should be that at least one attribute is indicated in the "requires replace" field of the provider's planning response, in which case Terraform Core will:
Then during the apply phase, Terraform Core will:
create_before_destroysetting.