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"
}
]
}
]
}
}
}
我有一个模板,可以在每个 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"
}
]
}
]
}
}
}