Creating a Complex Custom Azure Role

We recently had the need to create a custom role in the Azure Portal which stopped a set of administrators from creating networks or virtual machines.

This was because we are planning to share our ExpressRoute connection with their subscription and we only allow IT to add new devices to our network or domain.

Now the standard Azure RBAC roles don't do anything like this.  These roles are typically configured with only a small set of permissions.

The role needed the following setup

Allow All
Allow start, stop, deallocate VM
Deny All Compute
Deny All Network
Deny All Permissions

The following article was pretty useful in describing the process of creating the custom role.  There are a few methods, but I opted for the creation of the JSON file.

To get the actual permissions required to build the JSON file itself, we needed to run the following commands

Get-AzureRMProviderOperation Microsoft.Compute/*
Get-AzureRMProviderOperation Microsoft.Network/*

Output in Powershell

This produced a list of all of the operations which can be allowed or denied.  I needed to export this to ensure I allowed the administrators to be able to start, stop and deallocate VMs.

The following items are the permissions we want to allow the users to have.

Operation         : Microsoft.Compute/virtualMachines/read
OperationName     : Get Virtual Machine
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machines
Description       : Get the properties of a virtual machine

Operation         : Microsoft.Compute/virtualMachines/start/action
OperationName     : Start Virtual Machine
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machines
Description       : Starts the virtual machine

Operation         : Microsoft.Compute/virtualMachines/powerOff/action
OperationName     : Power Off Virtual Machine
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machines
Description       : Powers off the virtual machine. Note that the virtual machine will continue to be billed.

Operation         : Microsoft.Compute/virtualMachines/restart/action
OperationName     : Restart Virtual Machine
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machines
Description       : Restarts the virtual machine

Operation         : Microsoft.Compute/virtualMachines/deallocate/action
OperationName     : Deallocate Virtual Machine
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machines
Description       : Powers off the virtual machine and releases the compute resources

Operation         : Microsoft.Compute/virtualMachines/instanceView/read
OperationName     : Get Virtual Machine Instance View
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machine Instance View
Description       : Gets the detailed runtime status of the virtual machine and its resources

Operation         : Microsoft.Compute/locations/vmSizes/read
OperationName     : List Available Virtual Machine Sizes in Location
ProviderNamespace : Microsoft Compute
ResourceName      : Virtual Machine Sizes
Description       : Lists available virtual machine sizes in a location

There were a few more than originally intended e.g. Instance view, list sizes etc.  We remove these entries from the Output, filter just on Operation and copy these items into the NotActions section of the JSON file.

The next step was to create a JSON file.  The * in Actions allows all permissions and then we use the NotActions to Deny Operation permissions.
{
  "Name": "BI administrator",
  "Id": "null",
  "IsCustom": true,
  "Description": "Can do everything other than create virtual machines and manage networking.",
  "Actions": ["*"
  ],
  "NotActions": [
"Microsoft.Compute/availabilitySets/delete",
"Microsoft.Compute/availabilitySets/read",
"Microsoft.Compute/availabilitySets/vmSizes/read",
"Microsoft.Compute/availabilitySets/write",
"Microsoft.Compute/disks/beginGetAccess/action",
"Microsoft.Compute/disks/delete",
"Microsoft.Compute/disks/endGetAccess/action",
"Microsoft.Compute/disks/read",
"Microsoft.Compute/disks/write",
"Microsoft.Compute/images/delete",
"Microsoft.Compute/images/read",
"Microsoft.Compute/images/write",
"Microsoft.Compute/locations/diskOperations/read",
"Microsoft.Compute/locations/operations/read",
"Microsoft.Compute/locations/runCommands/read",
"Microsoft.Compute/locations/usages/read",
"Microsoft.Compute/operations/read",
"Microsoft.Compute/register/action",
"Microsoft.Compute/restorePointCollections/delete",
"Microsoft.Compute/restorePointCollections/read",
"Microsoft.Compute/restorePointCollections/restorePoints/delete",
"Microsoft.Compute/restorePointCollections/restorePoints/read",
"Microsoft.Compute/restorePointCollections/restorePoints/retrieveSasUris/action",
"Microsoft.Compute/restorePointCollections/restorePoints/write",
"Microsoft.Compute/restorePointCollections/write",
"Microsoft.Compute/snapshots/beginGetAccess/action",
"Microsoft.Compute/snapshots/delete",
"Microsoft.Compute/snapshots/endGetAccess/action",
"Microsoft.Compute/snapshots/read",
"Microsoft.Compute/snapshots/write",
"Microsoft.Compute/virtualMachineScaleSets/deallocate/action",
"Microsoft.Compute/virtualMachineScaleSets/delete",
"Microsoft.Compute/virtualMachineScaleSets/delete/action",
"Microsoft.Compute/virtualMachineScaleSets/extensions/delete",
"Microsoft.Compute/virtualMachineScaleSets/extensions/read",
"Microsoft.Compute/virtualMachineScaleSets/extensions/write",
"Microsoft.Compute/virtualMachineScaleSets/instanceView/read",
"Microsoft.Compute/virtualMachineScaleSets/manualUpgrade/action",
"Microsoft.Compute/virtualMachineScaleSets/powerOff/action",
"Microsoft.Compute/virtualMachineScaleSets/read",
"Microsoft.Compute/virtualMachineScaleSets/reimage/action",
"Microsoft.Compute/virtualMachineScaleSets/restart/action",
"Microsoft.Compute/virtualMachineScaleSets/rollingUpgrades/cancel/action",
"Microsoft.Compute/virtualMachineScaleSets/rollingUpgrades/read",
"Microsoft.Compute/virtualMachineScaleSets/scale/action",
"Microsoft.Compute/virtualMachineScaleSets/skus/read",
"Microsoft.Compute/virtualMachineScaleSets/start/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/deallocate/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/delete",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/instanceView/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/read",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/reimage/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachineScaleSets/virtualMachines/start/action",
"Microsoft.Compute/virtualMachineScaleSets/write",
"Microsoft.Compute/virtualMachines/capture/action",
"Microsoft.Compute/virtualMachines/convertToManagedDisks/action",
"Microsoft.Compute/virtualMachines/delete",
"Microsoft.Compute/virtualMachines/extensions/delete",
"Microsoft.Compute/virtualMachines/extensions/read",
"Microsoft.Compute/virtualMachines/extensions/write",
"Microsoft.Compute/virtualMachines/generalize/action",
"Microsoft.Compute/virtualMachines/performMaintenance/action",
"Microsoft.Compute/virtualMachines/redeploy/action",
"Microsoft.Compute/virtualMachines/runCommand/action",
"Microsoft.Compute/virtualMachines/write",
"Microsoft.Network/applicationGatewayAvailableWafRuleSets/read",
"Microsoft.Network/applicationGateways/backendAddressPools/join/action",
"Microsoft.Network/applicationGateways/backendhealth/action",
"Microsoft.Network/applicationGateways/delete",
"Microsoft.Network/applicationGateways/read",
"Microsoft.Network/applicationGateways/start/action",
"Microsoft.Network/applicationGateways/stop/action",
"Microsoft.Network/applicationGateways/write",
"Microsoft.Network/bgpServiceCommunities/read",
"Microsoft.Network/checkTrafficManagerNameAvailability/action",
"Microsoft.Network/connections/delete",
"Microsoft.Network/connections/read",
"Microsoft.Network/connections/sharedKey/read",
"Microsoft.Network/connections/sharedKey/write",
"Microsoft.Network/connections/vpndeviceconfigurationscript/read",
"Microsoft.Network/connections/write",
"Microsoft.Network/dnsoperationresults/read",
"Microsoft.Network/dnsoperationstatuses/read",
"Microsoft.Network/dnszones/A/delete",
"Microsoft.Network/dnszones/A/read",
"Microsoft.Network/dnszones/A/write",
"Microsoft.Network/dnszones/AAAA/delete",
"Microsoft.Network/dnszones/AAAA/read",
"Microsoft.Network/dnszones/AAAA/write",
"Microsoft.Network/dnszones/CNAME/delete",
"Microsoft.Network/dnszones/CNAME/read",
"Microsoft.Network/dnszones/CNAME/write",
"Microsoft.Network/dnszones/delete",
"Microsoft.Network/dnszones/MX/delete",
"Microsoft.Network/dnszones/MX/read",
"Microsoft.Network/dnszones/MX/write",
"Microsoft.Network/dnszones/NS/delete",
"Microsoft.Network/dnszones/NS/read",
"Microsoft.Network/dnszones/NS/write",
"Microsoft.Network/dnszones/PTR/delete",
"Microsoft.Network/dnszones/PTR/read",
"Microsoft.Network/dnszones/PTR/write",
"Microsoft.Network/dnszones/read",
"Microsoft.Network/dnszones/recordsets/read",
"Microsoft.Network/dnszones/SOA/read",
"Microsoft.Network/dnszones/SOA/write",
"Microsoft.Network/dnszones/SRV/delete",
"Microsoft.Network/dnszones/SRV/read",
"Microsoft.Network/dnszones/SRV/write",
"Microsoft.Network/dnszones/TXT/delete",
"Microsoft.Network/dnszones/TXT/read",
"Microsoft.Network/dnszones/TXT/write",
"Microsoft.Network/dnszones/write",
"Microsoft.Network/expressRouteCircuits/authorizations/delete",
"Microsoft.Network/expressRouteCircuits/authorizations/read",
"Microsoft.Network/expressRouteCircuits/authorizations/write",
"Microsoft.Network/expressRouteCircuits/delete",
"Microsoft.Network/expressRouteCircuits/peerings/arpTables/action",
"Microsoft.Network/expressRouteCircuits/peerings/delete",
"Microsoft.Network/expressRouteCircuits/peerings/read",
"Microsoft.Network/expressRouteCircuits/peerings/routeTables/action",
"Microsoft.Network/expressRouteCircuits/peerings/routeTablesSummary/action",
"Microsoft.Network/expressRouteCircuits/peerings/stats/read",
"Microsoft.Network/expressRouteCircuits/peerings/write",
"Microsoft.Network/expressRouteCircuits/read",
"Microsoft.Network/expressRouteCircuits/stats/read",
"Microsoft.Network/expressRouteCircuits/write",
"Microsoft.Network/expressRouteServiceProviders/read",
"Microsoft.Network/loadBalancers/backendAddressPools/join/action",
"Microsoft.Network/loadBalancers/backendAddressPools/read",
"Microsoft.Network/loadBalancers/delete",
"Microsoft.Network/loadBalancers/frontendIPConfigurations/read",
"Microsoft.Network/loadBalancers/inboundNatPools/join/action",
"Microsoft.Network/loadBalancers/inboundNatPools/read",
"Microsoft.Network/loadBalancers/inboundNatRules/delete",
"Microsoft.Network/loadBalancers/inboundNatRules/join/action",
"Microsoft.Network/loadBalancers/inboundNatRules/read",
"Microsoft.Network/loadBalancers/inboundNatRules/write",
"Microsoft.Network/loadBalancers/loadBalancingRules/read",
"Microsoft.Network/loadBalancers/networkInterfaces/read",
"Microsoft.Network/loadBalancers/outboundNatRules/read",
"Microsoft.Network/loadBalancers/probes/read",
"Microsoft.Network/loadBalancers/read",
"Microsoft.Network/loadBalancers/virtualMachines/read",
"Microsoft.Network/loadBalancers/write",
"Microsoft.Network/localnetworkgateways/delete",
"Microsoft.Network/localnetworkgateways/read",
"Microsoft.Network/localnetworkgateways/write",
"Microsoft.Network/locations/checkDnsNameAvailability/read",
"Microsoft.Network/locations/operationResults/read",
"Microsoft.Network/locations/operations/read",
"Microsoft.Network/locations/privateAccessServices/read",
"Microsoft.Network/locations/usages/read",
"Microsoft.Network/networkInterfaces/delete",
"Microsoft.Network/networkInterfaces/effectiveNetworkSecurityGroups/action",
"Microsoft.Network/networkInterfaces/effectiveRouteTable/action",
"Microsoft.Network/networkInterfaces/ipconfigurations/read",
"Microsoft.Network/networkInterfaces/join/action",
"Microsoft.Network/networkInterfaces/loadBalancers/read",
"Microsoft.Network/networkInterfaces/read",
"Microsoft.Network/networkInterfaces/write",
"Microsoft.Network/networkSecurityGroups/defaultSecurityRules/read",
"Microsoft.Network/networkSecurityGroups/delete",
"Microsoft.Network/networkSecurityGroups/join/action",
"Microsoft.Network/networkSecurityGroups/read",
"Microsoft.Network/networkSecurityGroups/securityRules/delete",
"Microsoft.Network/networkSecurityGroups/securityRules/read",
"Microsoft.Network/networkSecurityGroups/securityRules/write",
"Microsoft.Network/networkSecurityGroups/write",
"Microsoft.Network/networkWatchers/configureFlowLog/action",
"Microsoft.Network/networkWatchers/delete",
"Microsoft.Network/networkWatchers/ipFlowVerify/action",
"Microsoft.Network/networkWatchers/nextHop/action",
"Microsoft.Network/networkWatchers/packetCaptures/delete",
"Microsoft.Network/networkWatchers/packetCaptures/queryStatus/action",
"Microsoft.Network/networkWatchers/packetCaptures/read",
"Microsoft.Network/networkWatchers/packetCaptures/stop/action",
"Microsoft.Network/networkWatchers/packetCaptures/write",
"Microsoft.Network/networkWatchers/queryFlowLogStatus/action",
"Microsoft.Network/networkWatchers/queryTroubleshootResult/action",
"Microsoft.Network/networkWatchers/read",
"Microsoft.Network/networkWatchers/securityGroupView/action",
"Microsoft.Network/networkWatchers/topology/action",
"Microsoft.Network/networkWatchers/troubleshoot/action",
"Microsoft.Network/networkWatchers/write",
"Microsoft.Network/operations/read",
"Microsoft.Network/publicIPAddresses/delete",
"Microsoft.Network/publicIPAddresses/join/action",
"Microsoft.Network/publicIPAddresses/read",
"Microsoft.Network/publicIPAddresses/write",
"Microsoft.Network/register/action",
"Microsoft.Network/routeFilters/delete",
"Microsoft.Network/routeFilters/join/action",
"Microsoft.Network/routeFilters/read",
"Microsoft.Network/routeFilters/rules/delete",
"Microsoft.Network/routeFilters/rules/read",
"Microsoft.Network/routeFilters/rules/write",
"Microsoft.Network/routeFilters/write",
"Microsoft.Network/routeTables/delete",
"Microsoft.Network/routeTables/join/action",
"Microsoft.Network/routeTables/read",
"Microsoft.Network/routeTables/routes/delete",
"Microsoft.Network/routeTables/routes/read",
"Microsoft.Network/routeTables/routes/write",
"Microsoft.Network/routeTables/write",
"Microsoft.Network/trafficManagerGeographicHierarchies/read",
"Microsoft.Network/trafficManagerProfiles/azureEndpoints/delete",
"Microsoft.Network/trafficManagerProfiles/azureEndpoints/read",
"Microsoft.Network/trafficManagerProfiles/azureEndpoints/write",
"Microsoft.Network/trafficManagerProfiles/delete",
"Microsoft.Network/trafficManagerProfiles/externalEndpoints/delete",
"Microsoft.Network/trafficManagerProfiles/externalEndpoints/read",
"Microsoft.Network/trafficManagerProfiles/externalEndpoints/write",
"Microsoft.Network/trafficManagerProfiles/nestedEndpoints/delete",
"Microsoft.Network/trafficManagerProfiles/nestedEndpoints/read",
"Microsoft.Network/trafficManagerProfiles/nestedEndpoints/write",
"Microsoft.Network/trafficManagerProfiles/read",
"Microsoft.Network/trafficManagerProfiles/write",
"Microsoft.Network/unregister/action",
"Microsoft.Network/virtualnetworkgateways/supportedvpndevices/read",
"Microsoft.Network/virtualNetworks/checkIpAddressAvailability/read",
"Microsoft.Network/virtualNetworks/delete",
"Microsoft.Network/virtualNetworks/peer/action",
"Microsoft.Network/virtualNetworks/read",
"Microsoft.Network/virtualNetworks/subnets/delete",
"Microsoft.Network/virtualNetworks/subnets/join/action",
"Microsoft.Network/virtualNetworks/subnets/joinPrivateAccessService/action",
"Microsoft.Network/virtualNetworks/subnets/joinViaServiceTunnel/action",
"Microsoft.Network/virtualNetworks/subnets/read",
"Microsoft.Network/virtualNetworks/subnets/virtualMachines/read",
"Microsoft.Network/virtualNetworks/subnets/write",
"Microsoft.Network/virtualNetworks/virtualMachines/read",
"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/delete",
"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/read",
"Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write",
"Microsoft.Network/virtualNetworks/write",
"Microsoft.Authorization/*/Delete", 
"Microsoft.Authorization/*/Write",
"Microsoft.Authorization/elevateAccess/Action"
 ],
  "AssignableScopes": [
    "/subscriptions/123456789-1234-1234-1234-123456789123",
  ]
}

You will notice the last three entries

"Microsoft.Authorization/*/Delete", 
"Microsoft.Authorization/*/Write",
"Microsoft.Authorization/elevateAccess/Action"

These will stop the administrator being able to change the permissions for themselves.  Clearly if I missed this, the whole exercise would be pointless!

If you want to use this JSON file, you will just need to replace the name, description and the subscription ID.

You will then need to create a new Role from the JSON file.  This article has more detail on how to do this, but the PowerShell command you will need to run is
New-AzureRmRoleDefinition -InputFile "C:\CustomRoles\customrole1.json"

Role in Azure Portal
And there you have it!  A custom Azure Role that can do nearly everything other than VMs, network and permissions.

Comments

Popular posts from this blog

Assigning Windows 10/11 Enterprise Subscription Activation Licences to Hybrid Azure AD Joined Devices

Power Automate: Get first item in output

De-selectable radio buttons - Power Apps