在 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 来匹配 subnetTypetypeA 并相应地创建一个虚拟网络。

{
    "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 个问题:

  1. 无法在 arm 模板中循环对象键
  2. 使用模板中的不同资源创建子网

没有办法解决我所知道的第一个限制,而第二个限制主要是由于您试图解决第一个限制。我会采用完全不同的方法:

"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 被创建)