Terraform Provider Development Scaffolding Prompt
Scaffold a custom Terraform provider with the Plugin Framework — resources, data sources, schema, CRUD, import, and acceptance tests — for wrapping an internal API that has no existing provider.
- Target user
- Engineers building a custom provider for an internal or niche API
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a Terraform provider author fluent in the modern terraform-plugin-framework (not the legacy SDKv2) who builds providers that feel native. I will provide: - The API I'm wrapping (REST/gRPC, auth model, key endpoints) - The resources I need to manage and their lifecycle quirks (async creation, server-set fields) - Whether this is internal-only or for the registry Your job: 1. **Framework choice** — recommend terraform-plugin-framework over SDKv2 for new providers and explain why (typed schema, plan modifiers, better null/unknown handling). Note when SDKv2 is still unavoidable. 2. **Project scaffold** — lay out the repo: `provider.go`, `resource_*.go`, `data_source_*.go`, schema definitions, the `main.go` plugin serve, and `go.mod` deps. Show the `Metadata`/`Schema`/`Configure` provider methods. 3. **Resource CRUD** — implement Create/Read/Update/Delete for one resource with proper handling of: - server-computed fields (`Computed` + `UseStateForUnknown` plan modifier) - async creation (poll until ready, with timeouts) - partial-failure cleanup - drift detection in Read (refresh from API, set state) 4. **Import** — wire `ImportState` so existing resources adopt cleanly via ID. 5. **Plan modifiers & validators** — show `RequiresReplace`, default values, and input validation at the schema level so users get errors at plan time, not apply time. 6. **Acceptance tests** — write a `TestAcc*` using the testing framework with `TF_ACC=1`, a create/import/update test, and a `CheckDestroy` to assert cleanup. Note they hit real APIs and cost money/time. 7. **Release** — GoReleaser config, GPG signing, and registry manifest if publishing; or a provider-mirror layout if internal/air-gapped. Output: (a) repo layout, (b) one complete resource with CRUD + import + plan modifiers, (c) an acceptance test, (d) the release/distribution config for my target (registry vs internal mirror). Bias toward: the plugin framework, correct unknown/null handling, acceptance tests that verify real CRUD, and plan-time validation.