Azure ARM 模板:将 NSG 或 Route Table 添加到动态 vnet/subnet 模板

Azure ARM Template: add NSG or Route Table to dynamic vnet/subnet template

我有一个模板,可以在每个 vnet 中部署多个 vnet 和多个子网。它不必在所有 vnet 中具有相同数量的子网。 效果很好。 但现在我想将 NSG 添加到其中一个子网,并将路由 table 添加到另一个子网。我无法正常工作 - 你们中的任何人都可以帮助我吗?

模板文件如下所示:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "VNET": {
            "type": "array"
        }
    },
    "variables": {},
    "resources": [
        {
            "apiVersion": "2017-05-10",
            "name": "[concat('Deploy-',parameters('VNET')[copyIndex('Vnets')].VnetName)]",
            "type": "Microsoft.Resources/deployments",
            "copy": {
                "name": "Vnets",
                "count": "[length(parameters('VNET'))]"
            },
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                        {
                            "apiVersion": "2017-10-01",
                            "type": "Microsoft.Network/virtualNetworks/",
                            "name": "[parameters('VNET')[copyIndex('Vnets')].VnetName]",
                            "location": "[resourceGroup().location]",
                            "tags": "[resourceGroup().tags]",
                            "properties": {
                                "addressSpace": {
                                    "addressPrefixes": [
                                        "[parameters('VNET')[copyIndex('Vnets')].VnetAddressSpace]"
                                    ]
                                },
                                "copy": [
                                    {
                                        "name": "subnets",
                                        "count": "[length(parameters('VNET')[copyIndex('Vnets')].Subnets)]",
                                        "input": {
                                            "name": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].name]",
                                            "properties": {
                                                "addressPrefix": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].addressPrefix]"
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            }
        }
    ],
    "outputs": {}
}

参数文件如下所示:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "VNET": {
            "value": [
                {
                    "VnetName": "Vnet-01",
                    "VnetAddressSpace": "10.11.0.0/16",
                    "Subnets": [
                        {
                            "name": "subnet-10-11-1-0-24",
                            "addressPrefix": "10.11.1.0/24"
                        },
                        {
                            "name": "subnet-10-11-2-0-24",
                            "addressPrefix": "10.11.2.0/24"
                        },
                        {
                            "name": "subnet-10-11-3-0-24",
                            "addressPrefix": "10.11.3.0/24"
                        }
                    ]
                },
                {
                    "VnetName": "Vnet-02",
                    "VnetAddressSpace": "10.12.0.0/16",
                    "Subnets": [
                        {
                            "name": "subnet-10-12-1-0-24",
                            "addressPrefix": "10.12.1.0/24"
                        },
                        {
                            "name": "subnet-10-12-2-0-24",
                            "addressPrefix": "10.12.2.0/24"
                        }
                    ]
                }
            ]
        }
    }
}

编辑: 添加 networkSecurityGroup 的行(见下文)后,只要将参数值设置为 null,我就可以使用它 但是我应该如何输入参数呢? 请参阅下面的错误消息。

"copy": [
                                    {
                                        "name": "subnets",
                                        "count": "[length(parameters('VNET')[copyIndex('Vnets')].Subnets)]",
                                        "input": {
                                            "name": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].name]",
                                            "properties": {
                                                "addressPrefix": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].addressPrefix]",
                                                "networkSecurityGroup": "[if(equals(json('null'), parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup), json('null'), resourceId('Microsoft.Network/networkSecurityGroups/',parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup))]"
                                            }
                                        }
                                    }
                                ]
