Skip to content

Bug: roleDefinitions() function fails during ARM WhatIf but succeeds on real deployment #19507

@MDAG21

Description

@MDAG21

Summary

The roleDefinitions() Bicep function compiles correctly to ARM JSON and deploys successfully, but the ARM WhatIf API rejects it with The template function 'roleDefinitions' is not valid. This makes it impossible to use roleDefinitions() in any template that uses WhatIf previews (including the New-AzResourceGroupDeployment -WhatIf flag and az deployment group what-if).

Bicep Version

0.42.1.51946

Repro Steps

1. Create a minimal Bicep template

// test-roledefinitions.bicep
targetScope = 'resourceGroup'

param roleDefinitionName string = 'Contributor'

output id string = roleDefinitions(roleDefinitionName).id
output roleDefinitionId string = roleDefinitions(roleDefinitionName).roleDefinitionId

2. Create a parameters file

// test-roledefinitions.bicepparam
using './test-roledefinitions.bicep'

param roleDefinitionName = 'Contributor'

3. Build the template (succeeds)

bicep build test-roledefinitions.bicep

Compiled ARM output (abbreviated):

{
  "outputs": {
    "id": {
      "type": "string",
      "value": "[roleDefinitions(parameters('roleDefinitionName')).id]"
    },
    "roleDefinitionId": {
      "type": "string",
      "value": "[roleDefinitions(parameters('roleDefinitionName')).roleDefinitionId]"
    }
  }
}

4. Real deployment (succeeds ✅)

New-AzResourceGroupDeployment `
  -ResourceGroupName 'my-rg' `
  -TemplateParameterFile 'test-roledefinitions.bicepparam' `
  -Name 'test-deploy'

Output:

ProvisioningState : Succeeded
Outputs           : {id, roleDefinitionId}

id               = /subscriptions/<sub-id>/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c
roleDefinitionId = b24988ac-6180-42a0-ab88-20f7382dd24c

5. WhatIf via PowerShell Az module (fails ❌)

New-AzResourceGroupDeployment `
  -ResourceGroupName 'my-rg' `
  -TemplateParameterFile 'test-roledefinitions.bicepparam' `
  -Name 'test-deploy' `
  -WhatIf `
  -ErrorAction Stop

Error:

New-AzResourceGroupDeployment:
InvalidTemplate - Long running operation failed with status 'Failed'.
Additional Info: 'Deployment template language expression evaluation failed:
'The template function 'roleDefinitions' is not valid.
Please see https://aka.ms/arm-functions for usage details.'.
Please see https://aka.ms/arm-functions for usage details.'

6. WhatIf via Azure CLI (fails ❌)

az deployment group what-if \
  --resource-group my-rg \
  --parameters test-roledefinitions.bicepparam

Error:

ERROR: InvalidTemplate - Deployment template language expression evaluation failed:
'The template function 'roleDefinitions' is not valid.
Please see https://aka.ms/arm-functions for usage details.'.
Please see https://aka.ms/arm-functions for usage details.

Expected Behaviour

roleDefinitions() is a GA Bicep function. WhatIf should evaluate it successfully the same way a real deployment does — or at minimum, skip evaluation of ARM-layer functions it cannot resolve and continue with the rest of the WhatIf analysis.

Actual Behaviour

The ARM WhatIf API rejects the compiled template with The template function 'roleDefinitions' is not valid, blocking the entire WhatIf operation. The same template deploys successfully without -WhatIf.

Environment

Property Value
Bicep version 0.42.1.51946
Az PowerShell module 15.x (self-hosted agent)
Azure CLI version tested on latest
Deployment scope resourceGroup
Template input .bicepparam file (compiled to ARM JSON by bicep build)

Impact

Any Bicep template that uses roleDefinitions() for role assignments (a common, idiomatic pattern) will fail the WhatIf step in CI/CD pipelines, making it impossible to use WhatIf previews without reverting to the lower-level subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '<guid>') workaround.

Workaround

Replace roleDefinitions() with the older subscriptionResourceId pattern:

// Instead of:
roleDefinitionId: roleDefinitions('Contributor').id

// Use:
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')

This works in both real deployment and WhatIf, but defeats the purpose of the roleDefinitions() function.

Related Links

Metadata

Metadata

Assignees

Type

No type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions