How to Define Azure Role-based Access Control (RBAC), Part Two
This guide covers how to combine role assignment and resource tagging with Powershell control flow to make hundreds of changes in a few lines of code.
Oct 26, 2020 • 5 Minute Read
Introduction
When your cloud infrastructure is large with dozens of apps and hundreds of users, managing all these permissions becomes difficult to maintain in a reproducible and transparent way. A previous guide, How to Define Azure Role-based Access Control (RBAC), covered the basic usage of role definition and assignment using the Azure CLI.
In this guide, you will build on those skills to learn how to combine role assignment and resource tagging in conjunction with Powershell control flow to make hundreds of changes in a few lines of code.
Using ForEach to Iterate Over Identities
Azure provides resource groups to help you manage and secure your apps and other protected resources. This allows you to group related resources together. One common pattern is to place all the resources in a single micro-service together. This may include an Azure App Service and the Storage account it uses to save its data.
In this pattern, each Azure App Service should only have permission to access the storage account within its resource group. To do this in Powershell, use the ForEach-Object Cmdlet to iterate over all your resource groups and the apps inside them.
# get all resource groups
$groups = az group list -o json | ConvertFrom-Json
# iterate over all resource groups
$groups | foreach {
$rg=$_.name
$rgid = $_.id
# get all apps inside a resource group and iterate over them
$apps=az webapp list -g $rg -o tsv --query "[].name"
$apps | foreach {
$app=$_
$id = az webapp identity assign -g $rg -n $app -o tsv --query "principalId"
az role assignment create --role "Storage Blob Data Contributor" --assignee $id --scope $rgid
# get the deployment slots if any
$slots = az webapp deployment slot list -g $rg -n $app -o tsv --query "[].name"
# make sure an managed identity is assigned
$slots | foreach {
$id = az webapp identity assign -g $rg -s $_ -n $app -o tsv --query "principalId"
az role assignment create --role "Storage Blob Data Contributor" --assignee $id --scope $rgid
}
}
}
The snippet above demonstrates how to use the ForEach-Object cmdlet to assign the Storage Blob Data Contributor roles to each app service. Note that the applications are only authorized to access storage accounts in their own resource groups. The cmdlet has an alias, foreach, which makes the code slightly more terse. The advantage of this code is that it is re-entrant; when you run it the first time, it will create the system-assigned managed identities and roles. If you rerun the code and these objects have already been created, it won't throw errors.
If you are applying many of the same role assignments to different apps, you may want to create a custom role definition that combines several roles together. Custom role definitions are demonstrated in Part One of this guide, How to Define Azure Role-based Access Control (RBAC). This may be required since there is a hard limit of 2000 role assignments per Azure subscription.
Skipping Role Assignments for Certain Resources
Another useful organization feature of Azure is the ability to tag resource groups and resources. This can help with your security infrastructure since you can establish conventions and patterns that make it easier for your organization to make widespread changes. To take advantage of tags for the purpose of RBAC role assignments, write a JMESQuery to filter out resources. This allows you to skip role assignments for certain resources or groups.
The following code snippet demonstrates how to do this for resource groups and Azure App Services.
# filter out resource groups have the tag "sec:sensitive"
az group list -o json --query "[?tags.sec!='sensitive']" | ConvertFrom-Json
# filter out app services have that the tag "sec:sensitive"
az webapp list -g rg-pl-demo --query "[?tags.sec!='sensitive'].name"
By tagging your resources correctly, you can set up different resource groups with differing security requirements. These tags can then be read by your automation scripts to consistently apply your organization's security policy.
Conclusion
Naming and tagging is important for scaling your cloud infrastructure. You have used tags to define security policies, but they can be also be used in different ways, such as cost monitoring and asset organization. Learn more by reading Microsoft's recommended best practices on naming and tagging.