Skip to content

fix(recipes): add provider alias placeholders before terraform get - #13300

Merged
nicolejms merged 6 commits into
mainfrom
nicolejms-terraform-provider-alias-fix
Oct 15, 2026
Merged

nicolejms merged 6 commits into
mainfrom
nicolejms-terraform-provider-alias-fix

Conversation

@nicolejms

@nicolejms nicolejms commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Terraform recipes fail when the module declares provider configuration_aliases. This PR fixes the failure.

Radius runs the first terraform get with the module block only, the same as on main. Modules that do not declare configuration_aliases do not change.

If terraform get fails, Radius inspects the downloaded module (Terraform downloads the module before it validates it). For each aliased provider in the environment recipe config that the module declares in configuration_aliases, Radius adds a placeholder provider block (alias only), a required_providers entry with the source from the module, and an entry in the module providers map. Then it runs terraform get again. Radius does not pass aliases that the module does not declare, so a module that configures its own aliased provider still works.

After the module inspection, AddProviders always replaces the placeholders with the full provider configuration. If the module does not declare a matching alias, AddProviders removes the module providers map.

The Terraform driver now passes the environment configuration to GetRecipeMetadata, so the metadata path can also retry.

Reason for change

terraform get validates the module provider requirements. Radius added the aliased provider blocks only after the download, so terraform get failed with Missing required provider configuration. The deploy, delete, and GetRecipeMetadata paths all download the module, so all three paths failed.

Part of #13299

The custom subtest of Test_TerraformRecipe_AzureResourceGroup and the docs note are in open PR #13296. They are not on main. After this PR and #13296 merge, a follow-up removes the t.Skip for #13299 and updates the note in running-functional-tests.md.

How to test

Unit tests on Linux (Docker golang:1.27, non-root user):

gofmt -l ./pkg/recipes                    # passed (no output)
go vet ./pkg/recipes/terraform/... ./pkg/recipes/driver/...   # passed
go test ./pkg/recipes/terraform/... ./pkg/recipes/driver/... ./pkg/recipes/engine/... -cover -count=1   # passed

Coverage:

Package main This PR
pkg/recipes/terraform 79.2% 80.4%
pkg/recipes/terraform/config 95.3% 96.4%
pkg/recipes/driver/terraform 87.3% 87.3%

AddProviderAliasPlaceholders, updateModuleWithProviderAliases, and retryGetWithProviderAliases have 100% coverage.

TestProviderConfigurationAliasesWithTerraform installs Terraform 1.16.5 and runs a real terraform get against local modules. It is skipped with -short. It checks:

  • A module with configuration_aliases: metadata and config generation pass, and main.tf.json has the full provider config and the module providers map.
  • A module with configuration_aliases for cyrilgdn/postgresql: the retry adds the source, and main.tf.json has required_providers with cyrilgdn/postgresql.
  • A module without aliases: passes, and has no module providers map.
  • An alekc/kubectl module that uses only the default provider, with kubectl.custom in the environment: passes, and has no module providers map.
  • A module that configures its own provider "aws" { alias = "custom" }, with aws.custom in the environment: passes, and has no module providers map.
  • A module with configuration_aliases and no alias in the environment: fails with Missing required provider configuration.

Manual checks with Docker hashicorp/terraform:1.16.5 get:

  • get downloads the module before it fails validation, so Radius can inspect the module after the first failure.
  • An alias-only placeholder for a cyrilgdn/postgresql alias fails with Provider type mismatch. It passes when required_providers has the source. "backend": null is not valid, so the backend is now omitted when it is not set.

File change summary

File Summary of change
pkg/recipes/terraform/config/config.go Add AddProviderAliasPlaceholders, which adds placeholders only for aliases that the module declares, with the module source. AddProviders always resets Provider. updateModuleWithProviderAliases removes stale module providers maps.
pkg/recipes/terraform/config/types.go Add the moduleProvidersKey constant. Omit backend when it is not set.
pkg/recipes/terraform/execute.go Pass the config to downloadAndInspect.
pkg/recipes/terraform/module.go Add retryGetWithProviderAliases, which inspects the module after a failed terraform get, adds the placeholders, and runs terraform get again.
pkg/recipes/driver/terraform/terraform.go Pass EnvConfig to the executor GetRecipeMetadata.
pkg/recipes/terraform/config/config_test.go Unit tests for the placeholders and their replacement in AddProviders.
pkg/recipes/terraform/execute_test.go Unit test that the first saved main.tf.json has no placeholders.
pkg/recipes/terraform/module_test.go Unit tests for the cases where the retry returns the original error.
pkg/recipes/driver/terraform/terraform_test.go Check that GetRecipeMetadata passes the environment configuration.
pkg/recipes/terraform/provider_alias_test.go New test that runs a real terraform get against modules with and without configuration_aliases, including non-HashiCorp providers and a module that configures its own aliased provider.

Terraform validates module provider requirements during 'terraform get'.
A module that declares provider configuration_aliases failed with
"Missing required provider configuration", because Radius added the
aliased provider blocks only after the module download.

getTerraformConfig now writes alias-only placeholder provider blocks and
the module providers map for each aliased provider in the environment
recipe config. This fixes the deploy, delete, and GetRecipeMetadata paths.
AddProviders now always replaces the placeholders, and removes the module
providers map when the module does not declare a matching alias.

Add unit tests, and a test that runs a real 'terraform get' against a
module with configuration_aliases.

Part of #13299

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: nicolejms <nicolej@microsoft.com>
Copilot AI balanced review requested due to automatic review settings October 14, 2026 21:03
@nicolejms
nicolejms requested review from a team as code owners October 14, 2026 21:03
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@github-actions github-actions Bot added the pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable label Oct 14, 2026
@nicolejms nicolejms added the pr:standard Ongoing maintenance, minor improvements, documentation updates, and routine development work label Oct 14, 2026

Copilot AI 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.

🟡 Changes recommended

Metadata requests still omit environment configuration, and non-HashiCorp provider aliases encounter source-identity mismatches.

2 open findings
What changed in this PR

Addresses Terraform recipe alias failures in #13299 by adding provider placeholders before module download, then replacing them after inspection.

Changes:

  • Writes alias placeholders before terraform get.
  • Replaces placeholders and removes unmatched module provider mappings.
  • Adds unit coverage and real-Terraform regression tests.
File Description
pkg/​recipes/​terraform/​provider_alias_test.go Tests alias handling with real Terraform.
pkg/​recipes/​terraform/​execute.go Adds placeholders before saving bootstrap configuration.
pkg/​recipes/​terraform/​execute_test.go Verifies persisted placeholders.
pkg/​recipes/​terraform/​config/​types.go Defines the module providers key.
pkg/​recipes/​terraform/​config/​config.go Generates placeholders and replaces temporary configuration.
pkg/​recipes/​terraform/​config/​config_test.go Tests placeholder creation, replacement, and cleanup.

🧠 Review effort: Balanced


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/recipes/terraform/config/config.go
Comment thread pkg/recipes/terraform/execute.go Outdated
Comment thread pkg/recipes/terraform/config/config.go
Comment thread pkg/recipes/terraform/config/config.go
@github-actions github-actions Bot added pr:waiting-for-author The author needs to address human review feedback or human-endorsed inline feedback and removed pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable labels Oct 14, 2026
nicolejms and others added 2 commits October 14, 2026 14:30
… config

Address review feedback on the provider alias placeholders:

- The alias placeholders have no source, so Terraform uses the hashicorp
  namespace. Modules that require an aliased provider from another
  namespace (for example cyrilgdn/postgresql) failed 'terraform get' with
  a provider type mismatch. Terraform downloads the module before it
  validates the configuration, so on failure Radius now inspects the
  downloaded module, adds required_providers sources for the placeholder
  providers, and runs 'terraform get' again.
- Omit the Terraform backend from main.tf.json when it is not set,
  because Terraform does not accept a null backend.
- The Terraform driver now passes the environment configuration to
  GetRecipeMetadata, so the metadata path also adds the placeholders.

Add unit tests, a driver assertion, and a real-Terraform case for a
non-HashiCorp aliased provider.

Part of #13299

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: nicolejms <nicolej@microsoft.com>
…wnload

Do not add provider alias placeholders before the first terraform get.
Modules that do not declare configuration_aliases now download with the
same configuration as before.

If terraform get fails, inspect the downloaded module. Add placeholders
only for the environment aliases that the module declares in
configuration_aliases, with the provider source from the module, and run
terraform get again.

Add real Terraform regression tests for a non-HashiCorp provider module
that uses only the default provider, and for a module that configures its
own aliased provider.

Part of #13299

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: nicolejms <nicolej@microsoft.com>
@github-actions github-actions Bot added pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable and removed pr:waiting-for-author The author needs to address human review feedback or human-endorsed inline feedback labels Oct 14, 2026
@github-actions github-actions Bot added pr:review-approved Required reviews are approved; checks may still be pending and removed pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable labels Oct 14, 2026
@nicolejms
nicolejms enabled auto-merge October 14, 2026 21:58
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Unit Tests

    2 files  ± 0    448 suites  ±0   17m 46s ⏱️ +27s
