---
page_title: 'Plugin Development - Framework: Resources'
description: >-
  How to build resources in the provider development framework. Resources allow
  Terraform to manage infrastructure objects.
---

# Resources

[Resources](/terraform/language/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](/terraform/plugin/framework/resources/create) resources by receiving Terraform configuration and plan data, performing creation logic, and saving Terraform state data.
- [Read](/terraform/plugin/framework/resources/read) resources by receiving Terraform prior state data, performing read logic, and saving refreshed Terraform state data.
- [Update](/terraform/plugin/framework/resources/update) resources in-place by receiving Terraform prior state, configuration, and plan data, performing update logic, and saving updated Terraform state data.
- [Delete](/terraform/plugin/framework/resources/delete) resources by receiving Terraform prior state data and performing deletion logic.

Further documentation is available for deeper resource concepts:

- [Configure](/terraform/plugin/framework/resources/configure) resources with provider-level data types or clients.
- [Default](/terraform/plugin/framework/resources/default) for specifying a default value for an attribute that is null within the configuration.
- [Import state](/terraform/plugin/framework/resources/import) so practitioners can bring existing resources under Terraform lifecycle management.
- [Manage private state](/terraform/plugin/framework/resources/private-state) to store additional data in resource state that is not shown in plans.
- [Modify plans](/terraform/plugin/framework/resources/plan-modification) 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](/terraform/plugin/framework/resources/state-upgrade) to transparently update state data outside plans.
- [Validate](/terraform/plugin/framework/resources/validate-configuration) practitioner configuration against acceptable values.
- [Timeouts](/terraform/plugin/framework/resources/timeouts) in practitioner configuration for use in resource create, read, update and delete functions.

## Define Resource Type

Implement the [`resource.Resource` interface](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource). Ensure the [Add Resource To Provider](#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](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource.Metadata) 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`:

```go
// With the resource.Resource implementation
func (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](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#MetadataResponse.TypeName) from the [`provider.Provider` interface `Metadata` method](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#Provider.Metadata) can set the provider name so it is available in the [`resource.MetadataRequest.ProviderTypeName` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#MetadataRequest.ProviderTypeName).

In this example, the provider defines the `examplecloud` name for itself, and the data source is named `examplecloud_thing`:

```go
// With the provider.Provider implementation
func (p *ExampleCloudProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
	resp.TypeName = "examplecloud"
}

// With the resource.Resource implementation
func (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](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/resource#Resource.Schema) defines a [schema](/terraform/plugin/framework/schemas) 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](/terraform/plugin/framework/providers) implementation via the [`provider.Provider` interface `Resources` method](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/provider#Provider.Resources).

In this example, the `ThingResource` type, which implements the `resource.Resource` interface, is added to the provider implementation:

```go
// With the provider.Provider implementation
func (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:

```go
// With the provider.Provider implementation
func (p *ExampleCloudProvider) Resources(_ context.Context) []func() resource.Resource {
	return []func() resource.Resource{
		NewThingResource,
	}
}

// With the resource.Resource implementation
func NewThingResource() resource.Resource {
	return &ThingResource{}
}
```
