Create network security groups using the Azure CLI 2.0

CLI versions to complete the task

You can complete the task using one of the following CLI versions:

  • Azure CLI 1.0 – our CLI for the classic and resource management deployment models
  • Azure CLI 2.0 - our next generation CLI for the resource management deployment model (this article)

You can use an NSG to control traffic to one or more virtual machines (VMs), role instances, network adapters (NICs), or subnets in your virtual network. An NSG contains access control rules that allow or deny traffic based on traffic direction, protocol, source address and port, and destination address and port. The rules of an NSG can be changed at any time, and changes are applied to all associated instances.

For more information about NSGs, visit what is an NSG.

Scenario

To better illustrate how to create NSGs, this document will use the scenario below.

VNet scenario

In this scenario you will create an NSG for each subnet in the TestVNet virtual network, as described below:

  • NSG-FrontEnd. The front end NSG will be applied to the FrontEnd subnet, and contain two rules:
    • rdp-rule. This rule will allow RDP traffic to the FrontEnd subnet.
    • web-rule. This rule will allow HTTP traffic to the FrontEnd subnet.
  • NSG-BackEnd. The back end NSG will be applied to the BackEnd subnet, and contain two rules:
    • sql-rule. This rule allows SQL traffic only from the FrontEnd subnet.
    • web-rule. This rule denies all internet bound traffic from the BackEnd subnet.

The combination of these rules create a DMZ-like scenario, where the back end subnet can only receive incoming traffic for SQL from the front end subnet, and has no access to the Internet, while the front end subnet can communicate with the Internet, and receive incoming HTTP requests only.

The sample Azure CLI 2.0 commands following expect a simple environment already created based on the scenario preceding.

Create the NSG for the FrontEnd subnet

To create an NSG named NSG-FrontEnd based on the scenario preceding, follow the steps following.

  1. If you haven't yet, install and configure the latest Azure CLI 2.0 and log in to an Azure account using az login.

  2. Create an NSG using the az network nsg create command.

     az network nsg create \
     --resource-group testrg \
     --name NSG-FrontEnd \
     --location centralus 
    

    Parameters:

    • --resource-group: Name of the resource group where the NSG is created. For our scenario, TestRG.
    • --location: Azure region where the new NSG is created. For our scenario, westus.
    • --name: Name for the new NSG. For our scenario, NSG-FrontEnd.

      The expected output is quite a bit of information including a list of all the default rules. The following example shows the default rules using a JMESPATH query filter with the table output format:

      az network nsg show \
      -g testrg \
      -n nsg-frontend \
      --query 'defaultSecurityRules[].{Access:access,Desc:description,DestPortRange:destinationPortRange,Direction:direction,Priority:priority}' \
      -o table
      

    Output:

     Access    Desc                                                    DestPortRange    Direction      Priority
    
     Allow     Allow inbound traffic from all VMs in VNET              *                Inbound           65000
     Allow     Allow inbound traffic from azure load balancer          *                Inbound           65001
     Deny      Deny all inbound traffic                                *                Inbound           65500
     Allow     Allow outbound traffic from all VMs to all VMs in VNET  *                Outbound          65000
     Allow     Allow outbound traffic from all VMs to Internet         *                Outbound          65001
     Deny      Deny all outbound traffic                               *                Outbound          65500
    
  3. Create a rule that allows access to port 3389 (RDP) from the Internet with the az network nsg rule create command.

    Note

    Depending on the shell you are using, you might need to modify the * character in the arguments following so as not to expand the argument before execution.

     az network nsg rule create \
     --resource-group testrg \
     --nsg-name NSG-FrontEnd \
     --name rdp-rule \
     --access Allow \
     --protocol Tcp \
     --direction Inbound \
     --priority 100 \
     --source-address-prefix Internet \
     --source-port-range "*" \
     --destination-address-prefix "*" \
     --destination-port-range 3389
    

    Expected output:

     {
         "access": "Allow",
         "description": null,
         "destinationAddressPrefix": "*",
         "destinationPortRange": "3389",
         "direction": "Inbound",
         "etag": "W/\"<guid>\"",
         "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-FrontEnd/securityRules/rdp-rule",
         "name": "rdp-rule",
         "priority": 100,
         "protocol": "Tcp",
         "provisioningState": "Succeeded",
         "resourceGroup": "testrg",
         "sourceAddressPrefix": "Internet",
         "sourcePortRange": "*"
     }
    

    Parameters:

    • --resource-group testrg: The resource group to use. Note that it is case-insensitive.
    • --nsg-name NSG-FrontEnd: Name of the NSG in which the rule is created.
    • --name rdp-rule: Name for the new rule.
    • --access Allow: Access level for the rule (Deny or Allow).
    • --protocol Tcp: Protocol (Tcp, Udp, or *).
    • --direction Inbound: Direction of the connection (Inbound or Outbound).
    • --priority 100: Priority for the rule.
    • --source-address-prefix Internet: Source address prefix in CIDR or using default tags.
    • --source-port-range "*": Source port or port range. Port that opened the connection.
    • --destination-address-prefix "*": Destination address prefix in CIDR or using default tags.
    • --destination-port-range 3389: Destination port or port range. Port that receives the connection request.
  4. Create a rule that allows access to port 80 (HTTP) from the Internet az network nsg rule create command.

     az network nsg rule create \
     --resource-group testrg \
     --nsg-name NSG-FrontEnd \
     --name web-rule \
     --access Allow \
     --protocol Tcp \
     --direction Inbound \
     --priority 200 \
     --source-address-prefix Internet \
     --source-port-range "*" \
     --destination-address-prefix "*" \
     --destination-port-range 80
    

    Expected putput:

     {
         "access": "Allow",
         "description": null,
         "destinationAddressPrefix": "*",
         "destinationPortRange": "80",
         "direction": "Inbound",
         "etag": "W/\"<guid>\"",
         "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-FrontEnd/securityRules/web-rule",
         "name": "web-rule",
         "priority": 200,
         "protocol": "Tcp",
         "provisioningState": "Succeeded",
         "resourceGroup": "testrg",
         "sourceAddressPrefix": "Internet",
         "sourcePortRange": "*"
     }
    
  5. Bind the NSG to the FrontEnd subnet with the az network vnet subnet update command.

     az network vnet subnet update \
     --vnet-name TestVNET \
     --name FrontEnd \
     --resource-group testrg \
     --network-security-group NSG-FrontEnd
    

    Expected output:

     {
         "addressPrefix": "192.168.1.0/24",
         "etag": "W/\"<guid>\"",
         "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/virtualNetworks/TestVNET/subnets/FrontEnd",
         "ipConfigurations": [
             {
             "etag": null,
             "id": "/subscriptions/<guid>/resourceGroups/TestRG/providers/Microsoft.Network/networkInterfaces/TestNIC/ipConfigurations/ipconfig1",
             "name": null,
             "privateIpAddress": null,
             "privateIpAllocationMethod": null,
             "provisioningState": null,
             "publicIpAddress": null,
             "resourceGroup": "TestRG",
             "subnet": null
             }
         ],
         "name": "FrontEnd",
         "networkSecurityGroup": {
             "defaultSecurityRules": null,
             "etag": null,
             "id": "/subscriptions/<guid>f/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-FrontEnd",
             "location": null,
             "name": null,
             "networkInterfaces": null,
             "provisioningState": null,
             "resourceGroup": "testrg",
             "resourceGuid": null,
             "securityRules": null,
             "subnets": null,
             "tags": null,
             "type": null
         },
         "provisioningState": "Succeeded",
         "resourceGroup": "testrg",
         "resourceNavigationLinks": null,
         "routeTable": null
     }
    

