Skip to content

Direct-module Bicep recipes fail on AVM telemetry (Microsoft.Resources/deployments) at location "global"; require enableTelemetry: false workaround #12280

Description

@willdavsmith

Summary

Direct-module Bicep recipes (#11876) fail to deploy a standard Azure Verified Module (AVM) unless the recipe author explicitly sets enableTelemetry: false on the module. AVMs include, by default (enableTelemetry defaults to true), a nested Microsoft.Resources/deployments "telemetry" resource, and the Radius Bicep deployment path cannot process that nested deployment because the recipe is deployed into the Radius/UCP plane whose location is global.

This is currently worked around in every AVM-backed recipe, but the workaround is non-obvious, easy to forget, and impossible to apply to modules that don't expose such a toggle.

What's an AVM telemetry resource?

Every Azure Verified Module ships a usage-telemetry block, gated on a module parameter that defaults to true:

@description('Optional. Enable/Disable usage telemetry for module.')
param enableTelemetry bool = true

#disable-next-line no-deployments-resources
resource avmTelemetry 'Microsoft.Resources/deployments@2024-03-01' = if (enableTelemetry) {
  name: take('46d3xbcp.res.dbformysql-flexibleserver.${...}.${substring(uniqueString(deployment().name, location), 0, 4)}', 64)
  properties: {
    mode: 'Incremental'
    template: { '$schema': '...', contentVersion: '1.0.0.0', resources: [], outputs: {...} }
  }
}

It is an empty nested deployment Microsoft uses to count module usage (the "pid-" partner ID). It deploys no real resources.

Repro

  1. Point a Radius.Core/recipePacks recipe at any AVM via the direct-module feature, without setting enableTelemetry: false, e.g.:
    'Radius.Data/mySqlDatabases': {
      kind: 'bicep'
      source: 'mcr.microsoft.com/bicep/avm/res/db-for-my-sql/flexible-server:0.10.3'
      parameters: {
        name: serverName
        // ... no enableTelemetry override ...
      }
      outputs: { host: 'fqdn' }
    }
  2. rad deploy a resource of that type.
  3. The deployment fails while processing the AVM's nested Microsoft.Resources/deployments telemetry resource at location global.

Setting enableTelemetry: false on the module parameters makes the deployment succeed.

Root cause (as we understand it)

The direct-module recipe template is submitted through the Bicep driver into the Radius/UCP plane, not directly to Azure:

  • NewDefaultProviderConfig (pkg/sdk/clients/providerconfig.go) routes the Deployments provider (ProviderTypeDeployments = "Microsoft.Resources") — which owns nested Microsoft.Resources/deployments resources — to constructRadiusDeploymentScope(resourceGroup), i.e. a /planes/radius/local/resourceGroups/... scope, not the Azure provider scope.
  • The Radius/UCP plane's location is v1.LocationGlobal = "global" (pkg/armrpc/api/v1/location.go:21).
  • Azure resources declared by the AVM are projected out to the real Azure RG via the Azure provider scope (newProviderConfig in pkg/recipes/driver/bicep/bicep.go), but the AVM's telemetry resource is a Microsoft.Resources/deployments — so it is handled by the Radius deployment engine in the global-location UCP resource group, where it cannot be processed (the nested deployment references location and is not a projectable cloud resource).

Net: any nested Microsoft.Resources/deployments inside a direct-module template hits this path. AVM telemetry is the common case because it is on by default in every AVM.

Note: we set enableTelemetry: false proactively (per AVM guidance and this limitation), so the exact deployment-engine error string isn't captured here — the repro above reproduces it. Happy to attach engine logs if useful.

Impact

  • Every AVM-backed direct-module recipe must remember enableTelemetry: false. A recipe author who omits it gets a confusing failure that has nothing to do with their resource.
  • Modules that don't expose a telemetry/opt-out toggle can't be used as direct modules at all — there's no way to suppress the nested deployment from the recipe.
  • More broadly, any module that legitimately uses a nested Microsoft.Resources/deployments (not just telemetry) is unsupported through direct modules today.

Current workaround

In radius-project/resource-types-verification — which verifies resource types against real clouds via direct modules — all four AVM recipes (PostgreSQL + MySQL, base and app-connection variants) set:

// AVM modules emit a Microsoft.Resources/deployments telemetry resource the
// Radius Bicep deployment engine can't process at location "global".
enableTelemetry: false

Proposed solutions (options)

  1. Skip/no-op nested Microsoft.Resources/deployments telemetry resources in the Bicep recipe path (e.g. recognize and drop the AVM "pid-" telemetry deployment, or any nested deployment that declares no projectable cloud resources). Lowest-risk, targeted.
  2. Propagate a valid location to the Radius-plane deployment context (e.g. the environment's Azure provider location) so nested deployments that reference location resolve to a real region instead of global.
  3. Fully support nested Microsoft.Resources/deployments in the deployment engine for direct modules (they are valid ARM), including the global-location case.
  4. (Weakest) Document enableTelemetry: false as a required pattern for AVMs — a band-aid that doesn't help modules lacking the toggle.

Recommend (1) or (2): they remove the footgun without requiring recipe authors to know about it, and unblock modules that don't expose a telemetry switch.

Affected files

  • pkg/recipes/driver/bicep/bicep.go — direct-module recipe driver / provider config construction.
  • pkg/sdk/clients/providerconfig.go — NewDefaultProviderConfig (Deployments provider → Radius-plane scope).
  • pkg/armrpc/api/v1/location.go — LocationGlobal.
  • Deployment engine nested-Microsoft.Resources/deployments handling.

Additional context

  • Direct module support for Recipes — Direct module support for Recipes #11876.
  • Surfaced by the resource-types-verification effort, which also surfaced the parameter-resolver nesting gap (single-level ternary) and the secret-injection work (x-radius-secret-binding).

Activity

  1. radius-triage commented on Jul 6, 2026

    @radius-triage

    👍 We've reviewed this issue and have agreed to add it to our backlog. Please subscribe to this issue for notifications, we'll provide updates when we pick it up.

    We also welcome community contributions! If you would like to pick this item up sooner and submit a pull request, please visit our contribution guidelines and assign this to yourself by commenting "/assign" on this issue.

    For more information on our triage process please visit our triage overview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triagedThis issue has been reviewed and triaged

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions