Audit Subnets That do not Have Network Security Group Associated

5 Min. Read

Today, a common theme in cloud environments is enforcing organizational standards and adopting cloud governance since day one. And this is very important since it will give you the ability to define policies, processes, and procedures. These policies then dictate what can be done and verify that what does exist is correct. A service from Microsoft called Azure Policy is a great way to make that happen and take corrective action.

This article will demonstrate how to audit Azure virtual network subnets that do not have Network Security Group (NSG) associated.


Azure Policy is a service in Azure that you use to create, assign, and manage policies. These policies enforce different rules and effects over your resources, so those resources stay compliant with your corporate standards and service level agreements. Azure Policy meets this need by continuously evaluating your resources for non-compliance with assigned policies.

You have a policy in your organization that dictates auditing all existing virtual network subnets that do not have Network Security Group (NSG) associated. As you know very well, you should protect your subnet from potential threats by restricting access to it with a Network Security Group (NSG). NSGs contain a list of Access Control List (ACL) rules that allow or deny network traffic to your subnet.

A quick look at Azure Security Center, we have already a built-in Azure Policy definition which is based on the default Azure Security Benchmark (V2) that requires having a network security group (NSG) associated at the subnet level, as well as at the network interface to pass this recommendation as shown in the figure below.

Subnets should be associated with a network security group

Based on this default policy, when an NSG is associated with a subnet, the ACL rules apply to all the VM instances and integrated services in that subnet, but don’t apply to internal traffic inside the subnet. To secure resources in the same subnet from one another, you need to enable NSG directly on the resources as well.

As a side note, Azure Security Center offers continuous assessment and security recommendations free of charge. You don’t need Azure Defender to get the benefits of those assessements and recommedantions.

However, according to our policy requirements, we are only interested in the Network Security Groups (NSG) associated on the subnet level, and not on the resource (network interface) level. Because Security Center won’t flag the resource as healthy unless both (Subnet and NIC) are associated with a Network Security Groups (NSG).

In this article, I will share with you how to create a custom Azure Policy to audit all virtual network subnets that do not have Network Security Group (NSG) associated.


To follow this article, you need to have the following:

  1. An Azure subscription. If you don’t have an Azure subscription, you can create a free one here.
  2. At least one virtual network(s) deployed with their appropriate IP subnets. Please check the following quickstart guide to create a virtual network.
  3. At least one network security group(s). Please check the following guide to create a network security group.
  4. Last but not least, you need to have the appropriate permissions to create and manage Azure Policy definitions. The Azure RBAC built-in roles that you can use are Resource Policy Contributor or Security Admin.

Create Custom Policy definition

A quick overview of Azure Policy effects. Each policy definition that you create in the Azure Policy has a single effect. That effect determines what happens when the policy rule is evaluated to match. The effects behave differently if they are for a new resource, an updated resource, or an existing resource.

In this example, we need to evaluate the associated NSG for all subnets. For this to work, we need to use the “Audit” policy effect. To understand how the Azure Policy effect works with the “Audit” policy definition, please check the official documentation from Microsoft.

Assuming you have all the prerequisites in place, take now the following steps:

Open the Azure Portal, click “All services” and then search for “Policy” and then click on “Definitions” → “+ Policy definition”.

For the “Definition location“, select the location by clicking the ellipsis [] and select either a management group or a subscription.

In the “Name“ field, give a descriptive name for the policy definition such as – “Audit Subnets that do not have Network Security Group associated“.

In the “Category” section, select the appropriate category for this policy. In this example, I will choose “Network“.

Create Azure Policy Custom Definition

