Feature Specification: Provider Schema Extraction

Created: 2026-09-22

Status: Implemented

Input: Reconstructed from the code at 3c0765d, the nix-unit suite, the commit and pull request history of nix-tf-schema, the fediversity monorepo history from which the library was extracted, and the Claude Code logs.

User Scenarios & Testing (mandatory)

User Story 1 - Get a provider schema at build time (Priority: P1)

A maintainer has a packaged OpenTofu/Terraform provider from nixpkgs. The maintainer gets its schema without a network connection and without a hand-run tofu command: the raw tofu providers schema -json output, the tfvars variable form of it (see 001-flat-schema-conversion), and a Nix module type for it.

Why this priority: all other helpers take a provider schema as input. Without extraction, a maintainer must run tofu by hand and keep the output up to date.

Independent Test: extract the schema of hashicorp_external and cast a configuration of its external data source against the module type. The raw schema, the wrapped form and the cast configuration have the expected values.

Acceptance Scenarios:

  1. Given a provider selector p: [ p.hashicorp_external ], When the maintainer extracts the schemas, Then the result has schema, wrapped and converted, and the provider key in wrapped has no registry.opentofu.org/ prefix.
  2. Given the Nix build sandbox, When the extraction runs, Then it succeeds without network access, because the provider comes from the store.

User Story 2 - Vendor a schema file into a consumer (Priority: P1)

A consumer does not want import-from-derivation at evaluation time (for example because it evaluates for another architecture, where it cannot run the provider binary). The maintainer builds a normalized schema file once, commits it into the consumer, and reads it with builtins.fromJSON.

Why this priority: import-from-derivation makes evaluation slow and breaks cross-architecture evaluation and sandboxed nix flake check.

Independent Test: build the schema file for one provider. The JSON has format_version, source, version and resource_schemas, and has no data source or provider configuration schemas.

Acceptance Scenarios:

  1. Given a provider and its registry source address, When the maintainer builds the file, Then the file carries that source and the provider version, so that a consumer can assert that the file still matches its provider.
  2. Given the same provider twice, When the maintainer builds the file twice, Then the output is the same (sorted keys, fixed indentation).

Edge Cases

  • A provider whose schema uses types that the flat conversion does not support (object, tuple): the converted type of the extraction fails when the option is used. The nested walk (002-nested-resource-generation) supports them.
  • The extraction derives the provider name from the last segment of meta.homepage. [NEEDS CLARIFICATION: a provider package whose homepage does not end in the provider name gives a wrong required_providers key. Is meta.homepage the intended source of the name, or should the extraction take the source address as mkProviderSchemaFile does? This question goes away if the extraction is removed.] (#18)
  • The schema file keeps the first provider in the output only. It is made for one provider per file.
  • extractProviderSchemas uses import-from-derivation, and no known consumer uses it: consumers commit schema files from mkProviderSchemaFile. Its test is the only reason that the nix-unit suite cannot run as a sandboxed flake check. [NEEDS CLARIFICATION: remove extractProviderSchemas, or keep it as a supported helper? The removal is under consideration.] (#18)

Requirements (mandatory)

Functional Requirements

  • FR-001: The library MUST extract provider schemas by running tofu providers schema -json in a derivation, with the providers from pkgs.opentofu.withPlugins.
  • FR-002: The extraction MUST NOT need network access.
  • FR-003: The extraction result MUST give the raw schema, the wrapped tfvars form and the converted module type.
  • FR-004: The converted module type MUST drop attributes flagged sensitive unless the caller allows them.
  • FR-005: The library MUST build a schema file for one provider that keeps only resource_schemas and adds source and version.
  • FR-006: The schema file MUST be deterministic for the same provider.
  • FR-007: The schema file builder MUST NOT use import-from-derivation.

Key Entities

  • Provider schema: the JSON output of tofu providers schema -json, with provider_schemas keyed by fully qualified provider address.
  • Schema file: a normalized, self-identifying JSON file for one provider, for a consumer to commit.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: The test-extractProviderSchemas and test-mkProviderSchemaFile cases of the nix-unit suite pass in CI.
  • SC-002: A consumer that commits a schema file evaluates without import-from-derivation.

Assumptions

  • The provider is packaged in nixpkgs terraform-providers (or in the same shape), with version, owner and meta.homepage.
  • OpenTofu is the Terraform implementation. The registry.opentofu.org/ prefix is the only prefix that the wrapped and converted forms remove.