diff --git a/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml b/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml index d2ee2f9ccc..e51c41ee43 100644 --- a/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml +++ b/.azuredevops/modulePipelines/ms.network.networksecuritygroups.yml @@ -42,6 +42,7 @@ stages: parameters: removeDeployment: '${{ parameters.removeDeployment }}' deploymentBlocks: + - path: $(modulePath)/.parameters/min.parameters.json - path: $(modulePath)/.parameters/parameters.json - stage: Publishing diff --git a/.github/workflows/ms.network.networksecuritygroups.yml b/.github/workflows/ms.network.networksecuritygroups.yml index 1fa6764967..626f5c4dfc 100644 --- a/.github/workflows/ms.network.networksecuritygroups.yml +++ b/.github/workflows/ms.network.networksecuritygroups.yml @@ -81,7 +81,7 @@ jobs: strategy: fail-fast: false matrix: - parameterFilePaths: ['parameters.json'] + parameterFilePaths: ['min.parameters.json', 'parameters.json'] steps: - name: 'Checkout' uses: actions/checkout@v2 diff --git a/arm/Microsoft.Network/networkSecurityGroups/.parameters/min.parameters.json b/arm/Microsoft.Network/networkSecurityGroups/.parameters/min.parameters.json new file mode 100644 index 0000000000..b07946467a --- /dev/null +++ b/arm/Microsoft.Network/networkSecurityGroups/.parameters/min.parameters.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "<>-az-nsg-min-001" + } + } +} diff --git a/arm/Microsoft.Network/networkSecurityGroups/.parameters/parameters.json b/arm/Microsoft.Network/networkSecurityGroups/.parameters/parameters.json index 0070aa133a..c8f75d3aaf 100644 --- a/arm/Microsoft.Network/networkSecurityGroups/.parameters/parameters.json +++ b/arm/Microsoft.Network/networkSecurityGroups/.parameters/parameters.json @@ -5,7 +5,7 @@ "name": { "value": "<>-az-nsg-x-001" }, - "networkSecurityGroupSecurityRules": { + "securityRules": { "value": [ { "name": "Specific", @@ -57,11 +57,15 @@ "access": "Allow", "priority": 102, "direction": "Inbound", - "sourceApplicationSecurityGroupIds": [ - "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + "sourceApplicationSecurityGroups": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + } ], - "destinationApplicationSecurityGroupIds": [ - "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + "destinationApplicationSecurityGroups": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + } ] } } diff --git a/arm/Microsoft.Network/networkSecurityGroups/deploy.bicep b/arm/Microsoft.Network/networkSecurityGroups/deploy.bicep index 92ef624221..a2cc0b0ce8 100644 --- a/arm/Microsoft.Network/networkSecurityGroups/deploy.bicep +++ b/arm/Microsoft.Network/networkSecurityGroups/deploy.bicep @@ -5,7 +5,7 @@ param name string param location string = resourceGroup().location @description('Optional. Array of Security Rules to deploy to the Network Security Group. When not provided, an NSG including only the built-in roles will be deployed.') -param networkSecurityGroupSecurityRules array = [] +param securityRules array = [] @description('Optional. Resource ID of the diagnostic storage account.') param diagnosticStorageAccountId string = '' @@ -70,29 +70,52 @@ resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2021-05-0 location: location tags: tags properties: { - securityRules: [for nsgSecurityRule in networkSecurityGroupSecurityRules: { - name: nsgSecurityRule.name + securityRules: [for securityRule in securityRules: { + name: securityRule.name properties: { - description: contains(nsgSecurityRule.properties, 'description') ? nsgSecurityRule.properties.description : '' - protocol: nsgSecurityRule.properties.protocol - sourcePortRange: contains(nsgSecurityRule.properties, 'sourcePortRange') ? nsgSecurityRule.properties.sourcePortRange : '' - destinationPortRange: contains(nsgSecurityRule.properties, 'destinationPortRange') ? nsgSecurityRule.properties.destinationPortRange : '' - sourceAddressPrefix: contains(nsgSecurityRule.properties, 'sourceAddressPrefix') ? nsgSecurityRule.properties.sourceAddressPrefix : '' - destinationAddressPrefix: contains(nsgSecurityRule.properties, 'destinationAddressPrefix') ? nsgSecurityRule.properties.destinationAddressPrefix : '' - access: nsgSecurityRule.properties.access - priority: int(nsgSecurityRule.properties.priority) - direction: nsgSecurityRule.properties.direction - sourcePortRanges: contains(nsgSecurityRule.properties, 'sourcePortRanges') ? nsgSecurityRule.properties.sourcePortRanges : null - destinationPortRanges: contains(nsgSecurityRule.properties, 'destinationPortRanges') ? nsgSecurityRule.properties.destinationPortRanges : null - sourceAddressPrefixes: contains(nsgSecurityRule.properties, 'sourceAddressPrefixes') ? nsgSecurityRule.properties.sourceAddressPrefixes : null - destinationAddressPrefixes: contains(nsgSecurityRule.properties, 'destinationAddressPrefixes') ? nsgSecurityRule.properties.destinationAddressPrefixes : null - sourceApplicationSecurityGroups: (contains(nsgSecurityRule.properties, 'sourceApplicationSecurityGroupIds') && (!empty(nsgSecurityRule.properties.sourceApplicationSecurityGroupIds))) ? concat([], array(json('{"id": "${nsgSecurityRule.properties.sourceApplicationSecurityGroupIds[0]}", "location": "${location}"}'))) : null - destinationApplicationSecurityGroups: (contains(nsgSecurityRule.properties, 'destinationApplicationSecurityGroupIds') && (!empty(nsgSecurityRule.properties.destinationApplicationSecurityGroupIds))) ? concat([], array(json('{"id": "${nsgSecurityRule.properties.destinationApplicationSecurityGroupIds[0]}", "location": "${location}"}'))) : null + protocol: securityRule.properties.protocol + access: securityRule.properties.access + priority: securityRule.properties.priority + direction: securityRule.properties.direction + description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' + sourcePortRange: contains(securityRule.properties, 'sourcePortRange') ? securityRule.properties.sourcePortRange : '' + sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') ? securityRule.properties.sourcePortRanges : [] + destinationPortRange: contains(securityRule.properties, 'destinationPortRange') ? securityRule.properties.destinationPortRange : '' + destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') ? securityRule.properties.destinationPortRanges : [] + sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') ? securityRule.properties.sourceAddressPrefix : '' + destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') ? securityRule.properties.destinationAddressPrefix : '' + sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') ? securityRule.properties.sourceAddressPrefixes : [] + destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') ? securityRule.properties.destinationAddressPrefixes : [] + sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') ? securityRule.properties.sourceApplicationSecurityGroups : [] + destinationApplicationSecurityGroups: contains(securityRule.properties, 'destinationApplicationSecurityGroups') ? securityRule.properties.destinationApplicationSecurityGroups : [] } }] } } +module networkSecurityGroup_securityRules 'securityRules/deploy.bicep' = [for (securityRule, index) in securityRules: { + name: '${uniqueString(deployment().name, location)}-securityRule-${index}' + params: { + name: securityRule.name + networkSecurityGroupName: networkSecurityGroup.name + protocol: securityRule.properties.protocol + access: securityRule.properties.access + priority: securityRule.properties.priority + direction: securityRule.properties.direction + description: contains(securityRule.properties, 'description') ? securityRule.properties.description : '' + sourcePortRange: contains(securityRule.properties, 'sourcePortRange') ? securityRule.properties.sourcePortRange : '' + sourcePortRanges: contains(securityRule.properties, 'sourcePortRanges') ? securityRule.properties.sourcePortRanges : [] + destinationPortRange: contains(securityRule.properties, 'destinationPortRange') ? securityRule.properties.destinationPortRange : '' + destinationPortRanges: contains(securityRule.properties, 'destinationPortRanges') ? securityRule.properties.destinationPortRanges : [] + sourceAddressPrefix: contains(securityRule.properties, 'sourceAddressPrefix') ? securityRule.properties.sourceAddressPrefix : '' + destinationAddressPrefix: contains(securityRule.properties, 'destinationAddressPrefix') ? securityRule.properties.destinationAddressPrefix : '' + sourceAddressPrefixes: contains(securityRule.properties, 'sourceAddressPrefixes') ? securityRule.properties.sourceAddressPrefixes : [] + destinationAddressPrefixes: contains(securityRule.properties, 'destinationAddressPrefixes') ? securityRule.properties.destinationAddressPrefixes : [] + sourceApplicationSecurityGroups: contains(securityRule.properties, 'sourceApplicationSecurityGroups') ? securityRule.properties.sourceApplicationSecurityGroups : [] + destinationApplicationSecurityGroups: contains(securityRule.properties, 'destinationApplicationSecurityGroups') ? securityRule.properties.destinationApplicationSecurityGroups : [] + } +}] + resource networkSecurityGroup_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') { name: '${networkSecurityGroup.name}-${lock}-lock' properties: { diff --git a/arm/Microsoft.Network/networkSecurityGroups/readme.md b/arm/Microsoft.Network/networkSecurityGroups/readme.md index 93c865c621..27cbecd179 100644 --- a/arm/Microsoft.Network/networkSecurityGroups/readme.md +++ b/arm/Microsoft.Network/networkSecurityGroups/readme.md @@ -10,6 +10,7 @@ This template deploys a network security group (NSG) with optional security rule | `Microsoft.Authorization/roleAssignments` | 2021-04-01-preview | | `Microsoft.Insights/diagnosticSettings` | 2021-05-01-preview | | `Microsoft.Network/networkSecurityGroups` | 2021-05-01 | +| `Microsoft.Network/networkSecurityGroups/securityRules` | 2021-05-01 | ## Parameters @@ -25,90 +26,10 @@ This template deploys a network security group (NSG) with optional security rule | `lock` | string | `NotSpecified` | `[CanNotDelete, NotSpecified, ReadOnly]` | Optional. Specify the type of lock. | | `logsToEnable` | array | `[NetworkSecurityGroupEvent, NetworkSecurityGroupRuleCounter]` | `[NetworkSecurityGroupEvent, NetworkSecurityGroupRuleCounter]` | Optional. The name of logs that will be streamed. | | `name` | string | | | Required. Name of the Network Security Group. | -| `networkSecurityGroupSecurityRules` | array | `[]` | | Optional. Array of Security Rules to deploy to the Network Security Group. When not provided, an NSG including only the built-in roles will be deployed. | | `roleAssignments` | array | `[]` | | Optional. Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11' | +| `securityRules` | _[securityRules](securityRules/readme.md)_ array | `[]` | | Optional. Array of Security Rules to deploy to the Network Security Group. When not provided, an NSG including only the built-in roles will be deployed. | | `tags` | object | `{object}` | | Optional. Tags of the NSG resource. | -### Parameter Usage: `networkSecurityGroupSecurityRules` - -The `networkSecurityGroupSecurityRules` parameter accepts a JSON Array of `securityRule` to deploy to the Network Security Group (NSG). - -Note that in case of using ASGs (Application Security Groups) - `sourceApplicationSecurityGroupIds` and `destinationApplicationSecurityGroupIds` properties - both the NSG and the ASG(s) have to be in the same Azure region. Currently an NSG can only handle one source and one destination ASG. -Here's an example of specifying a couple security rules: - -```json -"networkSecurityGroupSecurityRules": { - "value": [ - { - "name": "Port_8080", - "properties": { - "description": "Allow inbound access on TCP 8080", - "protocol": "*", - "sourcePortRange": "*", - "destinationPortRange": "8080", - "sourceAddressPrefix": "*", - "destinationAddressPrefix": "*", - "access": "Allow", - "priority": 100, - "direction": "Inbound", - "sourcePortRanges": [], - "destinationPortRanges": [], - "sourceAddressPrefixes": [], - "destinationAddressPrefixes": [], - "sourceApplicationSecurityGroupIds": [], - "destinationApplicationSecurityGroupIds": [] - } - }, - { - "name": "Port_8081", - "properties": { - "description": "Allow inbound access on TCP 8081", - "protocol": "*", - "sourcePortRange": "*", - "destinationPortRange": "8081", - "sourceAddressPrefix": "*", - "destinationAddressPrefix": "*", - "access": "Allow", - "priority": 101, - "direction": "Inbound", - "sourcePortRanges": [], - "destinationPortRanges": [], - "sourceAddressPrefixes": [], - "destinationAddressPrefixes": [], - "sourceApplicationSecurityGroupIds": [], - "destinationApplicationSecurityGroupIds": [] - } - }, - { - "name": "Port_8082", - "properties": { - "description": "Allow inbound access on TCP 8082", - "protocol": "*", - "sourcePortRange": "*", - "destinationPortRange": "8082", - "sourceAddressPrefix": "", - "destinationAddressPrefix": "", - "access": "Allow", - "priority": 102, - "direction": "Inbound", - "sourcePortRanges": [], - "destinationPortRanges": [], - "sourceAddressPrefixes": [], - "destinationAddressPrefixes": [], - //sourceApplicationSecurityGroupIds currently only supports 1 ID ! - "sourceApplicationSecurityGroupIds": [ - "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups//providers/Microsoft.Network/applicationSecurityGroups/" - ], - //destinationApplicationSecurityGroupIds currently only supports 1 ID ! - "destinationApplicationSecurityGroupIds": [ - "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups//providers/Microsoft.Network/applicationSecurityGroups/" - ] - } - } - ] -} -``` - ### Parameter Usage: `roleAssignments` ```json @@ -161,4 +82,5 @@ Tag names and tag values can be provided as needed. A tag can be left without a - [Diagnosticsettings](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) - [Locks](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) - [Networksecuritygroups](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/networkSecurityGroups) +- [Networksecuritygroups/Securityrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/networkSecurityGroups/securityRules) - [Roleassignments](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/roleAssignments) diff --git a/arm/Microsoft.Network/networkSecurityGroups/securityRules/.bicep/nested_cuaId.bicep b/arm/Microsoft.Network/networkSecurityGroups/securityRules/.bicep/nested_cuaId.bicep new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/arm/Microsoft.Network/networkSecurityGroups/securityRules/.bicep/nested_cuaId.bicep @@ -0,0 +1 @@ + diff --git a/arm/Microsoft.Network/networkSecurityGroups/securityRules/deploy.bicep b/arm/Microsoft.Network/networkSecurityGroups/securityRules/deploy.bicep new file mode 100644 index 0000000000..5c53eb29ad --- /dev/null +++ b/arm/Microsoft.Network/networkSecurityGroups/securityRules/deploy.bicep @@ -0,0 +1,110 @@ +@sys.description('Required. The name of the security rule') +param name string + +@sys.description('Required. The name of the network security group to deploy the security rule into') +param networkSecurityGroupName string + +@sys.description('Optional. Whether network traffic is allowed or denied.') +@allowed([ + 'Allow' + 'Deny' +]) +param access string = 'Deny' + +@sys.description('Optional. A description for this rule') +@maxLength(140) +param description string = '' + +@sys.description('Optional. The destination address prefix. CIDR or destination IP range. Asterisk "*" can also be used to match all source IPs. Default tags such as "VirtualNetwork", "AzureLoadBalancer" and "Internet" can also be used.') +param destinationAddressPrefix string = '' + +@sys.description('Optional. The destination address prefixes. CIDR or destination IP ranges.') +param destinationAddressPrefixes array = [] + +@sys.description('Optional. The application security group specified as destination.') +param destinationApplicationSecurityGroups array = [] + +@sys.description('Optional. The destination port or range. Integer or range between 0 and 65535. Asterisk "*" can also be used to match all ports.') +param destinationPortRange string = '' + +@sys.description('Optional. The destination port ranges.') +param destinationPortRanges array = [] + +@sys.description('Required. The direction of the rule. The direction specifies if rule will be evaluated on incoming or outgoing traffic.') +@allowed([ + 'Inbound' + 'Outbound' +]) +param direction string + +@sys.description('Required. The priority of the rule. The value can be between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule.') +param priority int + +@sys.description('Required. Network protocol this rule applies to.') +@allowed([ + '*' + 'Ah' + 'Esp' + 'Icmp' + 'Tcp' + 'Udp' +]) +param protocol string + +@sys.description('Optional. The CIDR or source IP range. Asterisk "*" can also be used to match all source IPs. Default tags such as "VirtualNetwork", "AzureLoadBalancer" and "Internet" can also be used. If this is an ingress rule, specifies where network traffic originates from.') +param sourceAddressPrefix string = '' + +@sys.description('Optional. The CIDR or source IP ranges.') +param sourceAddressPrefixes array = [] + +@sys.description('Optional. The application security group specified as source.') +param sourceApplicationSecurityGroups array = [] + +@sys.description('Optional. The source port or range. Integer or range between 0 and 65535. Asterisk "*" can also be used to match all ports.') +param sourcePortRange string = '' + +@sys.description('Optional. The source port ranges.') +param sourcePortRanges array = [] + +@sys.description('Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered') +param cuaId string = '' + +module pid_cuaId '.bicep/nested_cuaId.bicep' = if (!empty(cuaId)) { + name: 'pid-${cuaId}' + params: {} +} + +resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2021-05-01' existing = { + name: networkSecurityGroupName +} + +resource securityRule 'Microsoft.Network/networkSecurityGroups/securityRules@2021-05-01' = { + name: name + parent: networkSecurityGroup + properties: { + access: access + description: description + destinationAddressPrefix: destinationAddressPrefix + destinationAddressPrefixes: destinationAddressPrefixes + destinationApplicationSecurityGroups: destinationApplicationSecurityGroups + destinationPortRange: destinationPortRange + destinationPortRanges: destinationPortRanges + direction: direction + priority: priority + protocol: protocol + sourceAddressPrefix: sourceAddressPrefix + sourceAddressPrefixes: sourceAddressPrefixes + sourceApplicationSecurityGroups: sourceApplicationSecurityGroups + sourcePortRange: sourcePortRange + sourcePortRanges: sourcePortRanges + } +} + +@sys.description('The resource group the security rule was deployed into') +output resourceGroupName string = resourceGroup().name + +@sys.description('The resource ID of the security rule') +output resourceId string = securityRule.id + +@sys.description('The name of the security rule') +output name string = securityRule.name diff --git a/arm/Microsoft.Network/networkSecurityGroups/securityRules/readme.md b/arm/Microsoft.Network/networkSecurityGroups/securityRules/readme.md new file mode 100644 index 0000000000..aedb8ff78b --- /dev/null +++ b/arm/Microsoft.Network/networkSecurityGroups/securityRules/readme.md @@ -0,0 +1,44 @@ +# Network Security Groups Security Rules `[Microsoft.Network/networkSecurityGroups/securityRules]` + +This module deploys Network Security Group Security Rules. + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/networkSecurityGroups/securityRules` | 2021-05-01 | + +## Parameters + +| Parameter Name | Type | Default Value | Possible Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `access` | string | `Deny` | `[Allow, Deny]` | Optional. Whether network traffic is allowed or denied. | +| `cuaId` | string | | | Optional. Customer Usage Attribution ID (GUID). This GUID must be previously registered | +| `description` | string | | | Optional. A description for this rule | +| `destinationAddressPrefix` | string | | | Optional. The destination address prefix. CIDR or destination IP range. Asterisk "*" can also be used to match all source IPs. Default tags such as "VirtualNetwork", "AzureLoadBalancer" and "Internet" can also be used. | +| `destinationAddressPrefixes` | array | `[]` | | Optional. The destination address prefixes. CIDR or destination IP ranges. | +| `destinationApplicationSecurityGroups` | array | `[]` | | Optional. The application security group specified as destination. | +| `destinationPortRange` | string | | | Optional. The destination port or range. Integer or range between 0 and 65535. Asterisk "*" can also be used to match all ports. | +| `destinationPortRanges` | array | `[]` | | Optional. The destination port ranges. | +| `direction` | string | | `[Inbound, Outbound]` | Required. The direction of the rule. The direction specifies if rule will be evaluated on incoming or outgoing traffic. | +| `name` | string | | | Required. The name of the security rule | +| `networkSecurityGroupName` | string | | | Required. The name of the network security group to deploy the security rule into | +| `priority` | int | | | Required. The priority of the rule. The value can be between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule. | +| `protocol` | string | | `[*, Ah, Esp, Icmp, Tcp, Udp]` | Required. Network protocol this rule applies to. | +| `sourceAddressPrefix` | string | | | Optional. The CIDR or source IP range. Asterisk "*" can also be used to match all source IPs. Default tags such as "VirtualNetwork", "AzureLoadBalancer" and "Internet" can also be used. If this is an ingress rule, specifies where network traffic originates from. | +| `sourceAddressPrefixes` | array | `[]` | | Optional. The CIDR or source IP ranges. | +| `sourceApplicationSecurityGroups` | array | `[]` | | Optional. The application security group specified as source. | +| `sourcePortRange` | string | | | Optional. The source port or range. Integer or range between 0 and 65535. Asterisk "*" can also be used to match all ports. | +| `sourcePortRanges` | array | `[]` | | Optional. The source port ranges. | + +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the security rule | +| `resourceGroupName` | string | The resource group the security rule was deployed into | +| `resourceId` | string | The resource ID of the security rule | + +## Template references + +- [Networksecuritygroups/Securityrules](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/networkSecurityGroups/securityRules) diff --git a/arm/Microsoft.Network/networkSecurityGroups/securityRules/version.json b/arm/Microsoft.Network/networkSecurityGroups/securityRules/version.json new file mode 100644 index 0000000000..41f66cc990 --- /dev/null +++ b/arm/Microsoft.Network/networkSecurityGroups/securityRules/version.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", + "version": "0.1" +}