In this article, I’ll do a quick run through of Azure Policy and what you can do with it. Given that we can now deploy infrastructure in Azure quickly and we can provide multiple teams access, the question is how do we control what can be deployed. In this article, we’ll look at how to prevent users opening up inbound RDP ports open from the internet to their Windows VMs.
What is Azure Policy
Azure Policy is a new Azure feature where you can assign policies to your Azure subscriptions or management groups (groups of Azure subscriptions). Using Azure Policy, you can specify what Azure resources should be denied, which should be audited and which should be automatically remediated by deploying an additional ARM template you specify. For example you can block all storage accounts that don’t use encryption.
There are some built in policies however you can create your own using JSON. There are different parts to the JSON policy as code file:
- Policy definitions: These are policies that will be enforced such as Allowed Resource Types (set which resources can be deployed), Allowed Virtual Machine SKUs (sets which VM SKUs can be deployed).
- Initiative definitions: These are groups of policies that are aimed at achieving a larger goal. For example, you could have an initiative for reducing costs and then you can have a number of policies under that such as one policy which prevents users deploying large virtual machines and another which prevents them deploying databases which high DTUs. You can then assign the initiative definition to a subscription or management group.
Create Network Security Group for testing
For starters, I’ll go ahead and create a new Network Security Group which allows TCP port 3389 from the internet. For more information on Network Security Groups, see here.
Create Azure Policy Definition to deny inbound RDP
Now that we have created our Network Security Group which we want to block, we will go ahead and create an Azure Policy Definition.
1) Log into your Azure Portal and search for Policy:
2) Here you see the Overview pane with a summary of your compliance status. There are no assigned policies so we can see that we’re 100% compliant.
3) Create new policy code
The policy is written in JSON and includes a number of fields:
- displayName - The name that will appear in the Azure Portal
- description - The description that will appear in the Azure Portal
- mode: If set to all then the policy applies to all resource types. If set to indexed then the policy applies to only resource types that support tags and location
- parameters: Here we can set the parameters for our policy. Rather than create a policy for each inbound port you want to block, you can create a single policy which takes a port parameter. See below:
- if….then: This is the policy condition and action. It works like most if statements - i.e. if the resource meets certain criteria then an action will be taken. The action can be deny, audit and other options. There’s more information here.
The full JSON content is below:
4) Click on Definitions and add a new Policy Definition, add the JSON content to it and click Save:
5) Assign the policy. Click the policy definition you just created and then click on Assign.
6) Select the subscription or management group you want to assign the policy to and then set the parameters. In this case, we want to block inbound RDP traffic from the internet so you’d need to specify 3389 in the parameters section at the bottom. Click assign when done.
Testing Azure Policy:
Let’s test this out. We need to wait a bit of time for the policy to apply and hopefully we should see that the policy is not compliant and we can click through to find the offending resource.
If you try to create a new NSG rule which allows inbound port 3389 from the internet, it is denied by policy then you get an error like this:
You also get blocked if you try to deploy using PowerShell, terraform, the REST API or other methods as they all use the Azure Resource Manager.
In this article, we went through how you can use Azure Policy to deny the creation of any NSG rule that allows inbound traffic from the internet on specified ports. This is one step forward to achieving good Azure governance.