Skip to content

Commit 89d06e1

Browse files
committed
Update architecture doc to match implemented branch state
- Remove the Implementation plan section (superseded by actual code). - Replace the aspirational Delete protection section with a Status and known limitations section that lists what is wired vs. follow-ups. - Expand the Runtime flow to call out the .terraformrc rendering path added in pkg/recipes/terraform/cliconfig.go. - Add a Code map pointing at the relevant files.
1 parent 445cb9b commit 89d06e1

1 file changed

Lines changed: 71 additions & 63 deletions

File tree

‎docs/architecture/terraform-bicep-config.md‎

Lines changed: 71 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -150,20 +150,21 @@ graph LR
150150
1. Platform team deploys `terraformConfig` and/or `bicepConfig` resources.
151151
2. Platform team deploys an `environment` referencing them by resource ID.
152152
3. 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

Comments
 (0)