ARM模板参数对象数组转换为模板数组

时间:2017-11-02 16:34:07

标签: azure azure-resource-manager azure-template

我们正在尝试使用参数对象创建模板,因此可以选择在不同资源中使用多个值,即部署可能具有多个授权规则和eventhub的Event Hub命名空间,但另一个对象在第二个Event Hub命名空间的参数中,每个命名空间可能只有一个。

模板如下:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "eventhubs": {
      "type": "object",
      "metadata": {
        "description": "JSON object that describes the deployment. see example parameters file"
      }
    }
  },
  "variables": {
      "resourceNamePrefix": "[substring(resourceGroup().name, 0, 8)]",
      "datacenterCode": "[substring(resourceGroup().name, 0, 3)]",
      "productCode": "[substring(resourceGroup().name, 3, 3)]",
      "environmentLevel": "[substring(resourceGroup().name, 6, 2)]"
  },
"resources": [
  {
    "type": "Microsoft.EventHub/namespaces",
    "name": "[concat(variables('resourceNamePrefix'), parameters('eventhubs').instances[copyIndex()].name)]",
    "apiVersion": "2015-08-01",
    "location": "[resourceGroup().location]",
    "sku": {
      "name": "[concat(variables('resourceNamePrefix'), parameters('eventhubs').instances[copyIndex()].sku.name)]",
      "tier": "[parameters('eventhubs').instances[copyIndex()].sku.tier]",
      "capacity": "[parameters('eventhubs').instances[copyIndex()].sku.capacity]"
    },
    "copy": {
      "name": "eventHubCopy",
      "count": "[length(parameters('eventhubs').instances)]"
    },
    "properties": {
      "serviceBusEndpoint": "[concat('https://',variables('resourceNamePrefix'), parameters('eventhubs').instances[copyIndex()].name,'.servicebus.windows.net:443/')]",
      "enabled": "[parameters('eventhubs').instances[copyIndex()].properties.enabled]"
    },
    "resources": [
        *** PARAMETER OBJECT ***
    ]
    "dependsOn": []
      }
    ],
    "outputs": {}
  }

参数文件:

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
  "parameters": {
    "eventhubs": {
      "value": {
        "instances": [
          {
            "name": "EVT001",
            "sku": {
              "name": "Standard",
              "tier": "Standard",
              "capacity": 4
            },
            "scale": null,
            "properties": {
              "enabled": "true"
            },
            "resources": [
              {
                "type": "AuthorizationRules",
                "name": "SendKey",
                "apiVersion": "2015-08-01",
                "properties": {
                  "rights": [
                    "Send"
                  ]
                }
              },
              {
                "type": "AuthorizationRules",
                "name": "ListenKey",
                "apiVersion": "2015-08-01",
                "properties": {
                  "rights": [
                    "Listen"
                  ]
                }
              },
              {
                "type": "EventHub",
                "name": "TestHub",
                "apiVersion": "2015-08-01",
                "properties": {
                  "messageRetentionInDays": 7,
                  "status": "Active",
                  "partitionCount": 4
                }
              }
            ]
          },
          {
            "name": "EVT002",
            "sku": {
              "name": "Standard",
              "tier": "Standard",
              "capacity": 4
            },
            "scale": null,
            "properties": {
              "enabled": "true"
            },
            "resources": [
              {
                "type": "AuthorizationRules",
                "name": "SendKey",
                "apiVersion": "2015-08-01",
                "properties": {
                  "rights": [
                    "Send"
                  ]
                }
              },
              {
                "type": "EventHub",
                "name": "TestHub",
                "apiVersion": "2015-08-01",
                "properties": {
                  "messageRetentionInDays": 7,
                  "status": "Active",
                  "partitionCount": 4
                }
              },
              {
                "type": "EventHub",
                "name": "SecondHub",
                "apiVersion": "2015-08-01",
                "properties": {
                  "messageRetentionInDays": 7,
                  "status": "Active",
                  "partitionCount": 4
                }
              }
            ]
          }
        ]
      }
    }
  }
}

我尝试做的是将参数文件中资源数组的内容移动到模板文件中的嵌套资源数组中。将数组移动到对象中时可以这样做,但是我在数组中遇到以下问题:

"resources": "[parameters('eventhubs').instances[copyIndex()].properties]", <--- value must be of type array
"resources": [ { "[parameters('eventhubs').instances[copyIndex()].properties]" } ],  <--- expecting a name and value as it's in an object 
 "resources": [ "[parameters('eventhubs').instances[copyIndex()].properties]" ], <--- value must be of the following types: object

在参数文件中的数组中的对象周围添加另一组方括号也无济于事。

使用createArray函数时出现相同的错误。

我的解决方法是

    "resources": [
  {
    "type": "AuthorizationRules",
    "name": "[parameters('eventhubs').instances[copyIndex()].resources[0].name]",
    "apiversion": "[parameters('eventhubs').instances[copyIndex()].resources[0].apiversion]",
    "properties": "[parameters('eventhubs').instances[copyIndex()].resources[0].properties]",
    "dependsOn": [ "[concat(variables('resourceNamePrefix'), parameters('eventhubs').instances[copyIndex()].name)]" ]
  }
],

但是type属性不能是一个表达式,因此我们的模板将被消耗和使用的方式不起作用。

是否有可能做我正在尝试的事情?

1 个答案:

答案 0 :(得分:1)

这真的不符合答案(我很遗憾,没有时间输出所有解释),但你基本上是在寻找单独的配置和实现(这是明智之举) ,但ARM模板并不像你想象的那样直截了当。我会尝试创建一个mcve。它会非常抽象,但你只需要这个想法。

所以前提是:您需要部署具有不同属性的X数量的资源。

您配置数据如下所示:

"eventhubs": [
    {
        "name": "EVT001",
        "sku": skuobject,
        "scale": null,
        "properties": propertiesobject,
        "resources": [
            nestedobject,
            nestedobject,
            nestedobject
        ]
    },
    parentobject,
]

这个对象是数组内部父对象内部数组的嵌套对象(我建议你删除最外面的对象,因为它没用,除了增加复杂性外什么都不做)。您的操作过程,在复制循环中迭代最外层(父对象)数组,并尝试迭代资源属性中的最内层(嵌套对象)数组。这对ARM模板不起作用。

使用arm模板,您只能迭代一个级别(使用循环,硬编码可以根据需要进行深度调整),因此您需要做的是将配置对象拆分为1级深度的对象。您的对象是2级深度(父对象数组和嵌套对象数组)。你可以通过嵌套部署来做到这一点。

你需要做的是这样的事情:

{
    "name": "[concat('nested-', copyIndex())]",
    "type": "Microsoft.Resources/deployments",
    "apiVersion": "2016-06-01",
    "copy": {
        "name": "eventHubLoop",
        "count": "[length(parameters('eventhubs'))]" (this should be an array)
    },
    "properties": {
        "mode": "Incremental",
        "templateLink": {
            "uri": "xxx",
            "contentVersion": "1.0.0.0"
        },
        "parameters": {
            "currentIteration": {
                "value": "[parameters('eventhubs')[copyIndex()]]"
            }
        }
    }
}

并且您的嵌套模板应该是父资源(没有副本,因为它始终是单个资源,我们通过上面的循环处理了它)和properties \ resources循环。不幸的是我没有一个方便的例子(nda),但我希望你明白这个想法。你需要创建2个不同的循环,这样你就可以处理你的嵌套级别,如果你有3个级别的嵌套,你需要3个不同的循环(你可以用同样的方式实现)

你当然可以使这个更加复杂和参数化几乎任何东西(位置,不同的资源组,不同的附加属性),但我觉得这种复杂程度不会给表添加任何东西,而是让你创建一个属性文件完全作为一个模板(如果你问我,这就是它变得无用的地方)。