我正在尝试使用一系列参数 - 特别是电子邮件收件人列表 - 并将其写入我的Web应用程序的应用程序设置。
以下模板有效,但是 - 显然 - 仅写入数组中的第一项和第二个项目。
我已经研究了复制功能,但这似乎只能处理对象的创建,但我需要添加到键值对的现有列表中。
{
"$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]]",
...
}
}
]
}
我的用例非常相似:我希望用户指定要用于碎片的存储帐户的数量存储帐户,然后每个人都将连接字符串与我所有其他应用程序设置一起以:
以及我所有其他应用程序设置并肩设置添加连接字符串。<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'))]"
}
},
...
}
不幸的是,模板变量热切地评估,这意味着您无法参考任何资源属性。这是评估连接字符串的问题,也是我的其他应用程序设置,其中包含我在模板中部署的其他资源的引用。
。研究这个问题会导致查看嵌套模板,尤其是此堆栈溢出答案,用于在数组中使用嵌套模板上的copy
在数组中构建动态评估的对象列表。
这种方法看起来很有希望,直到我达到了另一个手臂模板的限制:
对于嵌套模板,您不能使用嵌套模板中定义的参数或变量。
解决方案是使用链接模板,但这是一个巨大的过度杀伤,应该是一个琐碎的问题。
在刮擦一些头后,我最终找出了一种适应它仅使用输出参数的方法,从而使其可以使用嵌套模板进行工作:
...
{
"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
数组作为空数组输出。 - 输出第一个连接字符串应用程序设置对象。
- 输出Web应用程序要求的所有其他应用程序设置对象的数组。
然后,使用copy
将referenceN
部署用于循环,我想部署的每个碎片之一(或在您的情况下,每个电子邮件接收者)。每个人都执行以下操作:
- 输出新的
storageAppSettings
数组作为storageAppSettings
数组的串联和上一个迭代referenceN-1
中生成的storageAppSetting
对象。 - 输出
Nth
storageAppSetting
对象。
请注意,在最终的referenceN
中,我们不需要输出storageAppSetting
,因为第一个是在reference0
中创建的,因此,为了整洁,我们有一个condition
来停止它。不幸的是,即使存在condition
,value
仍会被评估,除非您使用诸如min(variables('maximumShardIndex'), copyIndex(1))
之类的内容来防止端口错误,否则将变量maximumShardIndex
定义为[sub(parameters('resultsShardCount'), 1)]
。另一个解决方法,但随之而来的是它可以正常工作。
最终reference
的storageAppSettings
数组输出是我们的完整连接字符串应用程序设置对象的完整数组,而additionalAppSettings
数组来自reference0
是我们想要的所有其他应用程序设置对象,我们与连接字符串一起使用。
因此,最后您可以在Web应用中创建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)]"
}
},
...
}
我已经对此进行了测试,并且已经成功部署了一个针对N个存储帐户的数据,如resultsShardCount
模板参数。
我认为,您的解决方案看起来会大致相同,除非建立连接字符串name
/value
对象,您会从接收器列表中构建一个类似的数组,从而传递给模板。
您可以在属性对象中使用复制函数 - 请参阅:https://learn.microsoft.com/en-us/azure/azure-resource-resource-manager/Resource-Group--创建#property-ititeration
将其视为部署模板之前的复制/糊状操作类型。