Skip to content

feat: add a read-only Terraform provider prototype - #489

Open
cons-tan-tan wants to merge 2 commits into
cachix:mainfrom
cons-tan-tan:feat/terraform-read-only
Open

cons-tan-tan wants to merge 2 commits into
cachix:mainfrom
cons-tan-tan:feat/terraform-read-only

Conversation

@cons-tan-tan

Copy link
Copy Markdown

Summary

This prototype adds a Terraform provider that reads an existing secretspec.toml through the Go SDK and Rust resolver. Terraform configurations can reuse the manifest's storage configuration, profiles, scopes and derived values.

SecretSpec can generate and save missing values during resolution, including reads triggered by terraform plan. This provider refuses resolution that requires saving a generated or prompted value, while allowing existing values to be read.

  • Add secretspec_secrets as an ephemeral resource and a data source. Both accept path, optional profile, scope and reason, and return a sensitive values map.
  • Ephemeral results are omitted from state and saved plans and can be referenced in ephemeral contexts. The data source supports ordinary resource arguments and persists the entire returned map, including unused entries.
  • Expose WithReadOnly and WithNoFiles in the Go SDK through strict native requests. Older libraries reject restricted requests before resolution. The provider enables both options; the Rust resolver rejects as_path declarations, including hidden dependencies, before fetching values.
  • Move the existing read-only guard before generation so a refused command generator cannot run first. This also applies to serve --read-only; generation without provider storage remains allowed.
  • Add local development instructions and examples, and run Terraform acceptance tests in the SDK CI job. The prototype uses development overrides for local testing.

Related to #233. This implements the read side of the SDK-backed provider prototype discussed in the comments. The AWS publication/naming module and broader coexistence guide are outside the scope of this PR.

Testing

Local plan/apply tests passed on Linux with Terraform 1.10.5 and 1.16.1, covering sensitive output, ephemeral omission from saved plans/state, data-source persistence and unchanged stores after refusal. Tests use temporary dotenv stores; live AWS backends were not exercised.

A legacy-ABI shim also confirmed that restricted calls never invoke the legacy resolver, while unrestricted calls still work.

Expose read-only and no-files options through the strict native call
format so older libraries reject restrictions before resolution.

Refuse generation that requires storage before invoking generators,
and keep hidden dependency names out of scoped refusal diagnostics.
Resolve existing manifests as secretspec_secrets ephemeral resources or
data sources, returning a sensitive map for the selected profile/scope.

Enable SDK read-only and no-files restrictions for every lookup.
Document the state persistence tradeoff and local development setup,
and run Terraform acceptance tests in the SDK CI job.
if !m.Reason.IsNull() {
builder.WithReason(m.Reason.ValueString())
}
resolved, err := builder.Load()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ctx.Err() check above only handles cancellation before resolution starts. builder.Load() does not receive the context, so if Terraform requests cancellation while a backend read or an allowed non-persisting command generator is running, that work continues and this RPC remains blocked until the native call returns. A hanging command can therefore prevent a graceful stop of plan/apply.

Could we propagate cancellation through the Go SDK/native resolver to backend operations and child processes, and add a test that cancels an in-flight resolution? Returning early from a Go goroutine alone would leave the native work running.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants