Repository navigation
fix(recipes): add provider alias placeholders before terraform get - #13300
Conversation
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>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
There was a problem hiding this comment.
🟡 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.
… 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>
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
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>
Radius functional test overviewClick here to see the test run details
Test Status⌛ Building Radius and pushing container images for functional tests... |
…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>

Summary
Terraform recipes fail when the module declares provider
configuration_aliases. This PR fixes the failure.Radius runs the first
terraform getwith the module block only, the same as onmain. Modules that do not declareconfiguration_aliasesdo not change.If
terraform getfails, 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 inconfiguration_aliases, Radius adds a placeholder provider block (aliasonly), arequired_providersentry with thesourcefrom the module, and an entry in the moduleprovidersmap. Then it runsterraform getagain. 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,
AddProvidersalways replaces the placeholders with the full provider configuration. If the module does not declare a matching alias,AddProvidersremoves the moduleprovidersmap.The Terraform driver now passes the environment configuration to
GetRecipeMetadata, so the metadata path can also retry.Reason for change
terraform getvalidates the module provider requirements. Radius added the aliased provider blocks only after the download, soterraform getfailed withMissing required provider configuration. The deploy, delete, andGetRecipeMetadatapaths all download the module, so all three paths failed.Part of #13299
The
customsubtest ofTest_TerraformRecipe_AzureResourceGroupand the docs note are in open PR #13296. They are not onmain. After this PR and #13296 merge, a follow-up removes thet.Skipfor #13299 and updates the note inrunning-functional-tests.md.How to test
Unit tests on Linux (Docker
golang:1.27, non-root user):Coverage:
mainpkg/recipes/terraformpkg/recipes/terraform/configpkg/recipes/driver/terraformAddProviderAliasPlaceholders,updateModuleWithProviderAliases, andretryGetWithProviderAliaseshave 100% coverage.TestProviderConfigurationAliasesWithTerraforminstalls Terraform 1.16.5 and runs a realterraform getagainst local modules. It is skipped with-short. It checks:configuration_aliases: metadata and config generation pass, andmain.tf.jsonhas the full provider config and the moduleprovidersmap.configuration_aliasesforcyrilgdn/postgresql: the retry adds the source, andmain.tf.jsonhasrequired_providerswithcyrilgdn/postgresql.providersmap.alekc/kubectlmodule that uses only the default provider, withkubectl.customin the environment: passes, and has no moduleprovidersmap.provider "aws" { alias = "custom" }, withaws.customin the environment: passes, and has no moduleprovidersmap.configuration_aliasesand no alias in the environment: fails withMissing required provider configuration.Manual checks with Docker
hashicorp/terraform:1.16.5 get:getdownloads the module before it fails validation, so Radius can inspect the module after the first failure.cyrilgdn/postgresqlalias fails withProvider type mismatch. It passes whenrequired_providershas the source."backend": nullis not valid, so the backend is now omitted when it is not set.File change summary
pkg/recipes/terraform/config/config.goAddProviderAliasPlaceholders, which adds placeholders only for aliases that the module declares, with the module source.AddProvidersalways resetsProvider.updateModuleWithProviderAliasesremoves stale moduleprovidersmaps.pkg/recipes/terraform/config/types.gomoduleProvidersKeyconstant. Omitbackendwhen it is not set.pkg/recipes/terraform/execute.godownloadAndInspect.pkg/recipes/terraform/module.goretryGetWithProviderAliases, which inspects the module after a failedterraform get, adds the placeholders, and runsterraform getagain.pkg/recipes/driver/terraform/terraform.goEnvConfigto the executorGetRecipeMetadata.pkg/recipes/terraform/config/config_test.goAddProviders.pkg/recipes/terraform/execute_test.gomain.tf.jsonhas no placeholders.pkg/recipes/terraform/module_test.gopkg/recipes/driver/terraform/terraform_test.goGetRecipeMetadatapasses the environment configuration.pkg/recipes/terraform/provider_alias_test.goterraform getagainst modules with and withoutconfiguration_aliases, including non-HashiCorp providers and a module that configures its own aliased provider.