Reading Time: 3 minutes

You can use Azure network security group to filter network traffic to and from Azure resources in an Azure virtual network. A network security group contains security rules that allow or deny inbound network traffic to, or outbound network traffic from, several types of Azure resources. For each rule, you can specify source and destination, port, and protocol.

Microsoft Docs

So, essentially NSGs act like a basic “firewall” in that it filters the traffic in and out of the perimeter of the resources associated with. It comes with some built in rules to allow connectivity with Azure fabric and after that it is based on your needs to apply the rules that suit your business needs. The rules have a priority number; the lower the number the higher the priority.

NSGs can be applied on vnet, subnet and/or network interface

You can deploy a NSG, with an outbound rule for blocking internet access to all within the virtual network, with the following ARM Template:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "nsgName": {
            "defaultValue": "nsg-nointernet",
            "type": "String"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2020-03-01",
            "name": "[parameters('nsgName')]",
            "location": "westeurope",
            "properties": {
                "securityRules": [
                    {
                        "name": "no-internet",
                        "properties": {
                            "protocol": "*",
                            "sourcePortRange": "*",
                            "destinationPortRange": "*",
                            "sourceAddressPrefix": "VirtualNetwork",
                            "destinationAddressPrefix": "Internet",
                            "access": "Deny",
                            "priority": 100,
                            "direction": "Outbound",
                            "sourcePortRanges": [],
                            "destinationPortRanges": [],
                            "sourceAddressPrefixes": [],
                            "destinationAddressPrefixes": []
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/networkSecurityGroups/securityRules",
            "apiVersion": "2020-03-01",
            "name": "[concat(parameters('nsgName'), '/no-internet')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]"
            ],
            "properties": {
                "protocol": "*",
                "sourcePortRange": "*",
                "destinationPortRange": "*",
                "sourceAddressPrefix": "VirtualNetwork",
                "destinationAddressPrefix": "Internet",
                "access": "Deny",
                "priority": 100,
                "direction": "Outbound",
                "sourcePortRanges": [],
                "destinationPortRanges": [],
                "sourceAddressPrefixes": [],
                "destinationAddressPrefixes": []
            }
        }
    ],
    "outputs": {}
}

You can deploy the above NSG by issuing the following PowerShell code:

# rg-demo resource group must exist in your Azure subscription prior
# and the JSON file needs to be in the same directory you execute
New-AzResourceGroupDeployment `
    -DeploymentName "NSG-Deployment" `
    -ResourceGroupName "rg-demo" `
    -TemplateFile ".\nsg nointernet.json" `
    -Verbose
NSG deployed using the above ARM template
This is how it look like on the Portal

NSGs and ASGs

If you have followed the post for creating an Application Security Group, you can create the NSG with the following template:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "nsgName": {
            "defaultValue": "nsg-nointernet",
            "type": "String"
        },
        "asgName": {
            "type": "String"
        }
    },
    "variables": {
        "asgId":"[resourceId('Microsoft.Network/applicationSecurityGroups',parameters('asgName'))]"
    },
    "resources": [
        {
            "type": "Microsoft.Network/networkSecurityGroups",
            "apiVersion": "2020-03-01",
            "name": "[parameters('nsgName')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "securityRules": [
                    {
                        "name": "no-internet",
                        "properties": {
                            "protocol": "*",
                            "sourcePortRange": "*",
                            "destinationPortRange": "*",
                            "destinationAddressPrefix": "Internet",
                            "access": "Deny",
                            "priority": 100,
                            "direction": "Outbound",
                            "sourcePortRanges": [],
                            "destinationPortRanges": [],
                            "sourceAddressPrefixes": [],
                            "destinationAddressPrefixes": [],
                            "sourceApplicationSecurityGroups": [
                                {
                                    "id": "[variables('asgId')]"
                                }
                            ]
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/networkSecurityGroups/securityRules",
            "apiVersion": "2020-03-01",
            "name": "[concat(parameters('nsgName'), '/no-internet')]",
            "dependsOn": [
                "[resourceId('Microsoft.Network/networkSecurityGroups', parameters('nsgName'))]"
            ],
            "properties": {
                "protocol": "*",
                "sourcePortRange": "*",
                "destinationPortRange": "*",
                "destinationAddressPrefix": "Internet",
                "access": "Deny",
                "priority": 100,
                "direction": "Outbound",
                "sourcePortRanges": [],
                "destinationPortRanges": [],
                "sourceAddressPrefixes": [],
                "destinationAddressPrefixes": [],
                "sourceApplicationSecurityGroups": [
                    {
                        "id": "[variables('asgId')]"
                    }
                ]
            }
        }
    ],
    "outputs": {
        "asgId": {
            "type": "string",
            "value": "[variables('asgId')]"
        }
    }
}

And then deploy it like this, passing the ASG name as a parameter:

New-AzResourceGroupDeployment `
    -DeploymentName "NSG-Deployment" `
    -ResourceGroupName "rg-demo" `
    -TemplateFile ".\nsg nointernet with asg.json" `
    -asgName "asg-application-servers" `
    -Verbose
Another Template but deployed on the same NSG created above, resulted in updating the rules
This is the resulting rule as seen on Azure Portal

Read more about NSGs here.

Cheers!