@@ -150,20 +150,21 @@ graph LR
1501501 . Platform team deploys ` terraformConfig ` and/or ` bicepConfig ` resources.
1511512 . Platform team deploys an ` environment ` referencing them by resource ID.
1521523 . Environment controller validates the referenced config resources exist
153- (PUT-time validation).
154- 4 . At recipe execution time, the recipe driver resolves the config resource,
155- populates ` recipes.Configuration.RecipeConfig ` , and proceeds exactly as the
156- existing ` Applications.Core ` code path does today.
157- 5 . Secret references (` SecretReference ` with ` source ` + ` key ` ) are resolved at
153+ at PUT time and returns ` 400 Bad Request ` if not.
154+ 4 . At recipe execution time, the configuration loader fetches the referenced
155+ config resources and populates ` recipes.Configuration.RecipeConfig ` . The
156+ loader bridges the new schema into the existing ` RecipeConfig ` shape so the
157+ shared Terraform and Bicep drivers consume it through the same path the
158+ legacy ` Applications.Core ` ` recipeConfig ` flow uses.
159+ 5 . When ` terraformrc.providerInstallation ` is set, the Terraform driver
160+ renders a ` .terraformrc ` in the working directory and points Terraform at
161+ it via ` TF_CLI_CONFIG_FILE ` for both Deploy and Delete. The field is
162+ optional; the legacy ` Applications.Core ` path leaves it nil and behavior is
163+ unchanged.
164+ 6 . Secret references (` SecretReference ` with ` source ` + ` key ` ) are resolved at
158165 execution time by the driver, same as the legacy path. No secrets are
159166 persisted in the config resources.
160167
161- ### Delete protection
162-
163- Config resources cannot be deleted while referenced by an environment. The
164- delete controller checks for active references and returns ` 409 Conflict ` if
165- any exist. This follows the same pattern used by RecipePacks.
166-
167168### Example usage
168169
169170``` bicep
@@ -255,56 +256,63 @@ resource stagingEnv 'Radius.Core/environments@2025-08-01-preview' = {
255256## Compatibility
256257
257258- ` Applications.Core/environments ` with ` recipeConfig ` is unchanged and
258- continues to work.
259+ continues to work. The legacy datamodel types (` AuthConfig ` , ` GitAuthConfig ` ,
260+ ` ProviderConfigProperties ` , etc.) are untouched.
259261- ` Radius.Core/environments ` is new; there is no migration concern.
260- - The Terraform and Bicep recipe drivers already consume
261- ` recipes.Configuration.RecipeConfig ` . The only new code is populating that
262- struct from the config resource instead of from inline environment fields.
263-
264- ## Implementation plan
265-
266- ### Task 1: TypeSpec + codegen
267-
268- - Define ` Radius.Core/terraformConfig ` and ` Radius.Core/bicepConfig ` resources
269- in TypeSpec under ` typespec/Radius.Core/ ` .
270- - Add ` terraformConfig ` and ` bicepConfig ` optional string fields to
271- ` Radius.Core/environments ` .
272- - ` TerraformConfig ` : ` terraformrc ` (providerInstallation, credentials) + ` env ` .
273- No ` providers ` , no ` envSecrets ` (those are legacy; use recipe parameters).
274- - ` BicepConfig ` : ` registryAuthentication ` with ` authenticationMethod ` enum
275- (BasicAuth, AzureWI, AwsIrsa), ` basicAuthSecretId ` , ` azureWiClientId ` ,
276- ` azureWiTenantId ` , ` awsIamRoleArn ` .
277- - Regenerate SDKs.
278-
279- ### Task 2: Datamodel + converters
280-
281- - Add Go datamodel structs for ` TerraformConfigResource ` and
282- ` BicepConfigResource ` .
283- - Implement bidirectional API-to-datamodel converters.
284- - Unit tests for all conversions.
285-
286- ### Task 3: REST controllers
287-
288- - Standard CRUD controllers for both config resources.
289- - Delete-guard filter: reject delete if any environment references the config
290- (query environments by ` terraformConfig ` / ` bicepConfig ` field).
291- - Register routes.
292- - Unit tests.
293-
294- ### Task 4: Environment controller wiring
295-
296- - On environment create/update, validate that referenced config resource IDs
297- exist (return 400 if not).
298- - At recipe execution time, resolve the config resource and populate
299- ` recipes.Configuration.RecipeConfig ` using the same field mapping the legacy
300- ` Applications.Core ` path uses.
301- - Unit tests for the resolution path.
302-
303- ### Task 5: Functional tests
304-
305- - Deploy a Terraform recipe with env vars via ` Radius.Core/environments ` with
306- ` terraformConfig.env ` .
307- - Deploy a ` Radius.Core/bicepConfigs ` resource with ` registryAuthentication `
308- and validate CRUD + environment reference wiring.
309- - Verify delete protection: attempt to delete a config resource while
310- referenced by an environment, expect 409.
262+ - The shared Terraform and Bicep recipe drivers already consume
263+ ` recipes.Configuration.RecipeConfig ` . The new resources populate that struct
264+ through the same internal shape, so the drivers do not need to know which
265+ namespace the environment came from.
266+ - A new optional ` ProviderInstallation ` field was added to the shared
267+ ` TerraformConfigProperties ` datamodel. The ` Applications.Core ` path leaves
268+ it nil, so the Terraform driver behavior is unchanged for existing users.
269+
270+ ## Code map
271+
272+ - ` typespec/Radius.Core/terraformConfigs.tsp ` ,
273+ ` typespec/Radius.Core/bicepConfigs.tsp ` — resource definitions.
274+ - ` typespec/Radius.Core/environments.tsp ` — adds ` terraformConfig? ` and
275+ ` bicepConfig? ` properties.
276+ - ` swagger/specification/radius/resource-manager/Radius.Core/preview/2025-08-01-preview/openapi.json `
277+ and ` pkg/corerp/api/v20250801preview/zz_generated_* ` — regenerated SDK.
278+ - ` pkg/corerp/datamodel/terraformconfig.go ` ,
279+ ` pkg/corerp/datamodel/bicepconfig.go ` — datamodels.
280+ - ` pkg/corerp/api/v20250801preview/terraformconfig_conversion.go ` ,
281+ ` bicepconfig_conversion.go ` — bidirectional converters.
282+ - ` pkg/corerp/datamodel/converter/terraformconfig_converter.go ` ,
283+ ` bicepconfig_converter.go ` — versioned converter wiring.
284+ - ` pkg/corerp/setup/setup.go ` — registers CRUD routes for both resources.
285+ - ` pkg/corerp/frontend/controller/environments/v20250801preview/createorupdateenvironment.go ` —
286+ PUT-time validation of referenced config IDs.
287+ - ` pkg/recipes/configloader/environment.go ` — resolves config resources and
288+ bridges them into the shared ` RecipeConfig ` shape.
289+ - ` pkg/corerp/datamodel/recipe_types.go ` — adds optional ` ProviderInstallation `
290+ to ` TerraformConfigProperties ` for the shared driver.
291+ - ` pkg/recipes/terraform/cliconfig.go ` — renders ` .terraformrc ` from
292+ ` provider_installation ` .
293+ - ` pkg/recipes/terraform/execute.go ` — wires the ` .terraformrc ` writer into
294+ Deploy and Delete via ` TF_CLI_CONFIG_FILE ` .
295+ - ` test/functional-portable/dynamicrp/noncloud/resources/terraformconfig_bicepconfig_test.go ` —
296+ functional tests for CRUD wiring and the combined Terraform+Bicep flow.
297+
298+ ## Status and known limitations
299+
300+ The schema and CRUD plumbing are in place; the loader bridges the new shape
301+ into the existing ` RecipeConfig ` consumed by the shared drivers. The following
302+ are exposed in the schema or implied by the design but not yet wired end to
303+ end, and are tracked as follow-ups:
304+
305+ - ** Delete protection.** Config resources can currently be deleted while still
306+ referenced by an environment. The intended behavior is to return
307+ ` 409 Conflict ` if any environment references the config (the same pattern
308+ used by RecipePacks).
309+ - ** ` referencedBy ` .** The read-only ` referencedBy: string[] ` property is in
310+ the schema but not populated by any controller.
311+ - ** Bicep ` AzureWI ` / ` AwsIrsa ` .** The ` BicepRegistryAuthentication ` schema
312+ accepts all three authentication methods, but the loader only threads
313+ ` BasicAuth ` (via ` basicAuthSecretId ` ) into the existing Bicep driver shape.
314+ Identity-based methods are no-ops until corresponding driver work lands.
315+ - ** Terraform ` credentials ` for OCI/registry hosts.** ` terraformrc.credentials `
316+ is mapped into the legacy ` Authentication.Git.PAT ` map so existing Git-based
317+ module source auth continues to work. A native ` credentials "hostname" {} `
318+ block in the rendered ` .terraformrc ` is a follow-up.
0 commit comments