Skip to content

feat(cli): validate Terraform CLI feature versions#237

Open
sakul-learning wants to merge 1 commit into
open-constructs:mainfrom
sakul-learning:feat/terraform-cli-feature-version-validation
Open

feat(cli): validate Terraform CLI feature versions#237
sakul-learning wants to merge 1 commit into
open-constructs:mainfrom
sakul-learning:feat/terraform-cli-feature-version-validation

Conversation

@sakul-learning
Copy link
Copy Markdown
Contributor

Summary

Introduce a Terraform-compatible CLI feature/version validator that can be reused by feature PRs whose support depends on both the selected CLI product and its version.

This adds:

  • parseTerraformCliVersion() to detect Terraform vs OpenTofu from the first line of plain version output:
    • Terraform vX.Y.Z -> terraform
    • OpenTofu vX.Y.Z -> opentofu
  • ValidateTerraformFeatureVersion, a single validation class for the matrix:
    • feature -> CLI product (terraform / opentofu) -> semver constraint
  • tests proving that version -json-style output is not used to infer the product, because OpenTofu keeps the Terraform-compatible terraform_version key.

Intended downstream use

This is meant to unblock/reduce duplication for the S3 useLockfile work in:

A follow-up PR can add the backend-specific validation with:

new ValidateTerraformFeatureVersion("S3 native state locking", {
  terraform: ">=1.10.0",
  opentofu: ">=1.10.0",
});

If future features land at different times, the same class can encode different product constraints, for example:

new ValidateTerraformFeatureVersion("some future feature", {
  terraform: ">=1.12.0",
  opentofu: ">=1.10.0",
});

Test plan

  • yarn jest packages/cdktn/test/validations.test.ts --runInBand
  • yarn lerna run --scope cdktn build
  • yarn nx test cdktn --runInBand

@sakul-learning
Copy link
Copy Markdown
Contributor Author

Follow-up reference for future feature-specific validation PRs: I added a semi-curated generator in the canitf-project repo that emits a CDK Terrain-shaped TypeScript source file for HCL/configuration feature constraints.

Generated file:

Human-controlled input:

Quick usage:

canitf generate-cdktn-source \
  --features-input data/hcl-feature-input.json \
  --generated-features data/features.json \
  --out data/cdktn-feature-constraints.ts

The generated output is intended to line up with this PR's ValidateTerraformFeatureVersion shape, e.g. feature key -> { featureName, constraints, category, sources }, where constraints maps terraform / opentofu to semver ranges.

Longer context: why this exists and how to use it

The broad changelog-derived table in canitf-project is useful for discovery, but too noisy to drop directly into CDK Terrain. The more useful workflow for this PR series is semi-automated:

  1. Fetch official Terraform/OpenTofu release data and build the broad candidate table:

    canitf fetch --per-page 100 --max-pages 3 --out data/releases.json
    canitf build-table \
      --input data/releases.json \
      --json-out data/features.json \
      --markdown-out data/feature-table.md \
      --include-canitf
  2. Maintain the narrowed, human-curated scope in:

    data/hcl-feature-input.json
    

    That file controls the baseline, feature keys, CDK Terrain use cases, explicit semver constraints, and source links. Generated changelog/cani.tf rows can fill missing fields, but human input remains authoritative.

  3. Generate a CDK Terrain-style TypeScript file:

    canitf generate-cdktn-source \
      --features-input data/hcl-feature-input.json \
      --generated-features data/features.json \
      --out data/cdktn-feature-constraints.ts

Current focused feature set:

  • S3 native state locking / S3BackendConfig.useLockfile
  • provider-defined functions
  • configured provider-defined functions
  • override_resource, override_data, override_module
  • ephemeral values and resources
  • write-only attributes
  • backend configuration using locals and variables

Important baseline note: I could not confirm “OpenTofu forked from Terraform 1.7.5”; that appears to be the wrong framing. The local CDK Terrain workspace pins Terraform 1.7.5 in mise.toml, so the generator treats 1.7.5 as the CDK Terrain comparison baseline, not the OpenTofu fork point.

Example generated shape:

export const TERRAFORM_HCL_FEATURE_CONSTRAINTS = {
  "s3-native-state-locking": {
    featureName: "S3 native state locking",
    constraints: {
      terraform: ">=1.10.0",
      opentofu: ">=1.10.0",
    },
    category: "backend",
    cdktnUseCase: "S3BackendConfig.useLockfile",
    sources: [
      "https://developer.hashicorp.com/terraform/language/v1.10.x/upgrade-guides#s3-backend",
      "https://opentofu.org/docs/intro/whats-new/#native-s3-state-locking",
    ],
  },
} as const;

This should make the next PRs easier: update the curated JSON input, regenerate the TS source, then wire the relevant feature key into the specific validation path.

@sakul-learning sakul-learning changed the title feat(cdktn): validate Terraform CLI feature versions feat(cli): validate Terraform CLI feature versions Jun 4, 2026
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.

1 participant