Resources
Resources are an abstraction that allow Terraform to manage infrastructure objects, such as a compute instance, an access policy, or disk. Terraform assumes that every resource:
- operates as a pure key/value store, with values getting returned exactly as they were written.
- needs only one API call to update or return its state.
- can be be created, read, updated, and deleted.
This page describes the initial implementation details required for supporting a resource within the provider. Resource lifecycle management functionality is also required:
- Create resources by receiving Terraform configuration and plan data, performing creation logic, and saving Terraform state data.
- Read resources by receiving Terraform prior state data, performing read logic, and saving refreshed Terraform state data.
- Update resources in-place by receiving Terraform prior state, configuration, and plan data, performing update logic, and saving updated Terraform state data.
- Delete resources by receiving Terraform prior state data and performing deletion logic.
Further documentation is available for deeper resource concepts:
- Configure resources with provider-level data types or clients.
- Default for specifying a default value for an attribute that is null within the configuration.
- Import state so practitioners can bring existing resources under Terraform lifecycle management.
- Manage private state to store additional data in resource state that is not shown in plans.
- Modify plans to enrich the output for expected resource behaviors during changes, or marking a resource for replacement if an in-place update cannot occur.
- Upgrade state to transparently update state data outside plans.
- Validate practitioner configuration against acceptable values.
- Timeouts in practitioner configuration for use in resource create, read, update and delete functions.
Define Resource Type
Implement the resource.Resource
interface. Ensure the Add Resource To Provider documentation is followed so the resource becomes part of the provider implementation, and therefore available to practitioners.
Metadata Method
The resource.Resource
interface Metadata
method defines the resource name as it would appear in Terraform configurations. This name should include the provider type prefix, an underscore, then the resource specific name. For example, a provider named examplecloud
and a resource that reads "thing" resources would be named examplecloud_thing
.
In this example, the resource name in an examplecloud
provider that reads "thing" resources is hardcoded to examplecloud_thing
:
// With the resource.Resource implementationfunc (r *ThingResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = "examplecloud_thing"}
To simplify resource implementations, the provider.MetadataResponse.TypeName
field from the provider.Provider
interface Metadata
method can set the provider name so it is available in the resource.MetadataRequest.ProviderTypeName
field.
In this example, the provider defines the examplecloud
name for itself, and the data source is named examplecloud_thing
:
// With the provider.Provider implementationfunc (p *ExampleCloudProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) { resp.TypeName = "examplecloud"} // With the resource.Resource implementationfunc (d *ThingDataSource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_thing"}
Schema Method
The resource.Resource
interface Schema
method defines a schema describing what data is available in the resource's configuration, plan, and state.
Add Resource to Provider
Resources become available to practitioners when they are included in the provider implementation via the provider.Provider
interface Resources
method.
In this example, the ThingResource
type, which implements the resource.Resource
interface, is added to the provider implementation:
// With the provider.Provider implementationfunc (p *ExampleCloudProvider) Resources(_ context.Context) []func() resource.Resource { return []func() resource.Resource{ func() resource.Resource { return &ThingResource{}, }, }}
To simplify provider implementations, a named function can be created with the resource implementation.
In this example, the ThingResource
code includes an additional NewThingResource
function, which simplifies the provider implementation:
// With the provider.Provider implementationfunc (p *ExampleCloudProvider) Resources(_ context.Context) []func() resource.Resource { return []func() resource.Resource{ NewThingResource, }} // With the resource.Resource implementationfunc NewThingResource() resource.Resource { return &ThingResource{}}