在 ARM 模板中循环遍历复杂的 JSON 变量
Looping through complex JSON variables in ARM templates
在我的 ARM 模板中,我有一个名为 "subnets" 的变量,它可以是 3 种类型。
如果是类型A,那么我想要给定名称和地址的4个子网;如果是 typeB,则 2 个子网,依此类推。
"variables": {
"subnets" : {
"typeA" : {
"network" : "3.0/24",
"directory" : "5.0/24",
"documents" : "8.0/24",
"security" : "10.0/24",
},
"typeB" : {
"directory" : "10.0/24",
"database" : "11.0/24",
},
"dmz" : {
"directory" : "12.0/24",
"database" : "15.0/24", }
}
}
在 ARM 模板中,我有一个参数告诉我要使用什么类型。所以我有一个像下面这样的段,它使用 condition
来匹配 subnetType
是 typeA
并相应地创建一个虚拟网络。
{
"type": "Microsoft.Network/virtualNetworks",
"condition" : "[contains(parameters('subnetType'), 'typeA')]",
"apiVersion": "2018-10-01",
...
"copy" : [ {
"name" : "subnets",
"count" : "[length(array(variables('subnets').typeA))]",
"input": {
"name": "...",
"properties": {
"addressPrefix": "..."
}
}
} ]
}
}
正如您在上面看到的,我在这个 VirtualNetwork 资源中有一个 copy
块,我想为 typeA
网络创建各种子网。我想我可以将 subnets.typeA
转换为一个数组并使其长度循环( 就是这个想法,我不知道它是否真的有效 )但我是不清楚如何从上面的变量中提取子网名称和地址前缀。
所以这里有 2 个问题:
- 无法在 arm 模板中循环对象键
- 使用模板中的不同资源创建子网
没有办法解决我所知道的第一个限制,而第二个限制主要是由于您试图解决第一个限制。我会采用完全不同的方法:
"networks": [
{
"name": "typeA",
"subnets": [
{
"name": "network",
"addressSpace": "3.0/24"
},
{
"name": "directory",
"addressSpace": "5.0/24"
},
{
"name": "documents",
"addressSpace": "8.0/24"
},
{
"name": "security",
"addressSpace": "10.0/24"
}
]
},
{
// second virtual network
},
{
// x virtual network
}
]
这里的主要缺点 - 你必须有一个嵌套部署,因为你实际上不能在数组中迭代数组,所以你必须将数组中的每个对象提供给一个部署,该部署将创建一个虚拟网络可以包含各种子网。
可以参考this link for an example of this exact approach or the official Azure Building Blocks thingie way of doing this(方法上很相似,但是实现方式不同)
你可以使用不同的资源而不是迭代,但这意味着你不太灵活,每次你对输入进行更改时,一切都会中断或者只是不像你想象的那样工作(你的做事方式如果 dmz
不存在于那个变量中,这将崩溃,你会得到一个编译错误,类似地,如果你向对象添加另一个键,说 applicationgateway
它会起作用,但虚拟网络不会' t 被创建)
在我的 ARM 模板中,我有一个名为 "subnets" 的变量,它可以是 3 种类型。
如果是类型A,那么我想要给定名称和地址的4个子网;如果是 typeB,则 2 个子网,依此类推。
"variables": {
"subnets" : {
"typeA" : {
"network" : "3.0/24",
"directory" : "5.0/24",
"documents" : "8.0/24",
"security" : "10.0/24",
},
"typeB" : {
"directory" : "10.0/24",
"database" : "11.0/24",
},
"dmz" : {
"directory" : "12.0/24",
"database" : "15.0/24", }
}
}
在 ARM 模板中,我有一个参数告诉我要使用什么类型。所以我有一个像下面这样的段,它使用 condition
来匹配 subnetType
是 typeA
并相应地创建一个虚拟网络。
{
"type": "Microsoft.Network/virtualNetworks",
"condition" : "[contains(parameters('subnetType'), 'typeA')]",
"apiVersion": "2018-10-01",
...
"copy" : [ {
"name" : "subnets",
"count" : "[length(array(variables('subnets').typeA))]",
"input": {
"name": "...",
"properties": {
"addressPrefix": "..."
}
}
} ]
}
}
正如您在上面看到的,我在这个 VirtualNetwork 资源中有一个 copy
块,我想为 typeA
网络创建各种子网。我想我可以将 subnets.typeA
转换为一个数组并使其长度循环( 就是这个想法,我不知道它是否真的有效 )但我是不清楚如何从上面的变量中提取子网名称和地址前缀。
所以这里有 2 个问题:
- 无法在 arm 模板中循环对象键
- 使用模板中的不同资源创建子网
没有办法解决我所知道的第一个限制,而第二个限制主要是由于您试图解决第一个限制。我会采用完全不同的方法:
"networks": [
{
"name": "typeA",
"subnets": [
{
"name": "network",
"addressSpace": "3.0/24"
},
{
"name": "directory",
"addressSpace": "5.0/24"
},
{
"name": "documents",
"addressSpace": "8.0/24"
},
{
"name": "security",
"addressSpace": "10.0/24"
}
]
},
{
// second virtual network
},
{
// x virtual network
}
]
这里的主要缺点 - 你必须有一个嵌套部署,因为你实际上不能在数组中迭代数组,所以你必须将数组中的每个对象提供给一个部署,该部署将创建一个虚拟网络可以包含各种子网。
可以参考this link for an example of this exact approach or the official Azure Building Blocks thingie way of doing this(方法上很相似,但是实现方式不同)
你可以使用不同的资源而不是迭代,但这意味着你不太灵活,每次你对输入进行更改时,一切都会中断或者只是不像你想象的那样工作(你的做事方式如果 dmz
不存在于那个变量中,这将崩溃,你会得到一个编译错误,类似地,如果你向对象添加另一个键,说 applicationgateway
它会起作用,但虚拟网络不会' t 被创建)