-
Notifications
You must be signed in to change notification settings - Fork 96
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
Utility to call Read()
from the end of Create()
/Update()
#277
Comments
Read()
from Create()
/Update()
Read()
from the end of Create()
/Update()
Hi @magodo 👋 Thank you for raising this feature request and apologies it took so long to respond! It certainly follows some of the conventional details of how some providers worked with terraform-plugin-sdk resource implementations, where they would call the read functions at the end of their create or update functions since they matched in function signatures. While the framework could theoretically provide some functionality to allow provider developers to easily cross these logical boundaries, there are actually some specific reasons not to do so:
// Contrived example of using Go functions to share resource reading logic.
// This example, however, is not a recommended practice.
type exampleResourceData struct {/*...*/}
func readExample(ctx context.Context, client examplesdk.Client, id string) (exampleResourceData, diag.Diagnostics) {/*...*/}
func (r exampleResource) Create(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
// logic to create resource and get id string
data, diags := readExample(ctx, r.provider.client, id)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
if data == nil {
// this should return an error or retry the read call,
// rather than calling resp.State.RemoveResource()
}
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
}
func (r exampleResource) Read(ctx context.Context, req tfsdk.CreateResourceRequest, resp *tfsdk.CreateResourceResponse) {
var id string
diags := req.State.GetAttribute(ctx, path.Root("id") &id)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
data, diags := readExample(ctx, r.provider.client, id)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
if data == nil {
resp.State.RemoveResource()
return
}
resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
} Some additional details about proper resource disappearance handling between Create/Read/Update/Delete are captured in this Discuss post, which hopefully will make its way into the terraform.io documentation at some point. Therefore given the above, I think we would be very hesitant to introduce anything in this space. Thanks again for suggesting it though and reach out if you have any further questions about this. |
As an aside from writing the above response, if there is not already a feature request issue for having the framework return a very specific "oh no you called RemoveResource() when you shouldn't have" error diagnostic after the Create and Update methods, I'll add one and cross-reference this issue and the discuss post. |
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. |
Module version
Use-cases
In plugin SDK, it is prevalent to call
Read()
at the end ofCreate()
/Update()
in the resource implementation. This is avoid code duplication for APIs that doesn't return the full model in its "create" response.I'd like to continue this pattern in the framework.
Attempted Solutions
I manually convert to and from the
tfsdk.ReadResource{Request|Response}
, as below:Full example can be found here: https://github.com/magodo/terraform-provider-demo/blob/41121592396989284faad906d3943fcd084b4272/demo/resource_foo.go#L124-L137
Proposal
Apparently, above solution is not ideal. Propose there can be some builtin utilities to allow users to do that.
The text was updated successfully, but these errors were encountered: