From terraform-migration
This skill should be used when migrating Terraform provider data sources or resources from hashicorp/terraform-plugin-sdk/v2 to hashicorp/terraform-plugin-framework. Trigger phrases include "migrate to plugin framework", "SDK v2 to plugin framework", "convert to plugin framework", "migrate data source", "migrate resource", "plugin framework migration", "move to framework", or "upgrade from SDK v2". Provides step-by-step migration workflow, code patterns, schema mapping, and common gotchas.
npx claudepluginhub burythehammer/claude-code-plugins --plugin terraform-migrationThis skill uses the workspace's default tool permissions.
Migrate Terraform provider data sources and resources from `terraform-plugin-sdk/v2` to
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Migrate Terraform provider data sources and resources from terraform-plugin-sdk/v2 to
terraform-plugin-framework, following patterns established by completed migrations in the
target codebase.
Before writing any code, understand how the target provider is structured. This determines whether you follow existing conventions or fall back to the templates in references/.
terraform-plugin-framework to locate already-migrated data sources and resources. Note their file structure, naming conventions, and patterns.DataSources() and Resources() are returned from the framework provider, and where DataSourcesMap/ResourcesMap are defined in the SDK provider.tfplugindocs, custom generators). Look for go:generate directives, Makefile targets, or tools/ directories.protoV5ProviderFactories or equivalent. Note the test package conventions and any shared test helpers.tf5muxserver or tf6muxserver usage. This determines whether the protocol v5 block constraint applies (see references/gotchas.md #1).TypeSet/TypeList with Elem: &schema.Resource{})ForceNew, DiffSuppressFunc, or DefaultFunc usageIf Phase 0 found existing framework code: match those conventions exactly (directory layout, file naming, import organisation).
Otherwise, use the 3-file pattern as a fallback:
Data sources:
internal/<package>/
├── datasource_<name>.go # Schema, interfaces, Metadata, Configure
├── datasource_<name>_model.go # Model struct with tfsdk tags
├── datasource_<name>_read.go # Read implementation + helpers
└── helpers.go # Shared utilities (if needed)
Resources:
internal/<package>/
├── resource_<name>.go # Schema, interfaces, Metadata, Configure
├── resource_<name>_model.go # Model struct(s) with tfsdk tags
├── resource_<name>_crud.go # Create, Read, Update, Delete implementations
└── helpers.go # Shared utilities (if needed)
Create the model struct:
id is always types.String — even if SDK v2 used TypeInt (see references/gotchas.md #5)types.String, types.Bool, types.Int64, types.Float64 for scalarstypes.Set, types.List, types.Map for collectionstfsdk:"field_name" tag matching the schema attribute nameConsult references/schema-mapping.md for the full type mapping table.
Create the schema definition with: interface checks, struct, constructor, Metadata, Configure, and Schema methods.
Key rules:
tf5muxserver, SDK v2 TypeSet/TypeList with Elem: &schema.Resource{} MUST become blocks, not attributes. See references/gotchas.md #1.MaxItems: 1 nested objects become SingleNestedBlock. See references/gotchas.md #6.id — declare as schema.StringAttribute{Computed: true}. See references/gotchas.md #5.ForceNew becomes planmodifier.RequiresReplace().DefaultFunc becomes Default (e.g., stringdefault.StaticString("value")).DiffSuppressFunc becomes a custom planmodifier.CustomizeDiff becomes ModifyPlan (implement ResourceWithModifyPlan).For code templates, see references/data-source-template.md or references/resource-template.md.
Implement the operations following these patterns:
references/gotchas.md #4.req.Config.Get(ctx, &state) (data sources) or req.Plan.Get(ctx, &plan) (resources).references/gotchas.md #2.types.ObjectValueFrom with model structs. See references/gotchas.md #3.resp.State.Set(ctx, &state).Three changes required:
DataSources() or Resources() return slice.DataSourcesMap or ResourcesMap.Use the registration files identified in Phase 0. Look for how existing framework data sources/resources are registered.
Run the build and fix errors in a loop:
go build ./...go build ./... againgo vet ./... to catch additional issuesCommon build errors during migration:
Leverage the test infrastructure discovered in Phase 0:
protoV5ProviderFactories setuptestAccPreCheck patterngo test ./internal/<package>/... -v 2>&1 | tee test-output.log
Update the corresponding docs/data-sources/ or docs/resources/ markdown file if the schema changed (e.g., id type change from int to string).
| Need | File |
|---|---|
| Type mapping (SDK v2 → Framework) | references/schema-mapping.md |
| Common failure modes | references/gotchas.md |
| Data source code template | references/data-source-template.md |
| Resource code template | references/resource-template.md |