For the “POLICY RULE“, paste the following policy definition in JSON format and then click “Save“.

  "mode": "All",
  "policyRule": {
    "if": {
      "allOf": [
          "field": "type",
          "equals": "Microsoft.Network/virtualNetworks/subnets"
          "field": "Microsoft.Network/virtualNetworks/subnets/networkSecurityGroup",
          "exists": "false"
          "not": {
            "field": "name",
            "equals": "GatewaySubnet"
          "not": {
            "field": "name",
            "equals": "AzureBastionSubnet"
          "not": {
            "field": "name",
            "equals": "AzureFirewallSubnet"
    "then": {
      "effect": "[parameters('effect')]"
  "parameters": {
    "effect": {
      "type": "String",
      "metadata": {
        "displayName": "Effect",
        "description": "Enable or disable the execution of the policy"
      "allowedValues": [
      "defaultValue": "Audit"

In this custom policy, I am getting all the virtual network subnets type and then I am checking the network security group field if it does exist or not. Additionally, I am excluding all the default subnet names that Microsoft defined for the Gateway Subnet, Bastion Subnet, and Azure Firewall Subnet. Because those subnets should not have Network Security Group associated, so we need to exclude them from our policy to have an accurate audit.

Assign Custom Policy definition

To assign the custom policy definition, take the following steps:

Open the Azure Portal, click “All services” and then search for “Policy” and then click on “Assignments”. An assignment is a policy that has been assigned to take place within a specific scope.

Select “Assign policy” from the top of the “Policy | Assignments” page.

On the “Assign Policy” page, select the Scope by clicking the ellipsis [] and select either a management group or subscription. You can optionally select a resource group if you want. A scope determines what resources or grouping of resources the policy assignment gets enforced on. Then click Select at the bottom of the Scope page.

Select the Policy definition ellipsis [] to open the list of available definitions. Choose the custom policy that we created in the previous step. The Policy enforcement is Enabled by default. Click Next to continue.

On the Parameters page, specify the parameters for this policy assignment (Audit or Disabled). The default value is set to “Audit“, you can disable the effect of this policy later on by setting the effect to “Disabled“. Click Next to continue.

Assign Azure Policy Custom Definition

On the Remediation page, Click Next to continue. In this example, we don’t want to automate the remediation for non-compliant resources. To learn more about the remediation task, please check the following article.

On the Non-compliance messages page, set the desired message. Then click the “Review + create” button.

Subnet should be associated with a Network Security Group

Finally, click “Create” to create the assignment.

Verify Custom Policy definition

To verify that the custom policy is deployed successfully, you need to wait for at least 30 minutes after a resource has been created or updated. The policy won’t be triggered immediately, this is by design. To trigger the policy compliance scan manually (immediately), open the cloud shell and run the following command:

$job = Start-AzPolicyComplianceScan -AsJob
$job | ft -AutoSize

The scan job will run in the background as shown in the output below.

Trigger Azure Policy Compliance Evaluation Manually

Depending on the number of virtual network subnets that you have, the evaluation should be completed within 10 minutes.

Open the Azure Portal, click “All services” and then search for “Policy” and then click on the “Compliance” blade. Select the assignment that we created in the previous step and audit the compliance state for all resources as shown in the figure below. In this example, I have 10 subnets that are NOT compliant and 4 that are compliant.

Azure Policy Compliance Report

That’s it there you have it!


In this article, I showed you how to audit Azure virtual network subnets that do not have Network Security Group (NSG) associated at the subnet level, so you can take corrective action to make sure your organization policy and security requirements are met.

To learn more about Azure Policy, please check the official documentation from Microsoft.

Thank you for reading my blog.

If you have any questions or feedback, please leave a comment.

-Charbel Nemnom-

Related Posts


Install Azure Site Recovery Provider on Azure Stack HCI OS

Attribute-Based Access Control for Azure Blob Storage


Let me know what you think, or ask a question...

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Subscribe to Stay in Touch

Never miss out on your favorite posts and our latest announcements!

The content of this website is copyrighted from being plagiarized!

You can copy from the 'Code Blocks' in 'Black' by selecting the Code.

Please send your feedback to the author using this form for any 'Code' you like.

Thank you for visiting!