8 minutes
Azure Policies, the basics
When an organization decides to provision applications and infrastructure components in the cloud, security has to be taken into consideration. To mitigate human security mistakes it can be wise to put some guardrails around your cloud environments. The amounts of guardrails chosen depends on organisation size, developer experience level and security posture, as well as network topologies and possible connections to the on-premise company systems. In Azure, the Azure policies allow you to reduce the risk of having your environment being compromised by human error and risky configurations, either unintended or with malicious intent.
Azure policies can audit, deny, append and modify resource configurations that introduce unnecessary risk. You can also deploy complementary resources with a certain configuration where missing, for example you can automatically deploy a network security group for every created subnet, if your application teams have failed to do so.
The use of policies can be powerful, but also hampers your developers freedom. You should always weigh the ease of working, against the security gained when you assign a policy. There is no “golden path” for every single case here, you will have to adapt your security governance to the organisations needs and security posture. When you define and assign the policies, think about what the desired outcome is and how you can achieve that outcome with a minimum of hassle for your application teams.
This guide depends on the following:
Tool | Link |
---|---|
Azure Bicep Cli | Bicep Cli install instructions |
VSCode + Bicep Extension | Getting Up And Ready With VSCode and VSCode Productivity hints |
Azure Powershell | Setup Azure Powershell |
Azure Account | Register Free Azure Account |
Policy Definitions
First and foremost, all Azure policies are defined by Policy Definitions. A Policy Definition describes the conditions for when the policy will apply, how the policy is enforced and what parameters that can be supplied to the policy. Microsoft has provided a large variety of built-in policies, that you can assign without having to author your own Custom policy. You can find all these in the Azure Portal Policy blade by clicking definitions. The type column shows if the policy is built-in or custom made. I usually just type policy in the main search bar of the Azure portal to bring up the policy blade. However you can open the policy blade from management groups, subscriptions and resource groups, as these are the scopes where you can store policy definitions and make policy assignments.
Policy Initiatives / Sets
You can group policy definitions into something called initiatives or* policy sets* . This will enable you to assign a group of policies to a scope with a single assignment and helps grouping policies that server a common purpose.
Policy Assignments
The Policy Assignments is what links the Policy Definitions or Initiatives/PolicySets to an Azure Scope, such as a Management Group, Subscription or Resource Group. When assigning the policy, parameters can be provided. This will make it possible to make multiple assignments of a policy in the same scope, with different paramter values set in each, and also make it possible to use a policy definition for assignments in several different subordinate scopes.
Assigning Policies
To assign a policy you can either use the Azure Portal, use PowerShell or make a Bicep/ARM deployment of a policyassignment. I won’t show how to do it in the portal as I think it’s rather self explanatory if you open the policy blade.
Let’s assign a simple tag policy to the SAP Management group scope.
Find the policy in the Azure portal
Open up Managment Groups in the portal and then click the Policy in the left side menu. Then open definitions and search the policies for the keyword Tag, select the policy Require a tag and its value on resources. Copy the definition id in order to use it in your assignment.
PowerShell
Here is how you make a policyassignment using PowerShell.
Connect-AzAccount
$ManangementGroup = Get-AzManagementGroup 'SAP'
$ManangementGroup.Id
# Outputs /providers/Microsoft.Management/managementGroups/SAP
# This is the Scope you will assign the policy to
# Here you will use the Id you copied from the policydefinition in the Azure Portal
$PolicyDefinition = Get-AzPolicyDefinition -Id '/providers/Microsoft.Authorization/policyDefinitions/1e30110a-5ceb-460c-a204-c1c3969c6d62'
#Splatting the parameters for New-AzPolicyAssignment
$Params = @{
Name = 'TagCostCenter0000'
DisplayName = 'All resources must have tag CostCenter set to 0000'
PolicyDefinition = $PolicyDefinition
Scope = $ManangementGroup.Id
TagName = 'CostCenter'
TagValue = '0000'
}
New-AzPolicyAssignment @Params
Cleaning up
If you want to remove the policy assignment at a later time, you can use PowerShell again in a similar way.
Connect-AzAccount
$ManangementGroup = Get-AzManagementGroup 'SAP'
$ManangementGroup.Id
# Outputs /providers/Microsoft.Management/managementGroups/SAP
# This is the Scope you will unassign the policy from
# Removes the policy assignment
Remove-AzPolicyAssignment -Name 'TagCostCenter0000' -Scope $ManangementGroup.Id
Bicep
I like to deploy policyassignments using Bicep, as it provides a way to store all the details of the assignments in a nice readable format and you can easily version control the Bicep files. Another reason I like to deploy using template deployments (Bicep or ARM) is that if you would use Azure Cli or PowerShell cmdlets and loops to deploy each resource, it would call the Azure ARM Api once for every resource instead of just calling the Api once to deliver the deployment template.
With Bicep you can also bundle other resources together with the policy assignment and deploy to the same scope, as a nice package. Once a deployment has been submitted to Azure, the deployment will be carried out by Azure Resource manager independently of your PowerShell session. You’ll notice that this is way more efficient when deploying lot’s of resources in a single deployment. I prefer to use Bicep rather than ARM when suitable, because of the simplified syntax and the VSCode intellisense support for Bicep.
Create the Bicep file
Download the Bicep file assign_costcentertagpolicy.bicep. It’s a good idea to write your own bicep file and use the downloaded as reference, just to learn the syntax and the logic of the bicep files. Remember that Ctrl+Space
will give you intellisense syntax help.
targetScope
We are deploying this template to a managementGroup, the targetScope must match the scope we deploy to.
@decorator
The decorators for the tagName and tagValue parameters, these decorators provides descriptions for the parameters. There are other decorators available like “allowed(values)”, you can see what’s available if you just type the @ sign in the row above the parameter declaration, VSCode will bring up the Bicep intellisense.
param tagName string
This is a parameter, we will set the tagName defaultvalue to ‘CostCenter’.
param tagValue array
This is a parameter, we will set the tagName defaultvalue to ‘0000’.
resouce assign_costcentertagpolicy
This is the policy assignment resource.
name:
The name of the policy assignment, will be used in the resourceId for the policy assignment.
/* */
Remarked section (starting with /* and ending with */), this is just to show how to make the assignment for a remediation policy, remediation tasks require an indentity that will carry out the remediations.
properties
The properties of this policy assignment.
displayName
The name of the policy assignment that will be displayed in the Azure portal.
description
The description of the policy assignment that will be displayed in the Azure portal.
policyDefinitionId
The id of the policy definition that will be assigned.
parameters
In this key all the input parameters for the policy definition will be populated.
tagName
The first parameter that will be consumed by the policy definition, this value is consumed from the tagName parameter declared earlier in the bicep, using the defaultvalue ‘CostCenter’ if nothing else is provided when deploying.
tagValue
The second parameter that will be consumed by the policy definition, this value is consumed from the tagValue parameter declared earlier in the bicep, using the defaultvalue ‘0000’ if nothing else is provided when deploying.
Deploy the policy assignment
First you always need to authenticate your session to Azure, if have done so, but your session to Azure has expired, you may need to re-authenticate.
Connect-AzAccount
Now you can go ahead with deployment.
Note that I have chosen to deploy my policy assignment to the managementgroup ‘SAP’ that was created in a previous blogpost. In Location you can use your Azure location of preference.
#Splatting parameters to make it more readable
$Params = @{
ManagementGroupId = 'SAP'
Templatefile = '.\assign_costcentertagpolicy.bicep'
Location = 'WestEurope'
Name = 'PolicyAssigndeploy'
}
#Deploy the Assignment
New-AzManagementGroupDeployment @Params
Cleaning up
If you want to remove the policy assignment at a later time, can clean up both the assignment and the deployment details.
# Removes the policy assignment
$ManangementGroup = Get-AzManagementGroup 'SAP'
Remove-AzPolicyAssignment -Name 'TagCostCenter0000' -Scope $ManangementGroup.Id
# This line removes the deployment, but does not remove the assignment itself
Remove-AzManagementGroupDeployment -ManagementGroupId 'SAP' -Name 'PolicyAssigndeploy'
Conclusion
This was two ways to assign policies using code, using Azure Cli is very similar to using PowerShell, but there are also other ways to do this using code, but I won’t be covering other ways here. Next we will look into how to make Policy Initiatives / Policy Sets and how to author your own Custom Policies - stay tuned!
Please follow me on LinkedIn and let me know if you like my blog.