Implement Terraform Provider resources and data sources using the Plugin Framework. Use when developing CRUD operations, schema design, state management, and acceptance testing for provider resources.
View on GitHubhashicorp/agent-skills
terraform-provider-development
February 1, 2026
Select agents to install to:
npx add-skill https://github.com/hashicorp/agent-skills/blob/main/terraform/provider-development/skills/provider-resources/SKILL.md -a claude-code --skill provider-resourcesInstallation paths:
.claude/skills/provider-resources/# Terraform Provider Resources Implementation Guide
## Overview
This guide covers developing Terraform Provider resources and data sources using the Terraform Plugin Framework. Resources represent infrastructure objects that Terraform manages through Create, Read, Update, and Delete (CRUD) operations.
**References:**
- [Terraform Plugin Framework](https://developer.hashicorp.com/terraform/plugin/framework)
- [Resource Development](https://developer.hashicorp.com/terraform/plugin/framework/resources)
- [Data Source Development](https://developer.hashicorp.com/terraform/plugin/framework/data-sources)
## File Structure
Resources follow the standard service package structure:
```
internal/service/<service>/
├── <resource_name>.go # Resource implementation
├── <resource_name>_test.go # Acceptance tests
├── <resource_name>_data_source.go # Data source (if applicable)
├── find.go # Finder functions
├── exports_test.go # Test exports
└── service_package_gen.go # Auto-generated registration
```
Documentation structure:
```
website/docs/r/
└── <service>_<resource_name>.html.markdown # Resource documentation
website/docs/d/
└── <service>_<resource_name>.html.markdown # Data source documentation
```
## Resource Structure
### SDKv2 Resource Pattern
```go
func ResourceExample() *schema.Resource {
return &schema.Resource{
CreateWithoutTimeout: resourceExampleCreate,
ReadWithoutTimeout: resourceExampleRead,
UpdateWithoutTimeout: resourceExampleUpdate,
DeleteWithoutTimeout: resourceExampleDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 255),