我正在尝试获取一系列参数 - 特别是电子邮件收件人列表 - 并将这些参数写入我的网络应用程序的应用程序设置。
以下模板可以工作但显然只能从数组中写入第一个和第二个项目。
我研究过复制功能,但这只能处理对象的创建,但我需要添加到现有的键值对列表中。
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
...
"parameters": {
"Email:Recipients": {
"type": "array"
},
...
"resources": [
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
...
"resources": [
{
"apiVersion": "2015-08-01",
"name": "appsettings",
"type": "config",
"properties": {
...
"Email:Recipients:0": "[parameters('Email:Recipients')[0]]",
"Email:Recipients:1": "[parameters('Email:Recipients')[1]]",
...
}
}
]
}
答案 0 :(得分:0)
您可以在属性对象中使用复制功能 - 请参阅:https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple#property-iteration
在部署模板之前,将其视为复制/粘贴操作类型。
答案 1 :(得分:0)
我有一个与您非常相似的用例:我希望用户指定用于分片的存储帐户数,并为模板创建所有存储帐户,然后为每个帐户添加一个连接字符串作为Web应用程序的应用程序设置以及我所有其他应用程序设置,格式为:
<other app settings>
...
"STORAGE_CONNECTION_STRING_00": "<connectionString00>",
"STORAGE_CONNECTION_STRING_01": "<connectionString01>",
...
我意识到我可能为时已晚,无法为您提供帮助,但是希望这会对其他人有所帮助。
该解决方案的关键在于,与其将应用程序设置指定为Microsoft.Web/sites
资源的子资源,而应在属性部分内联指定它们。至关重要的是,这使您可以将它们指定为对象数组,每个对象具有name
和value
属性,而不是问题中的一个大对象:
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
...
"properties": {
...
"siteConfig": {
"appSettings": [
{
name: "STORAGE_CONNECTION_STRING_00",
value: "<connectionString00>"
},
...
]
},
...
}
我第一次尝试使用copy
将我所有的连接字符串添加到此列表中:
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
...
"properties": {
"siteConfig": {
"copy": [
{
"name": "appSettings",
"count": "[parameters('resultsShardCount')]",
"input": {
"name": "[concat('STORAGE_CONNECTION_STRING_', padLeft(copyIndex('appSettings'), 2, '0'))]",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageDataAccountNames')[copyIndex('appSettings')],';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageDataAccountNames')[copyIndex('appSettings')]), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
}
}
]
}
},
...
}
这可行,但是不允许我在存储连接字符串旁边添加其他任何应用程序设置。
我尝试使用单独的appsettings
子资源添加其他应用设置,如最初的问题一样,希望将它们合并,但这只是覆盖了连接字符串。
接下来,我尝试定义两个变量,一个使用copy
定义连接字符串对象数组,另一个定义所有其他应用程序设置对象的静态数组。我想然后可以使用union
函数将它们组合起来:
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
...
"properties": {
"siteConfig": {
"appSettings": "[union(variables('additionalAppSettings), variables('storageAppSettings'))]"
}
},
...
}
不幸的是,模板变量被急切地求值,这意味着您不能引用任何资源属性。这对于评估连接字符串和其他一些我的应用程序设置都是一个问题,其中包含对我正在模板中部署的其他资源的引用。
研究该问题将导致查看嵌套模板,尤其是this Stack Overflow answer,以便在嵌套模板上使用copy
在数组中建立动态求值对象的列表。
在我碰到another limitation的ARM模板之前,这种方法看起来非常有前途:
对于嵌套模板,不能使用嵌套模板中定义的参数或变量。
解决方案是改用链接模板,但这对于应该是一个小问题来说是一个巨大的矫kill过正。
在挠头之后,我最终想出了一种方法,使其仅使用输出参数,使其能够使用嵌套模板工作:
...
{
"name": "reference0",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"dependsOn": [
"storageDataAccountCopy"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [],
"outputs": {
"storageAppSettings": {
"type": "array",
"value": []
},
"storageAppSetting": {
"type": "object",
"condition": "[greater(parameters('resultsShardCount'), 0)]",
"value": {
"name": "[concat('STORAGE_CONNECTION_STRING_', padLeft(0, 2, '0'))]",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageDataAccountNames')[0],';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageDataAccountNames')[0]), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
}
},
"additionalAppSettings": {
"type": "array",
"value": [
{
"name": "APPLICATION_INSIGHTS_KEY",
"value": "[reference(concat('Microsoft.Insights/components/', variables('applicationInsightsName'))).InstrumentationKey]"
}
...
]
}
}
}
}
},
{
"name": "[concat('reference', copyIndex(1))]",
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"copy": {
"name": "storageAppSettings",
"count": "[parameters('resultsShardCount')]"
},
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [],
"outputs": {
"storageAppSettings": {
"type": "array",
"value": "[concat(reference(concat('reference', copyIndex())).outputs.storageAppSettings.value, array(reference(concat('reference', copyIndex())).outputs.storageAppSetting.value))]"
},
"storageAppSetting": {
"type": "object",
"condition": "[less(copyIndex(1), parameters('resultsShardCount'))]",
"value": {
"name": "[concat('STORAGE_CONNECTION_STRING_', padLeft(copyIndex(1), 2, '0'))]",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageDataAccountNames')[min(variables('maximumShardIndex'), copyIndex(1))],';AccountKey=', listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('storageDataAccountNames')[min(variables('maximumShardIndex'), copyIndex(1))]), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value)]"
}
}
}
}
}
},
...
解释其工作原理:
reference0
部署用于:
storageAppSettings
数组输出为空数组。然后使用referenceN
遍历copy
部署,对于我要部署的每个分片,一个循环(或者在您的情况下,对每个电子邮件接收者)。每个人都执行以下操作:
storageAppSettings
数组作为storageAppSettings
数组和上一次迭代storageAppSetting
中生成的referenceN-1
对象的串联。Nth
storageAppSetting
对象。请注意,在最后一个referenceN
上,我们不需要输出storageAppSetting
,因为第一个是在reference0
中创建的,因此为了简洁起见,我们有一个condition
要停止那。不幸的是,即使存在condition
,value
仍会被求值,否则会导致索引超出范围,除非您使用min(variables('maximumShardIndex'), copyIndex(1))
之类的变量maximumShardIndex
来防止它出现,被定义为[sub(parameters('resultsShardCount'), 1)]
。另一个解决方法,但是在适当的地方它可以正常工作。
因此,最后一个storageAppSettings
输出的reference
数组是我们连接字符串应用程序设置对象的完整数组,而其他所有additionalAppSettings
输出的reference0
数组应用程序设置对象以及连接字符串。
最后,您可以在网络应用程序中将这两个数组的并集创建appSettings
数组:
{
"apiVersion": "2015-08-01",
"type": "Microsoft.Web/sites",
...
"properties": {
"siteConfig": {
"appSettings": "[union(reference('reference0').outputs.additionalAppSettings.value, reference(concat('reference', parameters('resultsShardCount'))).outputs.storageAppSettings.value)]"
}
},
...
}
我已经对此进行了测试,它已经成功部署了一个Web应用程序,该应用程序可以根据resultsShardCount
模板参数的指定,将数据分片到N个存储帐户中。
我认为为您提供的解决方案大致相同,不同之处在于,除了建立连接字符串name
/ value
对象的数组之外,您还将通过传递的收件人列表建立相似的数组进入您的模板。