Hi all, welcome to another blog post.
This one is about custom policies. In case you missed the introduction to Azure Policy, here it is. Custom policies can help an organisation where the built-in policies are not sufficient. Just to demonstrate how easy it is to create a custom policy, lets create one. First create a resource group:
1 2 3 4 5 6 7 8 |
# Login to Azure Account Login-AzureRmAccount # Get Azure Subscription $Subscription = Get-AzureRmSubscription | Out-GridView -Title 'Select Subscription'-OutputMode Single Select-AzureRmSubscription -SubscriptionId $Subscription.Id # Create new resource group $resourceGroup = New-AzureRmResourceGroup -Name 'JDJ-EUW-PRD-NSG-RG' -Location 'WestEurope' |
This resource group will contain all the production network security groups (NSGs) in West Europe. With the built-in policy definition called ‘Allowed resource types’ you can restrict that only NSGs can be deployed in this resource group. But lets say we want to control the naming of the NSGs, this we need to accomplish with custom policies. I can try to explain how a custom policy definition structure is built, but this is already done by Microsoft here.
In the Azure Policy samples repository there are a lot of custom policy examples. For this example I have used the sample ‘enforce-match-pattern’. The nice thing in the repository that there is also a powershell script that provides you the information, how to deploy the policy definition. Lets create a definition:
1 2 3 4 5 6 7 |
# Create new Policy Definition $definition = New-AzureRmPolicyDefinition -Name "enforce-match-pattern" ` -DisplayName "Ensure resource names match the naming pattern" ` -description "Ensure resource names match the naming pattern" ` -Policy 'https://raw.githubusercontent.com/Azure/azure-policy/master/samples/TextPatterns/enforce-match-pattern/azurepolicy.rules.json' ` -Parameter 'https://raw.githubusercontent.com/Azure/azure-policy/master/samples/TextPatterns/enforce-match-pattern/azurepolicy.parameters.json' ` -Mode All |
When the deployment of the policy definition is done, we need to assign this to the resource group that we have created earlier. Because the example policy definition has a ‘namePattern’ field which require a parameter we have to provide the parameter ‘namePattern’ (sounds logical right?). In this blog I have chosen for the naming pattern ‘JDJ-EUW-PRD-??????-NSG-###’. The ??? stands for characters and the ### for numbers. Remember that the number of question marks or hashtags are the number of characters or numbers you need to define.
In a naming convention there probably will be some rules about how a company will use an abbreviation for regions, or resources like network security groups. At this moment it is not possible to create custom rule for this rules. Lets assign the policy definition to the resource group we created earlier.
1 2 3 4 5 6 7 8 |
# Assign the new Policy Definition $assignmentName = 'Enforce NSG naming convention' $assignmentScope = $resourceGroup.ResourceId $namePattern = 'JDJ-EUW-PRD-???????-NSG-###' # JDJ-EUW-PRD-7CHARACTERS-NSG-3NUMBERS New-AzureRMPolicyAssignment -Name $assignmentName ` -Scope $assignmentScope ` -PolicyDefinition $definition ` -namePattern $namePattern |
After assignment, the resource group is ‘protected’ by the custom policy. Now we need to test the policy to see if it works. First we will create a NSG with a naming pattern that is not compliant to the policy.
1 2 3 |
# Create NSG with wrong naming pattern $nsgName = 'Test-NSG' New-AzureRmNetworkSecurityGroup -Name $nsgName -ResourceGroupName $resourceGroup.ResourceGroupName -Location $resourceGroup.Location |
This deployment will fail, now lets create a NSG with a compliant naming convention.
1 2 3 |
# Create NSG with wrong naming pattern $nsgName = 'JDJ-EUW-PRD-SUBNETS-NSG-001' New-AzureRmNetworkSecurityGroup -Name $nsgName -ResourceGroupName $resourceGroup.ResourceGroupName -Location $resourceGroup.Location |
Keep posted for updates!
Hi there,
thanks for this nice article. While trying this out I asked myself how you would set several Policy Definitions on a Resource Group or better on the subscription level. Normally there is more than one kind of resources and if I really want to enforce a naming pattern for the company I’ll establish it at the top level for all the resources which can be deployed.
Best Regards,
Norman
The way to set several policy definitions is to use a initiative policy. For naming patterns there is a way you can enforce a resource type to have a specific name. For example:
{
“type”: “Microsoft.Authorization/policyDefinitions”,
“name”: “enforce-naming-subnet-policyDef”,
“properties”: {
“displayName”: “Enforce Naming – Subnet”,
“description”: “This policy enforces the correct naming of resources.”,
“metadata”: {
“category”: “Regulatory Compliance”
},
“parameters”: {},
“policyRule”: {
“if”: {
“allOf”: [
{
“field”: “type”,
“equals”: “Microsoft.Network/virtualNetworks/subnets”
},
{
“not”: {
“anyOf”: [
{
“field”: “name”,
“match”: “EUW-S##-???-VNET-##-SNT-????-##”
},
{
“field”: “name”,
“match”: “EUN-S##-???-VNET-##-SNT-????-##”
}
]
}
}
]
},
“then”: {
“effect”: “deny”
}
}
}
}
Hi, Thank you very much for writing the policy and I tried it is actually working as expected but I tried to add the users and trying to assign the user roles as they belong to then the naming pattern policy is restricting me to add by saying the customized policy match naming pattern.
Can you guide me?
Thanks,
Reddy