Skip to content Documentation index for agents (llms.txt)
Glotto Beta
Get started

The generated Terraform provider

If your API creates things customers want to manage as infrastructure — projects, webhooks, API keys, environments — they will eventually want to declare them in Terraform rather than script them by hand. From the same Glotto IR as your SDKs, docs site and MCP server, Glotto generates a complete, publishable Terraform provider: a Go module built on terraform-plugin-framework, with a resource per resource in your API, data sources, Registry documentation, and an acceptance-test scaffold.

Enable it in glotto.yml:

targets:
  terraform: {}

glotto generate then writes the provider module under <out>/terraform/.

What gets emitted

A module you can go build, tag, and publish — not a scaffold to fill in:

Path What it is
go.mod the provider module, pinning terraform-plugin-framework
main.go the providerserver entrypoint
internal/provider/provider.go the provider wiring, an embedded HTTP client configured from provider config, and every resource, data source and ephemeral resource
internal/provider/*_test.go a TF_ACC-gated acceptance-test scaffold, one per managed resource, plus the shared harness
docs/ the Terraform Registry docs tree — index.md, resources/*.md, data-sources/*.md
terraform-registry-manifest.json, .goreleaser.yml what the Registry’s publishing flow expects

The Registry docs are emitted natively from the same schema derivation as the provider code, so they cannot drift from the schema they document — and no tfplugindocs or terraform binary is needed to produce them.

Resources and data sources

Each resource in your API becomes a managed resource type, named from the provider’s type prefix and the resource’s path — glotto_webhook, and glotto_project_environment for a subresource. Its CRUD operations map to Terraform’s lifecycle from the operations your spec declares — create, read, update, delete — and resources are importable by id.

The provider’s own publishing identity is not yet configurable from glotto.yml: the type prefix is glotto and the Registry namespace defaults to glotto-dev. Surfacing those as per-target config is not supported yet.

Where a resource has a read operation, it also becomes a data source, so a practitioner can reference something they did not create. Collection endpoints emit a list data source alongside the single-item one.

An operation whose result is a short-lived credential — marked x-glotto-terraform-ephemeral in your spec — registers as an ephemeral resource instead, so its value never lands in Terraform state. Renewal and session-close hints (x-glotto-terraform-renew-at, -ttl-seconds, -close-operation) drive the corresponding framework callbacks.

Attribute shaping

Attributes are derived from your models, and the shaping follows standard OpenAPI where it can:

  • readOnly: true properties become Computed — server-assigned, never written from config.
  • required properties become Required; everything else is Optional.
  • uniqueItems: true arrays become sets rather than lists, so ordering is not spurious diff noise.

Where the spec’s own vocabulary isn’t enough, the x-glotto-terraform-* extensions override the inference per property — and those overrides win, so you can correct a schema you don’t control without editing it. Migrating from Stainless? Glotto translates the equivalent x-stainless-* extensions into these automatically — see Bring your Terraform attribute shaping across.

Publishing

The emitted module is the unit you publish: tag it and let the included .goreleaser.yml build the release artifacts the Terraform Registry expects, with terraform-registry-manifest.json declaring the protocol version. The provider carries a LICENSE file; Glotto stamps no licence terms into your provider’s source.

Kept true, not just generated

Like every Glotto artifact, the provider is a deterministic projection of your spec: byte-stable output, locked by golden tests, and compile-verified — the generated Go module is built in CI on every change to the engine, so a provider that would not compile never ships. It is regenerated in lockstep with your SDKs and docs from the same IR, and the drift gate proves the committed provider never lags your spec.

Add a resource, mark a field read-only, deprecate an endpoint — your provider is provably current on the next regeneration, and your practitioners’ configurations keep describing a real API.