You've successfully subscribed to Florin Loghiade
Great! Next, complete checkout for full access to Florin Loghiade
Welcome back! You've successfully signed in
Success! Your account is fully activated, you now have access to all content.

Creating custom RBAC roles in Azure Resource Manager

in

clip_image001
These days I was doing some Azure work for a customer and I was asked if it was possible to create multiple custom RBAC roles for their Azure subscription because the existing ones don’t suit their needs. So I rubbed my hands together and said to client that’s a definite yes and to let me know the requirements so I can start working on the new roles ?

Creating Custom RBAC roles in Azure is very easy and you only need a bit of patience and Owner/Subscription admin role on the subscription.

You need to have the Owner/Subscription Admin role because only those roles have access to the provider “Microsoft Authorization/write” operation so if you have a contributor role on your subscription then you need get owner status or give the .json file that you will create to the person that has that specific role.

roledefinitionowner

Microsoft Authorization/write provider operation is used for multiple subscription administrative tasks and that’s why it’s not available on lower ranks of RBAC roles. One of those operations that can be enforced / removed are Resource Locks that are put in place so that nobody on the subscription can remove or edit resources in a Resource Group.

The only way to create / delete / manage Custom RBAC roles is via Azure PowerShell so make sure that you have the latest version of the cmdlets installed ?

Creating a RBAC role starts first by getting a list of roles that are available on your subscription.

Get-AzureRmRoleDefinition | Select-Object Name, Description | Format-Table

Once you’ve decided which role you want to start with, you then need to save it as a JSON (JavaScript Object Notation) file and then open up your favorite editor and start adding/removing access.

In this example I’m going to export the Automation Operator role definition:

Get-AzureRmRoleDefinition -Name 'Automation Operator' | ConvertTo-Json | Out-File 'g:\automatioOoperator.json'

This is what’s in the file:

{
    "Name":  "Automation Operator",
    "Id":  "d3881f73-407a-4167-8283-e981cbba0404",
    "IsCustom":  false,
    "Description":  "Automation Operators are able to start, stop, suspend, and resume jobs",
    "Actions":  [
                    "Microsoft.Authorization/*/read",
                    "Microsoft.Automation/automationAccounts/jobs/read",
                    "Microsoft.Automation/automationAccounts/jobs/resume/action",
                    "Microsoft.Automation/automationAccounts/jobs/stop/action",
                    "Microsoft.Automation/automationAccounts/jobs/streams/read",
                    "Microsoft.Automation/automationAccounts/jobs/suspend/action",
                    "Microsoft.Automation/automationAccounts/jobs/write",
                    "Microsoft.Automation/automationAccounts/jobSchedules/read",
                    "Microsoft.Automation/automationAccounts/jobSchedules/write",
                    "Microsoft.Automation/automationAccounts/read",
                    "Microsoft.Automation/automationAccounts/runbooks/read",
                    "Microsoft.Automation/automationAccounts/schedules/read",
                    "Microsoft.Automation/automationAccounts/schedules/write",
                    "Microsoft.Insights/alertRules/*",
                    "Microsoft.ResourceHealth/availabilityStatuses/read",
                    "Microsoft.Resources/deployments/*",
                    "Microsoft.Resources/subscriptions/resourceGroups/read",
                    "Microsoft.Support/*"
                ],
    "NotActions":  [

                   ],
    "AssignableScopes":  [
                             "/"
                         ]
}

Now that we know what the standard Automation Operations Role Definition looks like, how do we modify it to suit our needs?

First things first. We have a set of Keys that need to be modified:

Name – We need to give a name to the custom role.
ID – Remove this as you won’t need it.
isCustom – Set this to true. If you remove is custom entirely then it will be auto set to true.
Description – Write short description of what the role allows the user to do.
Actions – This array is filled with provider operations that the custom role with be able to do.
NotActions – This array is filled with provider operations that the custom role is not able to do.
AssignableScopes– This array can contain Subscriptions, Resource Groups or Resources

Actions

The Actions key contains an array of strings that contain provider operations that are available to the custom role you’re building. These operations can contain wildcards (*) which will grant access to all operations that match it.
Example:
Microsoft.Resources/deployments/* – Grants access to all providers of type Resource Deployment.
resourcedeployments
Microsoft.Authorization/*/read – Grants access to read operations on all the child objects under Microsoft.Authorization provider./
authorizationread

In order to get a list of provider operations you will need to use the Get-AzureRmProviderOperation cmdlet

Get-AzureRmProviderOperation Microsoft.Authorization/*/read| Format-Table Operation, OperationName, Description
Get-AzureRmProviderOperation * | Format-Table Operation, OperationName, Description

NotActions

The NotAction key is used to better define the operations that the role will not have access to. This is not a deny action that trumps everything, it’s just an exclusion filter. If the user that will be granted this role receives a secondary role that grants him access to an excluded operation specified in the first role then he will be able to perform that operation.

You can specify NotActions in the same as you specify Actions.

AssignableScopes

The AssignableScopes key specifies where this custom role will be available to use. In this array of strings block, you can specify Subscription IDs, Resource Groups or resources that the custom role will grant access to.

This is a mandatory field and you have define at least one scope otherwise you will get a strange error that you do not have access to the provider operation Microsoft.Authorization/roleDefinitions/write even though you are the sole owner of that subscription.

Here are some examples of what you can populate the field with:

“/subscriptions/22318efa-ef99-45e3-b52f-280e3389c9b3” – Grants access to a specific subscription. If you want more than one subscriptions to have this custom role then separate them with commas.
“/subscriptions/22318efa-ef99-45e3-b52f-280e3389c9b3/resourceGroups/TestResourceGroup” – Grants access to a specific resource group.
“/subscriptions/22318efa-ef99-45e3-b52f-280e3389c9b3/resourceGroups/AutomationAccounts/providers/Microsoft.Automation/automationAccounts/AutomationAccount” – Grants access to a specific resource

Now that we know what each key in the exported JSON does, let’s start customizing the role.

Let’s say that for auditing purposes, I want a custom role that can be assigned to users in order to see what’s happening on all Automation account without the access to modify / delete anything. For that I already exporter the Automation Operator RBAC role and I will now start customizing it.

I run the Get-AzureRmProviderOperation cmdlet with the operation name Microsoft.Automation/automationAccounts/*/read and see the results.

resourceproviderautomation

From the start I realize that I cannot get away with it assigning Microsoft.Automation/automationAccounts/*/read because it grants the role read access to the automation accounts assets, specifically to certificates, connections and credentials. So it’s a no go.

So let’s start populating the Actions array of strings which should look something like this:

    "Actions":  [
                    "Microsoft.Automation/automationAccounts/read",
                    "Microsoft.Automation/automationAccounts/jobs/read",
                    "Microsoft.Automation/automationAccounts/jobs/streams/read",
                    "Microsoft.Automation/automationAccounts/runbooks/read",
                    "Microsoft.Automation/automationAccounts/hybridRunbookWorkerGroups/read",
                    "Microsoft.Automation/automationAccounts/jobSchedules/read",
                    "Microsoft.Automation/automationAccounts/connectionTypes/read",     
                    "Microsoft.Automation/automationAccounts/modules/read",                  
                    "Microsoft.Automation/automationAccounts/schedules/read",          
                    "Microsoft.Automation/automationAccounts/runbooks/draft/read",
                    "Microsoft.Automation/automationAccounts/runbooks/draft/testJob/read",   
                    "Microsoft.Automation/automationAccounts/webhooks/read"    
                ],

Looks good, now let’s set the AssignableScopes array of strings to three of our subscriptions:

    "AssignableScopes":  [
                            "/subscriptions/6357a48d-3ae9-463e-9b9e-5de6997c8d48/",
                            "/subscriptions/28bbf7b3-f036-482f-b909-4f9eb06048ab/",
                            "/subscriptions/22318efa-ef99-45e3-b52f-280e3389c9b3/"
                             
                         ]

Ok, let’s set the Name, Description and isCustom property and we’re done. Here’s the end result:

{
    "Name":  "Automation Reader",
    "IsCustom":  true,
    "Description":  "Role that grants a user read access to the Automations Account resources",
    "Actions":  [
                    "Microsoft.Automation/automationAccounts/read",
                    "Microsoft.Automation/automationAccounts/jobs/read",
                    "Microsoft.Automation/automationAccounts/jobs/streams/read",
                    "Microsoft.Automation/automationAccounts/runbooks/read",
                    "Microsoft.Automation/automationAccounts/hybridRunbookWorkerGroups/read",
                    "Microsoft.Automation/automationAccounts/jobSchedules/read",
                    "Microsoft.Automation/automationAccounts/connectionTypes/read",     
                    "Microsoft.Automation/automationAccounts/modules/read",                  
                    "Microsoft.Automation/automationAccounts/schedules/read",          
                    "Microsoft.Automation/automationAccounts/runbooks/draft/read",
                    "Microsoft.Automation/automationAccounts/runbooks/draft/testJob/read",   
                    "Microsoft.Automation/automationAccounts/webhooks/read"   
                ],
    "NotActions":  [

                   ],
    "AssignableScopes":  [
                            "/subscriptions/6357a48d-3ae9-463e-9b9e-5de6997c8d48/",
                            "/subscriptions/28bbf7b3-f036-482f-b909-4f9eb06048ab/",
                            "/subscriptions/22318efa-ef99-45e3-b52f-280e3389c9b3/"
                             
                         ]
}

Now all we have to do is to save file .json file and create a new custom RBAC role. For job this we will use the New-AzureRmRoleDefinition cmdlet that will point to the newly created json file.

New-AzureRmRoleDefinition -InputFile G:\automationReader.json

newroledefinition

Now you’re done ? The new custom role has been successfully created and can now be assigned to your users.

Hope this will of some use. Have a good one!