The Ops Community ⚙️

Cover image for Find the suitable Azure Role Definition for an Assignment
Kai Walter
Kai Walter

Posted on • Edited on

Find the suitable Azure Role Definition for an Assignment

Motivation

Managing Role Based Access Control (RBAC) authorizations for some of our major platforms I am often faced with the challenge to find the suitable role to be assigned based on error messages or fragments of information.

In this post I want to share how I approach this.

Azure PowerShell - Get-AzRoleDefinition

This Cmdlet can be used to to query a single role definition:

> Get-AzRoleDefinition -Name "Cosmos DB Account Reader Role"
Name             : Cosmos DB Account Reader Role
Id               : fbdf93bf-df7d-467e-a4d2-9458aa1360c8
IsCustom         : False
Description      : Can read Azure Cosmos DB Accounts data
Actions          : {Microsoft.Authorization/*/read, Microsoft.DocumentDB/*/read, Microsoft.DocumentDB/databaseAccounts/readonlykeys/action, Microsoft.Insights/MetricDefinitions/read…}
NotActions       : {}
DataActions      : {}
NotDataActions   : {}
AssignableScopes : {/}
Enter fullscreen mode Exit fullscreen mode

It can also be used to query all Azure provisioned and custom role definitions.

If you want to find a role where a fragment of Actions you want to assign is contained a filter on Actions helps narrowing down:

> Get-AzRoleDefinition | %{$_.Actions -match "DocumentDB/"}
Microsoft.DocumentDB/databaseAccounts/backup/action
Microsoft.DocumentDB/databaseAccounts/restore/action
Microsoft.DocumentDB/*/read
Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/restore/action
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/*/read
Microsoft.DocumentDB/locations/restorableDatabaseAccounts/read
Enter fullscreen mode Exit fullscreen mode

With that the role definition name is lost, which contains actions found.

Conserving role definitions name for output with Get-AzRoleDefinition | %{$rd=$_;$rd.Name;$rd.Actions -match "DocumentDB/"} shows all role definitions with actions, when those match. But we want only see role definitions, which contain matched actions.

First checking whether actions were found, output could be limited like:

> Get-AzRoleDefinition | %{$rd = $_;($rd.Actions -match "DocumentDB/").Count|?{$_ -gt 0}|%{"="*80;$rd.Name;$rd|Select-Object -ExpandProperty Actions}}
================================================================================
CosmosBackupOperator
Microsoft.DocumentDB/databaseAccounts/backup/action
Microsoft.DocumentDB/databaseAccounts/restore/action
================================================================================
Cosmos DB Account Reader Role
Microsoft.Authorization/*/read
Microsoft.DocumentDB/*/read
Microsoft.DocumentDB/databaseAccounts/readonlykeys/action
Microsoft.Insights/MetricDefinitions/read
Microsoft.Insights/Metrics/read
Microsoft.Resources/subscriptions/resourceGroups/read
Microsoft.Support/*
================================================================================
DocumentDB Account Contributor
Microsoft.Authorization/*/read
Microsoft.DocumentDb/databaseAccounts/*
Microsoft.Insights/alertRules/*
Microsoft.ResourceHealth/availabilityStatuses/read
...
Enter fullscreen mode Exit fullscreen mode

which leads to the small PowerShell script findAzRoleDefinition.ps1 I regularly use

[CmdletBinding()]
param (
    [Parameter(Mandatory=$true,Position=1)]
    [string]
    $Term
)

Get-AzRoleDefinition | %{$rd = $_;($rd.Actions -match $Term).Count|?{$_ -gt 0}|%{"="*80;$rd.Name;$rd|Select-Object -ExpandProperty Actions}}
Enter fullscreen mode Exit fullscreen mode

which I then pipe into an editor like VS Code: findRoleDefinition.ps1 "Microsoft.Storage/storageAccounts" | code -

Azure CLI - az role definition

If you prefer Azure CLI a search for a fragment of a role definition action directly can be achieved with JMESPath. Challenge is that actions are nested in another array:

...
    "permissions": [
      {
        "actions": [
          "Microsoft.DocumentDB/databaseAccounts/backup/action",
          "Microsoft.DocumentDB/databaseAccounts/restore/action"
        ],
        "dataActions": [],
        "notActions": [],
        "notDataActions": []
      }
    ],
...
Enter fullscreen mode Exit fullscreen mode

As I did not figure out how to make the nested arrays permissions and actions searchable my approach currently only works for the assumption that there is only one entry in permissions. The process then has 2 steps

  1. filter role definitions for actions containing the searched string fragment
  2. piping the determined role definition names to another step which renders the complete role definition

Piped with PowerShell:

az role definition list --query "[].{name:name,a:join('|', permissions[0].actions)} | [?contains(a, 'DocumentDB/')].name" -o tsv | %{az role definition list -n $_}
Enter fullscreen mode Exit fullscreen mode

Piped with Bash:

az role definition list --query "[].{name:name,a:join('|', permissions[0].actions)} | [?contains(a, 'DocumentDB/')].name" -o tsv | xargs -i az role definition list -n {}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)