
Provider Resources
Implement Terraform Plugin Framework resources and data sources with CRUD, schema design, state handling, and acceptance tests when building or extending a custom provider.
Install
npx skills add https://github.com/hashicorp/agent-skills --skill provider-resourcesWhat is this skill?
- Plugin Framework patterns for Create, Read, Update, Delete on managed resources
- Parallel guidance for data sources and schema design with state management
- Standard internal/service package layout with finder functions and acceptance tests
- Documentation paths under website/docs/r for registry-ready resource pages
- Pointers to HashiCorp official Plugin Framework and resource development docs
Adoption & trust: 1.7k installs on skills.sh; 654 GitHub stars; 3/3 security scanners passed (skills.sh audits); trending (+100% hot-view momentum).
Recommended Skills
Journey fit
Provider resource code is core backend/infrastructure product work you write before anyone can provision cloud APIs through Terraform. CRUD resources, finders, and acceptance tests live in internal service packages—the same backend engineering lane as APIs, but for IaC providers.
Common Questions / FAQ
Is Provider Resources safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - 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), }, "arn": { Type: schema.TypeString, Computed: true, }, "tags": tftags.TagsSchema(), "tags_all": tftags.TagsSchemaComputed(), }, CustomizeDiff: verify.SetTagsDiff, } } ``` ### Plugin Framework Resource Pattern ```go type resourceExample struct { framework.ResourceWithConfigure } func (r *resourceExample) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { resp.TypeName = req.ProviderTypeName + "_example" } func (r *resourceExample) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "id": framework.IDAttribute(), "name": schema.StringAttribute{ Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), }, Validators: []validator.String{ stringvalidator.LengthBetween(1, 255), }, }, "arn": schema.StringAttribute{ Computed: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.UseStateForUnknown(), }, }, }, } } ``` ## CRUD Operations ### Create Operation ```go func (r *resourceExample) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { var data resourceExampleModel resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) if resp.Diagnostics