Skip to content

Bicep authoring: drop the .properties. envelope by honoring x-ms-client-flatten #12000

@willdavsmith

Description

@willdavsmith

Problem

Every Radius Bicep resource currently requires a .properties. envelope to access the fields users actually care about. For example:

gateway.properties.url
frontendContainer.properties.container.ports.web.port
redis.properties.hostName
udtpgexisting.properties.host

This indirection appears in 17+ Bicep test/sample files in this repo and in every Bicep template a user writes against Radius resources. It is a direct ergonomic tax on the authoring experience.

Why this happens

Radius follows the ARM resource envelope pattern. Every resource has a standard envelope:

{
  "id": "...",
  "name": "...",
  "type": "...",
  "properties": {
    // user-defined fields live here
    "container": { ... },
    "connections": { ... }
  }
}

This shape is defined once in typespec/radius/v1/trackedresource.tsp:

model TrackedResourceRequired<TProperties, ...>
  extends Azure.ResourceManager.Foundations.TrackedResource {
  @extension("x-ms-client-flatten", true)   // <-- intended to flatten
  properties: TProperties;
}

Every Radius resource derives from TrackedResourceRequired, so every resource carries an x-ms-client-flatten: true annotation on its properties field.

ARM SDK generators (Go, C#) honor x-ms-client-flatten and hoist the inner fields onto the parent type. The Radius Bicep type generator (hack/bicep-types-radius/src/autorest.bicep/src/type-generator.ts) does not implement this flattening — it emits properties as a nested object, which is what surfaces as .properties. in user-authored Bicep.

Impact

  • Every Radius resource access in Bicep is one level deeper than necessary.
  • The pattern is non-obvious: users frequently ask why .properties. is required, and the answer ("ARM envelope artifact") is not a Radius design choice.
  • Inconsistent with the Radius SDKs (Go/C#), which already flatten.
  • Documentation, samples, and tests all pay the cost.

Proposed fix

Implement x-ms-client-flatten in the Bicep type generator. The annotation is already present on every Radius resource; the generator just needs to respect it. Flatten safely:

  • Skip (with a warning) when the schema uses a discriminator (polymorphic variants), since flattening would lose variant disambiguation.
  • Skip (with a warning) when a flattened child name would collide with an existing parent property.
  • Propagate ReadOnly/WriteOnly flags from the parent to flattened children.

After this change, users will write:

gateway.url
frontendContainer.container.ports.web.port
redis.hostName

Alternatives considered

# Option Notes
1 Implement x-ms-client-flatten in the Bicep type generator (this proposal) Medium effort, high impact, fixes it for every resource.
2 Upstream the fix to bicep-types-az Low effort to file, but blocks on upstream review/release.
3 Output helper modules that re-export common fields Medium effort, partial fix only.
4 Document the pattern in Radius docs Low effort, doesn't fix the UX.

Option 1 is the most impactful and is self-contained to this repository.

Related work

A PR implementing Option 1 will be linked to this issue.

Metadata

Metadata

Assignees

Labels

triagedThis issue has been reviewed and triaged

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions