Skip to content

fix(provider-generator): match shorthand provider sources against OpenTofu schema keys - #293

Merged
so0k merged 1 commit into
mainfrom
claude/opentofu-provider-registry-zhrhk5
Jul 1, 2026
Merged

so0k merged 1 commit into
mainfrom
claude/opentofu-provider-registry-zhrhk5

Conversation

@so0k

@so0k so0k commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Related issue

Fixes #216

Description

Root cause. cdktn get fails under OpenTofu (TERRAFORM_BINARY_NAME=tofu) with Could not find provider with constraint ..., even though the provider installs correctly. The failure is in provider-schema → target matching, not in provider download.

In packages/@cdktn/provider-generator/src/get/generator/provider-generator.ts, isMatching expands a target source and compares it to the schema key. When a source omits a registry hostname (a shorthand like hashicorp/awscc), the old code assumed the missing hostname was always registry.terraform.io and compared it strictly against the schema key's hostname:

  • Terraform resolves hashicorp/awscc → schema key registry.terraform.io/hashicorp/awscc ✅
  • OpenTofu resolves hashicorp/awscc → schema key registry.opentofu.org/hashicorp/awscc ❌ (never matched)

Fix (minimal, intentionally). Only compare the hostname when the source explicitly pins one (a 3-part source). Shorthand 1- and 2-part sources now match on namespace/name and ignore the schema key's registry hostname:

const explicitHostname = targetElements.length === 3;
return (
  (!explicitHostname || targetSource.hostname === hostname) &&
  targetSource.namespace === namespace &&
  targetSource.name === provider
);

Why exactly this shape:

  • Same cdktf.json works under both CLIs. emitProvider writes terraformProviderSource = constraint.source, so the shorthand hashicorp/awscc is preserved in generated metadata — it stays registry-agnostic instead of being pinned to one registry. This avoids the downside of the documented workaround (registry.opentofu.org/hashicorp/awscc), which hard-codes an OpenTofu-only source address.
  • Explicit hostnames stay strict. A 3-part source like registry.terraform.io/hashicorp/awscc still only matches that exact registry and won't cross to registry.opentofu.org.
  • Rejected alternatives. Branching on TERRAFORM_BINARY_NAME couples generator logic to the binary and breaks with wrapper scripts/paths. A full "match against actual schema keys + explicit ambiguity error" design adds machinery for a case that can't occur from a single terraform/tofu providers schema run (each provider resolves to exactly one registry per invocation). Per the project's YAGNI > KISS priority, we kept it minimal; getProviderByConstraint uses .find(), so the pathological "same namespace/name under two hostnames" schema would deterministically pick the first key rather than throw — acceptable and not worth building around today.

Scope note. hcl2cdk's separate matcher (packages/@cdktn/hcl2cdk/src/provider.ts) already matches with .endsWith() and is hostname-agnostic, so it is unaffected. This change is deliberately confined to the one matcher on the cdktn get path.

Tests

