When companies use Azure to deploy and use resources, they should use strict guidelines to safeguard their subscriptions and keep the quality at a high level. They need to make sure that resources are placed in the correct resource groups, in the correct region or that all the provisioned resources are correctly named and tagged. These are only some examples where Azure resource policies come into play because they allow how Azure resources can be provisioned and what is not compliant with the company policy.
Policies are built based on a simple “if-then” principle. If some condition is true (e.g. if a resource has no tags) there will be a specific action (e.g. allow or deny). Here are some examples what you can enforce with Azure resource policies:
- Azure resources can only be deployed when they are completely tagged, if not, the resources will not be created (goal: data quality and transparency)
- Only specific Azure resources can be deployed, everything else is denied (goal: service control)
- Azure resources should follow a specific naming scheme, if not, they cannot be created (goal: consistent naming)
- Azure resources can only be deployed when they are placed in a specific region, otherwise the creation fails (goal: geo-compliance)
There are many more scenarios of course. However, I will not cover all the background in this post because most of the information is already available somewhere out there. Check out this website for more details about Azure resource policies, how they compare to RBAC and what exact possibilities they offer. What I will cover in this blog post however is a complete walkthrough how to create a policy, assign it and test it.
Step 1 – Create a Policy File
The very first step is to create a policy file. This is pretty simple because it’s a simple-to-read JSON file. I will use Visual Studio to create this file.
To make the creation process easier, I will add a schema URL. After this URL is added, IntelliSense is available to create the file. By hitting Ctrl+Space somewhere in the structure you will see the available options.
http://schema.management.azure.com/schemas/2015-10-01-preview/policyDefinition.json
The policy file I create will allow Azure admins to deploy new Azure resources only in the West Europe and East US region. No other region should will be allowed. After a minute or two, the finished file will look something like this:
You can see the “If”-“Then”-structure that means, if a new resource will be created and the location will be “West Europe” or “East US”, the creation will happen, if the resource is provisioned into another region the creation will be denied.
Step 2 – Create a Policy Definition
Now as we have JSON file ready it’s time to use it to create a new policy definition in Azure. I use Powershell ISE to accomplish this task. For this walkthrough I will create a new resource group where I will assign the policy later.
#Prepare
Login-AzureRmAccount
Select-AzureRMSubscription -SubscriptionName “Sub2”
New-AzureRmResourceGroup -Name “AzurePolicyTest” -Location WestEurope
#Run
$PolicyDefinition = New-AzureRmPolicyDefinition `
-Name LimitLocations `
-DisplayName LimitLocations `
-Description “Only allow West Europe and East US Locations” `
-Policy .\Desktop\AzureResourcePolicy-LimitLocations.json
See the last command that actually creates the policy in Azure. This is where I use the JSON file I prepared in the step 1. The creation of the policy is done within seconds. You can check what policy definitions are available in your Azure environment.
#Check
Get-AzureRmPolicyDefinition | Select Name
It’s important to understand that after the policy was created, it has no effect unless it is assigned. This is what we will do in the next step.
Step 3 – Assign a Policy Definition
Now as the policy is ready and available in Azure, I need to assign it somewhere. Policies can be assigned at 3 different levels.
- Subscription
- Resource Group
- Resource
The policy target is dependent on what you want to accomplish with your policy. In this example I will assign the policy definition to the newly created resource group. That means, that newly provisioned services in this resource groups can only be located in the West Europe or East US regions whereas resources that are places in other resource groups can still be places in all available regions.
#Prepare
$PolicyAssignmentName = “LimitLocationsTest”
$RG = Get-AzureRmResourceGroup -Name “AzureResourcePolicyTest”
$Scope = “/subscriptions/$($Sub.Subscription.SubscriptionId)/resourceGroups/$($RG.ResourceGroupName)”#Run
New-AzureRmPolicyAssignment -Name $PolicyAssignmentName -PolicyDefinition $PolicyDefinition -Scope $Scope#Check
Get-AzureRmPolicyAssignment
Done!
Step 4 – Test the Configuration
Now it’s time to test the configuration. For that I will create a new storage account and select a region that is explicitly disallowed by the policy I just created.
After a few seconds an error is displayed. By clicking on it, more details will be shown.
The error is also visible in the Azure Monitor and allows you to easily analyze if your policies are working as expected in your environment.
That’s it, mission accomplished! Start working on your Azure resource policy strategy today and implement them to keep your Azure environment nice and clean, compliant and secure.
Cheers
Marcel
Pingback: Azure Resource Locks | marcelzehner.ch
Have you been able to create a policy for naming Resource Groups? I can’t seem to find the namespace that matches when a Resource Group is created. I tried Microsoft.Resources/resourceGroups but that did not work…. Any ideas?
Hey
Sorry for the delay. Don’t know, need to investigate and will post the answer here.
Cheers
Marcel
Hi Marcel
Thanks for the detailed walkthrough.
It occurred to me while testing what happens if you need to alter one or more of the definitions how do you do that? I have seen an example that changes the policydefinition description but not the properties themselves.
Thanks,
S.
Hello Marcel, thanks for the article, when i run the New-AzureRmPolicyAssignment i get below error, not sure where i have gone wrong?
PS C:\WINDOWS\system32>
$PolicyAssignmentName = “LimitVMTest”
$RG = Get-AzureRmResourceGroup -Name “AzurePolicyTest”
$Scope”/subscriptions/$($Sub.Subscription.SubscriptionId.Id)/resourceGroups/$($RG.ResourceGroupName)”
PS C:\WINDOWS\system32> New-AzureRmPolicyAssignment -Name $PolicyAssignmentName -PolicyDefinition $PolicyDefinition -Scope $Scope
New-AzureRmPolicyAssignment : The pipeline has been stopped.
At line:1 char:1
+ New-AzureRmPolicyAssignment -Name $PolicyAssignmentName -PolicyDefini …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmPolicyAssignment], PipelineStoppedException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzurePolicyAssignmentCmdlet
New-AzureRmPolicyAssignment : SubscriptionNotFound : The subscription ‘resourceGroups’ could not be found.
At line:1 char:1
+ New-AzureRmPolicyAssignment -Name $PolicyAssignmentName -PolicyDefini …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (:) [New-AzureRmPolicyAssignment], ErrorResponseMessageException
+ FullyQualifiedErrorId : SubscriptionNotFound,Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzurePolicyAssignmentCmdlet
Your $($Sub.Subscription.SubscriptionId.Id) is empty
Hi Marcel,
Excellent blog post.
I wonder if you know how to create a policy definition with parameters.
Just like the first example here : https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-policy
I hit errors when trying to create a new definition using the example : New-AzureRmPolicyDefinition : InvalidPolicyRule : Failed to parse policy rule: ‘Could not find member ‘parameters’ on object of type ‘PolicyRule’. Path ‘parameters’.’.
Pingback: Azure Resource Policies Management in the Azure Portal | marcelzehner.ch