"Subnets": [
                        {
                            "name": "subnet-10-11-1-0-24",
                            "addressPrefix": "10.11.1.0/24",
                            "networkSecurityGroup": "nsg-test"
                        },
                        {
                            "name": "subnet-10-11-2-0-24",
                            "addressPrefix": "10.11.2.0/24",
                            "networkSecurityGroup": null
                        },

错误信息:

"error": {
    "code": "InvalidRequestFormat",
    "message": "Cannot parse the request.",
    "details": [
      {
        "code": "MissingJsonReferenceId",
        "message": "Value for reference id is missing. Path properties.subnets[0].properties.networkSecurityGroup."
      }
    ]
  }

编辑 2: 如果我在所有子网上指定一个 NSG 名称,上面的代码就可以工作。 所以剩下要做的就是让它接受 null 作为值,如果我不想在其中一个子网上使用 NSG...

编辑 3: 做了一些更多的测试。 使用此模板,当我将参数设置为“name-of-nsg”但不设置为 null:

时它可以工作
"networkSecurityGroup": {
    "id": "[if(equals(json('null'), parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup), json('null'), resourceId('Microsoft.Network/networkSecurityGroups/',parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup))]"
}

使用此模板,当我将参数设置为 null 而不是“name-of-nsg”时,它会起作用:

"networkSecurityGroup": "[if(equals(json('null'), parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup), json('null'), resourceId('Microsoft.Network/networkSecurityGroups/',parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup))]"

我怎样才能让它同时适用于 null 和“name-of-nsg”?

我没有现成的示例,但它看起来像这样:

subnets:
- name: xxx-1
  addressPrefix: yyy
  nsg: < resourceId or something >
- name: xxx-2
  addressPrefix: yyy
  nsg: null

然后在您的模板中:

"copy": [
    {
        "name": "subnets",
        "count": "[length(parameters('VNET')[copyIndex('Vnets')].Subnets)]",
        "input": {
            "name": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].name]",
            "properties": {
                "addressPrefix": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].addressPrefix]"
                "networkSecurityGroup": "[if(eq(null, parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].nsg), json('null'), parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].nsg)]
            }
        }
    }
]

所以经过反复试验:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "VNET": {
            "type": "Array"
        }
    },
    "resources": [
        {
            "type": "Microsoft.Resources/deployments",
            "apiVersion": "2017-05-10",
            "name": "[concat('Deploy-',parameters('VNET')[copyIndex('Vnets')].VnetName)]",
            "properties": {
                "mode": "Incremental",
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "resources": [
                        {
                            "apiVersion": "2017-10-01",
                            "type": "Microsoft.Network/virtualNetworks/",
                            "name": "[parameters('VNET')[copyIndex('Vnets')].VnetName]",
                            "location": "eastus",
                            "properties": {
                                "addressSpace": {
                                    "addressPrefixes": [
                                        "[parameters('VNET')[copyIndex('Vnets')].VnetAddressSpace]"
                                    ]
                                },
                                "copy": [
                                    {
                                        "name": "subnets",
                                        "count": "[length(parameters('VNET')[copyIndex('Vnets')].Subnets)]",
                                        "input": {
                                            "name": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].name]",
                                            "properties": {
                                                "addressPrefix": "[parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].addressPrefix]",
                                                "networkSecurityGroup": "[if(equals(parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup, json('null')), json('null'), json(concat('{\"id\": \"', resourceId('Microsoft.Network/networkSecurityGroups', parameters('VNET')[copyIndex('Vnets')].Subnets[copyIndex('subnets')].networkSecurityGroup), '\"}')))]"
                                            }
                                        }
                                    }
                                ]
                            }
                        }
                    ]
                }
            },
            "copy": {
                "name": "Vnets",
                "count": "[length(parameters('VNET'))]"
            }
        }
    ]
}
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "VNET": {
            "value": [
                {
                    "VnetName": "Vnet-01",
                    "VnetAddressSpace": "10.11.0.0/16",
                    "Subnets": [
                        {
                            "name": "subnet-10-11-1-0-24",
                            "addressPrefix": "10.11.1.0/24",
                            "networkSecurityGroup": "nsg-test"
                        },
                        {
                            "name": "subnet-10-11-2-0-24",
                            "addressPrefix": "10.11.2.0/24",
                            "networkSecurityGroup": null
                        }
                    ]
                },
                {
                    "VnetName": "Vnet-02",
                    "VnetAddressSpace": "10.12.0.0/16",
                    "Subnets": [
                        {
                            "name": "subnet-10-12-1-0-24",
                            "addressPrefix": "10.12.1.0/24",
                            "networkSecurityGroup": "nsg-test"
                        }
                    ]
                }
            ]
        }
    }
}