0
votes

I use the following Terraform ARM template to deploy to Azure Stack: ...

resource "azurestack_template_deployment" "nsg-rule1" {
  count = "${var.nsgr_map["nsg_sourceportranges"] == "" && var.nsgr_map["nsg_destinationportranges"] == "" && var.nsgr_map["nsg_sourceaddressprefixes"] == "" && var.nsgr_map["nsg_destinationaddressprefixes"] == "" ? 1 : 0}"
  name                = "${var.nsgr_map["nsg_rulename"]}"
  resource_group_name = "${var.nsgr_map["rsg_name"]}"

  template_body = <<DEPLOY
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "networkSecurityGroupName": {
            "type": "String"
        },
        "networkSecurityGroupRuleName": {
            "type" : "String"
        }, 
        "protocol" : {
            "type" : "String"
        },
        "sourcePortRange": {
            "type" : "String"
        },
        "destinationPortRange": {
            "type" : "String"
        },
        "sourceAddressPrefix" : {
            "type" : "String"
        },
        "destinationAddressPrefix" : {
            "type" : "String"
        },
        "access" : {
            "type" : "String"
        },
        "priority" : {
            "type" : "String"
        },
        "direction" : {
            "type" : "String"
        },
        "sourcePortRanges" : {
            "type" : "String"
        },
        "destinationPortRanges" : {
            "type" : "String"
        },
        "sourceAddressPrefixes" : {
            "type" : "String"
        },
        "destinationAddressPrefixes" : {
            "type" : "String"
        }
    },
    "variables": {},
    "resources": [
        {
            "type": "Microsoft.Network/networkSecurityGroups/securityRules",
            "apiVersion": "2017-10-01",
            "name": "[concat(parameters('networkSecurityGroupName'),'/',parameters('networkSecurityGroupRuleName'))]",
            "properties": {
                "protocol": "[parameters('protocol')]",
                "sourcePortRange": "[parameters('sourcePortRange')]",
                "destinationPortRange": "[parameters('destinationPortRange')]",
                "sourceAddressPrefix": "[parameters('sourceAddressPrefix')]",
                "destinationAddressPrefix": "[parameters('destinationAddressPrefix')]",
                "access": "[parameters('access')]",
                "priority": "[parameters('priority')]",
                "direction": "[parameters('direction')]",
                "sourcePortRanges": "[parameters('sourcePortRanges')]",
                "destinationPortRanges": "[parameters('destinationPortRanges')]",
                "sourceAddressPrefixes": "[parameters('sourceAddressPrefixes')]",
                "destinationAddressPrefixes": "[parameters('destinationAddressPrefixes')]"
            }
        }
    ]
}
DEPLOY

  # these key-value pairs are passed into the ARM Template's `parameters` block
  parameters = {
    networkSecurityGroupName = "${var.nsgr_map["nsg_name"]}"
    networkSecurityGroupRuleName = "${var.nsgr_map["nsg_rulename"]}"
    protocol = "${var.nsgr_map["nsg_protocol"]}"
    sourcePortRange = "${var.nsgr_map["nsg_source_portrange"]}"
    destinationPortRange = "${var.nsgr_map["nsg_destination_portrange"]}"
    sourceAddressPrefix ="${var.nsgr_map["nsg_sourceaddressprefix"]}"
    destinationAddressPrefix = "${var.nsgr_map["nsg_destinationaddressprefix"]}"
    access = "${var.nsgr_map["nsg_access"]}"
    priority = "${var.nsgr_map["nsg_priority"]}"
    direction = "${var.nsgr_map["nsg_direction"]}"
    sourcePortRanges = ""
    destinationPortRanges = ""
    sourceAddressPrefixes = ""
    destinationAddressPrefixes = ""
  }

  deployment_mode = "Incremental"
}

...

In fact I want to add to an existing Network Security Group (NSG) on Azure Stack, some NSG-rules. The problem is that if I deploy different rules with the same name under the same resource group the deployment fails because the NSG is not part of the ID, which identifies the resource to create.

In other words I have two rules with the same name - say 'NSG_Rule_Open_VPN' under the resource group 'Virtual_Network_1' but for two different network security groups 'nsg_1' and 'nsg_2'. Then the deployment fails with an error, because Terraform deploys the same resource twice (but the targeted NSG's are not the same)

If I look to the activity protocol on Azure Stack it becomes clear that Terraform doesn't use the name of the targeted NSG in the ID to create the resource:

"resourceId": "/subscriptions/yyyxxx/resourcegroups/RSG_99_VirtualNetwork_01/providers/Microsoft.Resources/deployments/NSR_out_TCP_allow_VMtoINTERNET-HTTPS",

It uses only the resource group name 'RSG_99_VirtualNetwork_01' and the rule name 'NSR_out_TCP_allow_VMtoINTERNET-HTTPS' but not the NSG name.

Is there a way to avoid this. so that Terraform creates a resourceID which also has a dependency to the NSG name?

1

1 Answers

0
votes

this happens because this is the deployment name, not the NSG rule name. so you need to update this bit to include nsg-name or some counter or something random:

resource "azurestack_template_deployment" "nsg-rule1" {
  count = not_important_removed
  name                = "${var.nsgr_map["nsg_rulename"]}" # this bit needs to be updated
  resource_group_name = "${var.nsgr_map["rsg_name"]}"