Terraform
- Plugin Framework
- v1.18.x (latest)
- v1.17.x
- v1.15.x
- No versions of this document exist before v1.15.x. Click below to redirect to the version homepage.
- v1.14.x
- v1.13.x
- v1.12.x
- v1.11.x
- v1.10.x
- v1.9.x
- v1.8.x
- v1.7.x
- v1.6.x
- v1.5.x
- v1.4.x
- v1.3.x
- v1.2.x
- v1.1.x
- v1.0.x
- v0.17.x
- v0.16.x
- v0.15.x
- v0.14.x
- v0.13.x
- v0.12.x
- v0.11.x
- v0.10.x
- v0.9.x
- v0.8.x
- v0.7.x
Listing resources
List is called when a terraform query is executed, the ListResource RPC is called which in turn calls the list.ListResource interface List method. The request contains the configuration supplied to Terraform by the list block and the response contains a stream of the list results.
The list.ListRequest type also includes the IncludeResource field. Terraform can set this field when the practitioner enables the include_resource argument in HCL or when the query is run with the -generate-config-out flag. Check this field early in the List method so the provider can avoid unnecessary requests or response processing when Terraform only needs resource identity data.
Define List Method
Implement the List method by:
- Accessing the
Configdata from thelist.ListRequesttype. - Performing external calls and logic for the list operation.
- For each list result instantiate a new result object using the
list.ListRequest.NewListResultmethod. - Checking
list.ListRequest.IncludeResourceearly and using it to decide whether full resource data should be fetched and whetherlist.ListResult.Resourceshould be populated. - Return an iterator function that pushes list results into the response stream.
If the logic needs to return warning or error diagnostics, they can be added into the list.ListResult.Diagnostics field of an empty list result and pushed into the stream.
In this example, the list method on the resource examplecloud_thing is defined:
// ThingListResource defines the list implementation.
// Some list.ListResource interface methods are omitted for brevity.
type ThingListResource struct{}
type ThingListResourceModel struct {
ResourceGroupName types.String `tfsdk:"resource_group_name"`
}
func (r *ThingListResource) ListResourceConfigSchema(_ context.Context, _ list.ListResourceConfigSchemaRequest, resp *list.ListResourceConfigSchemaResponse) {
resp.Schema = listschema.Schema{
Attributes: map[string]listschema.Attribute{
"resource_group_name": listschema.StringAttribute{
Description: "Name of the resource group to list things in.",
Required: true,
},
},
}
}
func (r *ThingListResource) List(ctx context.Context, req list.ListRequest, stream *list.ListResultsStream) {
var data ThingListResourceModel
// Read list config data into the model
diags := req.Config.Get(ctx, &data)...
if diags.HasError() {
stream.Results = list.ListResultsStreamDiagnostics(diags)
return
}
// Typically lists will make external calls here using data from the config
// as input. For brevity, we assume the `things` slice below was returned by an
// API call here
// Check IncludeResource before making remote requests so the provider can
// avoid unnecessary work when Terraform only needs identity data.
var things []Thing
if req.IncludeResource {
// Fetch full resource data because Terraform requested it.
things = client.ListThingsWithResourceData(ctx, data.ResourceGroupName.ValueString())
} else {
// Fetch only the data needed to populate identities and display names.
things = client.ListThings(ctx, data.ResourceGroupName.ValueString())
}
// Define the function that will push results into the stream
stream.Results = func(push func(list.ListResult) bool) {
for _, thing := range things {
// Initialize a new result object for each thing
result := req.NewListResult(ctx)
// Set the user-friendly name of this thing
result.DisplayName = thing.Name
// Set resource identity data on the result
result.Diagnostics.Append(result.Identity.Set(ctx, thing.ID))
// Only set full resource data when Terraform requested it.
if req.IncludeResource {
result.Diagnostics.Append(result.Resource.Set(ctx, thing.Resource))
}
// Send the result to the stream.
if !push(result) {
return
}
}
}
Caveats
- An error is returned if a list result in the stream contains a null identity unless it contains a warning in the diagnostics.
- An error is returned if
req.IncludeResourceistrue, for example the practitioner setinclude_resource = trueor Terraform is using-generate-config-out, and a list result in the stream has a null resource.