0

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

模板如下:

{
  "$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 属性不能是表达式,因此不适用于我们的模板被使用和使用的方式。

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

4

1 回答 1

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 个不同的循环(您可以以相同的方式实现)

您当然可以使这变得更加复杂并参数化几乎任何东西(位置、不同的资源组、不同的附加属性),但我觉得这种复杂程度不会向表中添加任何内容,而是让您完全按照模板(如果你问我,这就是它变得无用的地方)。

于 2017-11-02T19:47:23.220 回答