Added provider-source-matching.test.ts driving TerraformProviderGenerator.generate(...) (since isMatching is module-private) over minimal hand-built schemas:

  1. shorthand hashicorp/awscc ↔ registry.opentofu.org/hashicorp/awscc → matches (the cdktn get fails to generate provider bindings when using OpenTofu #216 regression)
  2. shorthand hashicorp/awscc ↔ registry.terraform.io/hashicorp/awscc → still matches
  3. explicit registry.terraform.io/... ↔ registry.opentofu.org/... → stays strict, throws
  4. explicit hostname agreeing with the schema key → matches

Follow-up (out of scope): the repo currently has no integration tests that run with tofu. End-to-end coverage of the OpenTofu cdktn get path is tracked as a separate work item rather than bundled here, to keep this PR small and focused on the matcher fix. The unit tests above prove the matching behavior directly.

Note: the full nx unit suite was not run in the authoring environment (workspace ^build chain was slow); CI runs it here and it will also be validated locally. The change is a single boolean guard plus new tests.

Checklist

  • I have updated the PR title to match CDKTN's style guide
  • I have run the linter on my code locally (prettier via pre-commit hook)
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation if applicable (n/a)
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective
  • New and existing unit tests pass locally with my changes (deferred to CI — see note above)

🤖 Generated with Claude Code


Generated by Claude Code

…nTofu schema keys

Shorthand provider sources like "hashicorp/awscc" omit a registry
hostname. isMatching assumed the missing hostname was always
registry.terraform.io, but `tofu providers schema -json` returns schema
keys under registry.opentofu.org. As a result `cdktn get` failed with
"Could not find provider with constraint ..." under OpenTofu even though
the provider had been installed correctly (#216).

Only compare the hostname when the source explicitly pins one (a 3-part
source). Shorthand 1- and 2-part sources now match on namespace/name
regardless of the schema key's registry hostname, so the same
cdktf.json works under both Terraform and OpenTofu. Explicit 3-part
hostnames stay strict and do not cross registries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BG9ZUpdDa3GDNRkRMC2b5U
@so0k
so0k requested a review from a team as a code owner July 1, 2026 08:10

@jsteinich jsteinich left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While not matching against the current binary makes sense, we still may want a away in the future for users to be able to explicitly set cdktn into Terraform, OpenTofu, or mixed mode. Can be a follow-up item though.

@so0k
so0k merged commit fda0103 into main Jul 1, 2026
260 checks passed
@so0k
so0k deleted the claude/opentofu-provider-registry-zhrhk5 branch July 1, 2026 10:53
so0k pushed a commit that referenced this pull request Jul 3, 2026
🤖 Release PR — merge to cut a new release. Kept open and rebased
as commits land on `main`.
---


<details><summary>0.23.4</summary>

##
[0.23.4](v0.23.3...v0.23.4)
(2026-07-02)


### Features

* **cli:** validate Terraform CLI feature versions
([#237](#237))
([32d434c](32d434c))
* declared Terraform/OpenTofu target versions (validation foundation)
([#269](#269))
([0aa2343](0aa2343))
* **lib:** S3-backend - Add `useLockfile` field and update
`dynamodbTable` deprecated JSDoc
([#234](#234))
([32a408f](32a408f))
* **lib:** validate Fn usage against Terraform/OpenTofu versions
([#268](#268))
([cdf8115](cdf8115))


### Bug Fixes

* **cli:** don't mistake terraform error output for a missing-variable
prompt
([#267](#267))
([0ea946f](0ea946f))
* **cli:** release terraform state lock when interrupting diff/deploy
([#284](#284))
([de617db](de617db))
* **cli:** resolve prebuilt Java provider versions via repo1.maven.org
([#285](#285))
([d5af07d](d5af07d))
* **gha:** Adding CHANGELOG.md to prettier ignore list
([#258](#258))
([5160469](5160469))
* **gha:** pull jsii-terraform CI image from GHCR instead of Docker Hub
([#261](#261))
([f19d34b](f19d34b))
* **provider-generator:** copy only publishable files into the jsii
compile bundle
([#292](#292))
([562d4c7](562d4c7))
* **provider-generator:** match shorthand provider sources against
OpenTofu schema keys
([#293](#293))
([fda0103](fda0103))
* **release:** add Changelog title for correct release-please insertion
([#255](#255))
([004818a](004818a))
* **release:** drop devEngines.packageManager that broke npm publish
([ef508a6](ef508a6))
* **tools:** repair generate-function-bindings tool
([#273](#273))
([821e1cf](821e1cf))


### Miscellaneous Chores

* Add Gradle to Mise config
([#271](#271))
([1578270](1578270))
* add pnpm to mise
([#266](#266))
([48ab91f](48ab91f))
* add uv to mise
([#260](#260))
([163cf3d](163cf3d))
* **deps:** bump nrwl/nx-set-shas from
38457b511e60ee4e1da09255b658e480748a1af4 to
afb73a62d26e41464e9254689e1fd6122ee683c1
([#236](#236))
([b5ac018](b5ac018))
* **deps:** bump the github-actions-backward-compatible group across 1
directory with 7 updates
([#235](#235))
([de67d9f](de67d9f))
* **deps:** replace uuid dependency with node:crypto.randomUUID
([#291](#291))
([6d3657a](6d3657a))
* ESLint ignore test edge-provider-bindings
([#270](#270))
([ba407bb](ba407bb))
* Fix Verdaccio logging config
([#272](#272))
([aded64b](aded64b))
* **gha:** parallelize provider binding generation for documentation
examples
([#244](#244))
([0a9c955](0a9c955))
* Migrate package manager from yarn to pnpm
([#170](#170))
([d23da4e](d23da4e))
* migrate planning artifacts to cdktn-planning [skip ci]
([968c358](968c358))
* **release:** add release-please automation for versioning
([#243](#243))
([c759eec](c759eec))
* Remove dependency-pinner tool
([#250](#250))
([42c27d5](42c27d5))
* Remove unused dependencies
([#281](#281))
([c7de65e](c7de65e))
* **tests:** run verdaccio in-process
([#248](#248))
([c17677d](c17677d))
* Update JSII version constraint
([#245](#245))
([d89558f](d89558f))
* Update scheduled workflows to only run on open-constructs/cdk-terrain
([#256](#256))
([ba408cf](ba408cf))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: open-constructs-cdktn[bot] <291052431+open-constructs-cdktn[bot]@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

I'm going to lock this pull request because it has been closed for 30 days. This helps our maintainers find and focus on the active issues. If you've found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Aug 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cdktn get fails to generate provider bindings when using OpenTofu

3 participants