Restricting resource types from creation in Azure via Azure Policy
@20aman Jun 23, 2021As a best practice, you should restrict the type of resources that can be created in your environment. Even if these are required these should be created by creating an exemption in the policy temporarily. What this does is, it restricts end-users from accidentally creating those resources and disrupting your environment.
Resource Types to restrict
One such example is Route Tables. If someone in your organization with contributor rights creates a Route Table that is applied on a critical subnet then that user can divert all traffic from that subnet.
Public IP Addresses are another big one that you want to restrict. Any public IP in your environment needs to have a valid business justification. These are the connection to the outside world and therefore you need to ensure that if one exists in your environment then that has proper safeguards (like Firewall) etc. in place.
Classic resources should also be limited. You want to conform to the latest standards (ARM-based) and stay away from classic compute and storage resources within Azure.
We recommend the below resource types to consider restricting in your environment as a starting place. You can then extend these and add/remove any types as per your requirements:
- Route Tables
- Public IP addresses
- DNS Zones
- Network Watchers
- Search Services
- Bastion Hosts
- Elastic Pools
- Classic Compute
- Classic Storage
Policy Sample
The below policy sample implements the restrictions and limits the resource types (that we discussed above) from being created at all. If any of the mentioned resource type is created then the policy denies that resource creation operation.
{
"mode": "All",
"policyRule": {
"if": {
"anyOf": [
{
"field": "type",
"like": "Microsoft.Network/dnszones*"
},
{
"field": "type",
"like": "Microsoft.Network/networkWatchers*"
},
{
"field": "type",
"like": "Microsoft.Search/searchServices*"
},
{
"field": "type",
"like": "Microsoft.Network/publicIPAddresses*"
},
{
"field": "type",
"like": "Microsoft.Network/bastionHosts*"
},
{
"field": "type",
"like": "Microsoft.Sql/servers/elasticpools*"
},
{
"field": "type",
"like": "Microsoft.Network/routeTables*"
},
{
"field": "type",
"like": "Microsoft.ClassicCompute/*"
},
{
"field": "type",
"like": "Microsoft.ClassicStorage/*"
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {}
}
Additional Considerations - restricting VM SKUs
In addition to restricting the resource types, you should also restrict VM SKUs. A SKU from the high performance computing series like HBv3-series can eat up your budget very fast. So as a good practice you should be restricting the SKUs to only the ones that you allow. You will need to maintain the list and update it as different projects require additional SKUs or want to upgrade to the latest series. But that is easily done and hardly takes any time. The benefits far outweigh this one small downside.
Complete Policy Samples on GitHub
You can find the complete policy samples on the GitHub in my policy samples repository here: AzurePolicySamples - Enforcing Standards.