Create the NSG for the BackEnd subnet

To create an NSG named NSG-BackEnd based on the scenario preceding, follow the steps following.

  1. Create the NSG-BackEnd NSG with az network nsg create.

     az network nsg create \
     --resource-group testrg \
     --name NSG-BackEnd \
     --location centralus
    

    As in step 2, preceding, the expected output is quite large, including default rules.

  2. Create a rule that allows access to port 1433 (SQL) from the FrontEnd subnet with the az network nsg rule create command.

     az network nsg rule create \
     --resource-group testrg \
     --nsg-name NSG-BackEnd \
     --name sql-rule \
     --access Allow \
     --protocol Tcp \
     --direction Inbound \
     --priority 100 \
     --source-address-prefix 192.168.1.0/24 \
     --source-port-range "*" \
     --destination-address-prefix "*" \
     --destination-port-range 1433
    

    Expected output:

     {
     "access": "Allow",
     "description": null,
     "destinationAddressPrefix": "*",
     "destinationPortRange": "1433",
     "direction": "Inbound",
     "etag": "W/\"<guid>\"",
     "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-BackEnd/securityRules/sql-rule",
     "name": "sql-rule",
     "priority": 100,
     "protocol": "Tcp",
     "provisioningState": "Succeeded",
     "resourceGroup": "testrg",
     "sourceAddressPrefix": "192.168.1.0/24",
     "sourcePortRange": "*"
     }
    
  3. Create a rule that denies access to the Internet using the az network nsg rule create command.

     az network nsg rule create \
     --resource-group testrg \
     --nsg-name NSG-BackEnd \
     --name web-rule \
     --access Deny \
     --protocol Tcp  \
     --direction Outbound  \
     --priority 200 \
     --source-address-prefix "*" \
     --source-port-range "*" \
     --destination-address-prefix "*" \
     --destination-port-range "*"
    

    Expected putput:

     {
     "access": "Deny",
     "description": null,
     "destinationAddressPrefix": "*",
     "destinationPortRange": "*",
     "direction": "Outbound",
     "etag": "W/\"<guid>\"",
     "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-BackEnd/securityRules/web-rule",
     "name": "web-rule",
     "priority": 200,
     "protocol": "Tcp",
     "provisioningState": "Succeeded",
     "resourceGroup": "testrg",
     "sourceAddressPrefix": "*",
     "sourcePortRange": "*"
     }
    
  4. Bind the NSG to the BackEnd subnet using the az network vnet subnet set command.

     az network vnet subnet update \
     --vnet-name TestVNET \
     --name BackEnd \
     --resource-group testrg \
     --network-security-group NSG-BackEnd
    

    Expected output:

     {
     "addressPrefix": "192.168.2.0/24",
     "etag": "W/\"<guid>\"",
     "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/virtualNetworks/TestVNET/subnets/BackEnd",
     "ipConfigurations": null,
     "name": "BackEnd",
     "networkSecurityGroup": {
         "defaultSecurityRules": null,
         "etag": null,
         "id": "/subscriptions/<guid>/resourceGroups/testrg/providers/Microsoft.Network/networkSecurityGroups/NSG-BackEnd",
         "location": null,
         "name": null,
         "networkInterfaces": null,
         "provisioningState": null,
         "resourceGroup": "testrg",
         "resourceGuid": null,
         "securityRules": null,
         "subnets": null,
         "tags": null,
         "type": null
     },
     "provisioningState": "Succeeded",
     "resourceGroup": "testrg",
     "resourceNavigationLinks": null,
     "routeTable": null
     }