使用 AzureRM 在同一 vnet 中部署不同子网的嵌套模板
Nesting templates that deploy different subnets in the same vnet with AzureRM
我正在尝试通过模板实现一定程度的容器化。最后,我希望能够在一个模板中定义驻留在虚拟网络和子网(如数据库集群)内的组件(一台或多台服务器)。通过另一个模板,定义驻留在虚拟网络和子网内的组件,但可能是不同的。
模板A:
- 我的虚拟网
- 我的子网 1
- 我的接口1
模板 B:
- 我的虚拟网
- 我的子网2
- 我的接口2
这样,将模板 B 嵌套在模板 A 中会让我得到:
模板 AB:
- 我的虚拟网
- 我的子网 1
- 我的接口1
- 我的子网2
- 我的接口2
相反,我收到以下错误:
New-AzureRmResourceGroupDeployment : 4:56:27 PM - Resource
Microsoft.Network/virtualNetworks 'overlayTest-vnet' failed with message '
{
"error": {
"code": "InUseSubnetCannotBeDeleted",
"message": "Subnet overlayTest-subnet2 is in use by /subscriptions/beep-boop/resourceGroups/d/providers/Microsoft.Network/networkInterfaces/overlayTest-vnet-interface2/ipConfigurations/ipconfig1 and cannot be deleted.",
"details": []
}
}
生成的资源组是这样填充的(就像部署了嵌套模板并且嵌套后的资源退出一样)。
模板 AB:
- 我的虚拟网
- 我的子网2
- 我的接口2
而我的模板如下:
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"vmIP": {
"type": "string",
"defaultValue": "10.0.100.100"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet1')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.100.0/24"
},
"subnetName2": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix2": {
"type": "string",
"defaultValue": "10.0.101.0/24"
},
"_artifactsLocation": {
"type": "string"
},
"_artifactsLocationSasToken": {
"type": "securestring"
}
},
"variables": {
"OverlaySubnetTemplateFolder": "nestedtemplates",
"OverlaySubnetTemplateFileName": "OverlaySubnet.json",
"OverlaySubnetTemplateParametersFileName": "OverlaySubnet.parameters.json",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "OverlaySubnet",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/', variables('OverlaySubnetTemplateFolder'), '/', variables('OverlaySubnetTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"solutionName": {
"value": "[parameters('solutionName')]"
}
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName2'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix2')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface1')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
nestedtemplates/OverlaySubnet.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.101.0/24"
}
},
"variables": {
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface2')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
在嵌套模板中将 VNet 资源更改为子网资源,它将起作用。你试图做的是创建一个新的 vnet 而不是现有的 vnet,因此它会尝试更新现有的 vnet 以匹配你的定义(因此删除所有子网并添加覆盖中定义的 1)。
但老实说,整个方法都是错误的,你应该使用属性复制循环并一次性完成所有事情。
最后,我实现了创建嵌套模板的目标,该模板在父模板的虚拟网络中定义了自己的子网,同时保持了在没有父模板的情况下部署嵌套模板的能力。关键是使用有条件的虚拟网络资源,并确保嵌套模板在嵌套时不会破坏父模板的虚拟网络。感谢@4c74356b41 将我推向正确的方向
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"vmIP": {
"type": "string",
"defaultValue": "10.0.100.100"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet1')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.100.0/24"
},
"subnetName2": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix2": {
"type": "string",
"defaultValue": "10.0.101.0/24"
},
"_artifactsLocation": {
"type": "string"
},
"_artifactsLocationSasToken": {
"type": "securestring"
}
},
"variables": {
"OverlaySubnetTemplateFolder": "nestedtemplates",
"OverlaySubnetTemplateFileName": "OverlaySubnet.json",
"OverlaySubnetTemplateParametersFileName": "OverlaySubnet.parameters.json",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "OverlaySubnet",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/', variables('OverlaySubnetTemplateFolder'), '/', variables('OverlaySubnetTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"solutionName": {
"value": "[parameters('solutionName')]"
},
"createVirtualNetwork": {
"value": "no"
}
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface1')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
nestedtemplates/OverlaySubnet.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"createVirtualNetwork": {
"type": "string",
"defaultValue": "yes",
"allowedValues": [
"yes",
"no"
]
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.101.0/24"
}
},
"variables": {
"createVirtualNetwork": "[equals(parameters('createVirtualNetwork'), 'yes')]",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"condition": "[variables('createVirtualNetwork')]",
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface2')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnetName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
我正在尝试通过模板实现一定程度的容器化。最后,我希望能够在一个模板中定义驻留在虚拟网络和子网(如数据库集群)内的组件(一台或多台服务器)。通过另一个模板,定义驻留在虚拟网络和子网内的组件,但可能是不同的。
模板A:
- 我的虚拟网
- 我的子网 1
- 我的接口1
- 我的子网 1
模板 B:
- 我的虚拟网
- 我的子网2
- 我的接口2
- 我的子网2
这样,将模板 B 嵌套在模板 A 中会让我得到:
模板 AB:
- 我的虚拟网
- 我的子网 1
- 我的接口1
- 我的子网2
- 我的接口2
- 我的子网 1
相反,我收到以下错误:
New-AzureRmResourceGroupDeployment : 4:56:27 PM - Resource
Microsoft.Network/virtualNetworks 'overlayTest-vnet' failed with message '
{
"error": {
"code": "InUseSubnetCannotBeDeleted",
"message": "Subnet overlayTest-subnet2 is in use by /subscriptions/beep-boop/resourceGroups/d/providers/Microsoft.Network/networkInterfaces/overlayTest-vnet-interface2/ipConfigurations/ipconfig1 and cannot be deleted.",
"details": []
}
}
生成的资源组是这样填充的(就像部署了嵌套模板并且嵌套后的资源退出一样)。
模板 AB:
- 我的虚拟网
- 我的子网2
- 我的接口2
- 我的子网2
而我的模板如下:
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"vmIP": {
"type": "string",
"defaultValue": "10.0.100.100"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet1')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.100.0/24"
},
"subnetName2": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix2": {
"type": "string",
"defaultValue": "10.0.101.0/24"
},
"_artifactsLocation": {
"type": "string"
},
"_artifactsLocationSasToken": {
"type": "securestring"
}
},
"variables": {
"OverlaySubnetTemplateFolder": "nestedtemplates",
"OverlaySubnetTemplateFileName": "OverlaySubnet.json",
"OverlaySubnetTemplateParametersFileName": "OverlaySubnet.parameters.json",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "OverlaySubnet",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/', variables('OverlaySubnetTemplateFolder'), '/', variables('OverlaySubnetTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"solutionName": {
"value": "[parameters('solutionName')]"
}
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName2'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix2')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface1')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
nestedtemplates/OverlaySubnet.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.101.0/24"
}
},
"variables": {
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface2')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
在嵌套模板中将 VNet 资源更改为子网资源,它将起作用。你试图做的是创建一个新的 vnet 而不是现有的 vnet,因此它会尝试更新现有的 vnet 以匹配你的定义(因此删除所有子网并添加覆盖中定义的 1)。
但老实说,整个方法都是错误的,你应该使用属性复制循环并一次性完成所有事情。
最后,我实现了创建嵌套模板的目标,该模板在父模板的虚拟网络中定义了自己的子网,同时保持了在没有父模板的情况下部署嵌套模板的能力。关键是使用有条件的虚拟网络资源,并确保嵌套模板在嵌套时不会破坏父模板的虚拟网络。感谢@4c74356b41 将我推向正确的方向
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"vmIP": {
"type": "string",
"defaultValue": "10.0.100.100"
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet1')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.100.0/24"
},
"subnetName2": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix2": {
"type": "string",
"defaultValue": "10.0.101.0/24"
},
"_artifactsLocation": {
"type": "string"
},
"_artifactsLocationSasToken": {
"type": "securestring"
}
},
"variables": {
"OverlaySubnetTemplateFolder": "nestedtemplates",
"OverlaySubnetTemplateFileName": "OverlaySubnet.json",
"OverlaySubnetTemplateParametersFileName": "OverlaySubnet.parameters.json",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'), '/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"name": "OverlaySubnet",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2016-09-01",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[concat(parameters('_artifactsLocation'), '/', variables('OverlaySubnetTemplateFolder'), '/', variables('OverlaySubnetTemplateFileName'), parameters('_artifactsLocationSasToken'))]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"solutionName": {
"value": "[parameters('solutionName')]"
},
"createVirtualNetwork": {
"value": "no"
}
}
}
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"mode": "Incremental",
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface1')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}
nestedtemplates/OverlaySubnet.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"solutionName": {
"type": "string",
"defaultValue": "testing"
},
"createVirtualNetwork": {
"type": "string",
"defaultValue": "yes",
"allowedValues": [
"yes",
"no"
]
},
"virtualNetworkName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'), '-vnet')]"
},
"vnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.0.0/16"
},
"subnetName": {
"type": "string",
"defaultValue": "[concat(parameters('solutionName'),'-subnet2')]"
},
"subnetAddressPrefix": {
"type": "string",
"defaultValue": "10.0.101.0/24"
}
},
"variables": {
"createVirtualNetwork": "[equals(parameters('createVirtualNetwork'), 'yes')]",
"vnetID": "[resourceId('Microsoft.Network/virtualNetworks',parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetID'),'/subnets/', parameters('subnetName'))]"
},
"resources": [
{
"condition": "[variables('createVirtualNetwork')]",
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/virtualNetworks",
"name": "[parameters('virtualNetworkName')]",
"location": "[resourceGroup().location]",
"dependsOn": [],
"properties": {
"addressSpace": {
"addressPrefixes": [
"[parameters('vnetAddressPrefix')]"
]
},
"subnets": [
{
"name": "[parameters('subnetName')]",
"properties": {
"mode": "Incremental",
"addressPrefix": "[parameters('subnetAddressPrefix')]"
}
}
],
"virtualNetworkPeerings": []
}
},
{
"type": "Microsoft.Network/virtualNetworks/subnets",
"name": "[concat(parameters('virtualNetworkName'), '/', parameters('subnetName'))]",
"apiVersion": "2017-06-01",
"properties": {
"addressPrefix": "[parameters('subnetAddressPrefix')]",
"privateAccessServices": []
},
"dependsOn": [
"[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]"
]
},
{
"apiVersion": "2015-06-15",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(parameters('virtualNetworkName'), '-interface2')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]",
"[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnetName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "ipconfig1",
"properties": {
/*
"privateIPAllocationMethod": "Static",
// reserved IP address range for /24 is 1-3, so start with [0 + 4] or more
"privateIPAddress": "[parameters('vmIP')]",
*/
"privateIPAllocationMethod": "Dynamic",
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
}
}
],
"outputs": {}
}