7 431 tests +26  7 429 ✅ +26  2 💤 ±0  0 ❌ ±0 
8 864 runs  +26  8 862 ✅ +26  2 💤 ±0  0 ❌ ±0 

Results for commit d2937dd. ± Comparison against base commit d233ffc.

♻️ This comment has been updated with latest results.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.74%. Comparing base (d233ffc) to head (d2937dd).

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #13300      +/-   ##
==========================================
+ Coverage   60.68%   60.74%   +0.05%     
==========================================
  Files         772      772              
  Lines       45640    45687      +47     
==========================================
+ Hits        27698    27752      +54     
+ Misses      17942    17935       -7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Resolve the conflict in pkg/recipes/terraform/config/config_test.go.
Keep the provider alias placeholder tests and the custom Azure
configuration test from #13296.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: nicolejms <nicolej@microsoft.com>
@github-actions github-actions Bot added pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable and removed pr:review-approved Required reviews are approved; checks may still be pending labels Oct 14, 2026
@github-actions github-actions Bot removed the pr:waiting-for-review A reviewer owns the next action; required approval is pending or unverifiable label Oct 14, 2026
@github-actions github-actions Bot added the pr:review-approved Required reviews are approved; checks may still be pending label Oct 14, 2026
@radius-functional-tests

radius-functional-tests Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Radius functional test overview

🔍 Go to test action run

Click here to see the test run details
Name Value
Repository radius-project/radius
Commit ref d2937dd
Unique ID func995bf07f03
Image tag pr-func995bf07f03
  • Dapr: 1.14.4
  • Azure KeyVault CSI driver: 1.4.2
  • Azure Workload identity webhook: 1.3.0
  • Bicep recipe location ghcr.io/radius-project/dev/test/testrecipes/test-bicep-recipes/<name>:pr-func995bf07f03
  • Terraform recipe location http://tf-module-server.radius-test-tf-module-server.svc.cluster.local/<name>.zip (in cluster)
  • applications-rp test image location: ghcr.io/radius-project/dev/applications-rp:pr-func995bf07f03
  • dynamic-rp test image location: ghcr.io/radius-project/dev/dynamic-rp:pr-func995bf07f03
  • controller test image location: ghcr.io/radius-project/dev/controller:pr-func995bf07f03
  • ucp test image location: ghcr.io/radius-project/dev/ucpd:pr-func995bf07f03
  • deployment-engine test image location: ghcr.io/radius-project/deployment-engine:latest

Test Status

⌛ Building Radius and pushing container images for functional tests...
✅ Container images build succeeded
⌛ Publishing Bicep Recipes for functional tests...
✅ Recipe publishing succeeded
⌛ Starting corerp-cloud functional tests...
⌛ Starting ucp-cloud functional tests...
✅ ucp-cloud functional tests succeeded
✅ corerp-cloud functional tests succeeded

@nicolejms
nicolejms added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit ef1ce2e Oct 15, 2026
90 checks passed
@nicolejms
nicolejms deleted the nicolejms-terraform-provider-alias-fix branch October 15, 2026 00:06
@github-actions github-actions Bot removed the pr:review-approved Required reviews are approved; checks may still be pending label Oct 15, 2026
pujitha24 pushed a commit to pujitha24/radius that referenced this pull request Oct 16, 2026
…ius-project#13312)

## Summary

Removes the `t.Skip` for the `custom` subtest in the Terraform recipe
cloud functional test, now that radius-project#13300 fixes `terraform get` rejecting
modules with provider `configuration_aliases`.

## Reason for change

The skip referenced radius-project#13299. radius-project#13300 merged the fix, and this follow-up
re-enables the test so the cloud functional run verifies the `custom`
subtest end to end.

Fixes radius-project#13299

## How to test

Run the cloud functional tests (`recipe_terraform_test.go`,
`Test_TerraformRecipe_AzureResourceGroup` or equivalent) in CI; the
`custom` subtest should now run and pass.

## File change summary

| File | Summary of change |
| ---- | ----------------- |
|
`test/functional-portable/corerp/cloud/resources/recipe_terraform_test.go`
| Remove `t.Skip` for the `custom` subtest. |

---------

Signed-off-by: Nicole James <nicolej@microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:standard Ongoing maintenance, minor improvements, documentation updates, and routine development work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Terraform recipes fail when the module declares provider configuration_aliases

3 participants