Create or update Azure custom roles using Bicep

If the Azure built-in roles don't meet the specific needs of your organization, you can create your own custom roles. This article describes how to create or update a custom role using Bicep.

Bicep is a domain-specific language (DSL) that uses declarative syntax to deploy Azure resources. It provides concise syntax, reliable type safety, and support for code reuse. Bicep offers the best authoring experience for your infrastructure-as-code solutions in Azure.

To create a custom role, you specify a role name, role permissions, and where the role can be used. In this article, you create a role named Custom Role - RG Reader with resource permissions that can be assigned at a subscription scope or lower.

Prerequisites

To create a custom role, you must have permissions to create custom roles, such as User Access Administrator.

You also must have an active Azure subscription. If you don't have one, you can create a free account before you begin.

Review the Bicep file

The Bicep file used in this article is from Azure Quickstart Templates. The Bicep file has four parameters and a resources section. The four parameters are:

  • Array of actions with a default value of ["Microsoft.Resources/subscriptions/resourceGroups/read"].
  • Array of notActions with an empty default value.
  • Role name with a default value of Custom Role - RG Reader.
  • Role description with a default value of Subscription Level Deployment of a Role Definition.

The scope where this custom role can be assigned is set to the current subscription.

A custom role requires a unique ID. The ID can be generated with the guid() function. Since a custom role also requires a unique display name for the tenant, you can use the role name as a parameter for the guid() function to create a deterministic GUID. A deterministic GUID is useful if you later need to update the custom role using the same Bicep file.

targetScope = 'subscription'

@description('Array of actions for the roleDefinition')
param actions array = [
  'Microsoft.Resources/subscriptions/resourceGroups/read'
]

@description('Array of notActions for the roleDefinition')
param notActions array = []

@description('Friendly name of the role definition')
param roleName string = 'Custom Role - RG Reader'

@description('Detailed description of the role definition')
param roleDescription string = 'Subscription Level Deployment of a Role Definition'

var roleDefName = guid(roleName)

resource roleDef 'Microsoft.Authorization/roleDefinitions@2022-04-01' = {
  name: roleDefName
  properties: {
    roleName: roleName
    description: roleDescription
    type: 'customRole'
    permissions: [
      {
        actions: actions
        notActions: notActions
      }
    ]
    assignableScopes: [
      subscription().id
    ]
  }
}

The resource defined in the Bicep file is:

Deploy the Bicep file

  1. Save the Bicep file as main.bicep to your local computer.

  2. Create a variable named myActions with the actions for the roleDefinition.

    $myActions='["Microsoft.Resources/subscriptions/resourceGroups/read"]'
    
  3. Deploy the Bicep file using either Azure CLI or Azure PowerShell.

    az deployment sub create --location eastus --name customRole --template-file ./main.bicep --parameters actions=$myActions
    

When the deployment finishes, you should see a message indicating the deployment succeeded.

Review deployed resources

Use the Azure portal, Azure CLI, or Azure PowerShell to verify that the custom role was created.

az role definition list --name "Custom Role - RG Reader"

Update a custom role

Similar to creating a custom role, you can update an existing custom role using Bicep. To update a custom role, you need to specify the role you want to update. If you previously created the custom role in Bicep with a unique role ID that is deterministic, you can use the same Bicep file and specify the custom role by just using the display name.

  1. Specify the updated actions.

    $myActions='["Microsoft.Resources/resources/read","Microsoft.Resources/subscriptions/resourceGroups/read"]'
    
  2. Use Azure CLI or Azure PowerShell to update the custom role.

    az deployment sub create --location eastus --name customrole --template-file ./main.bicep --parameters actions=$myActions roleName="Custom Role - RG Reader"
    

    Note

    It may take several minutes for the updated custom role to be propagated.

Clean up resources

When no longer needed, use the Azure portal, Azure CLI, or Azure PowerShell to remove the custom role.

az role definition delete --name "Custom Role - RG Reader"

Next steps