[英]Azure ARM template how to use copy for multiple parts
我有一個找不到解決方案的問題,它是當我嘗試使用副本在我的儀表板 ARM 模板中動態創建多個部件時。
當我嘗試在其中一個鍵中使用“[copyIndex()]”時出現錯誤,正如我從錯誤消息中了解到的那樣,這將不起作用。 但我不確定如何解決這個問題,所以任何想法都會受到贊賞。
"copy": [
{
"name": "servers",
"count": "[length(parameters('locationKeys'))]",
"input": {
"[copyIndex('servers')]": {
"position": {
"x": "[mul(copyIndex('servers'), 4)]",
"y": 1,
"colSpan": 2,
"rowSpan": 1
}
}
}
}
]
正如您在上面的示例中看到的那樣,這是失敗的
"[copyIndex('servers')]": {
我得到這個錯誤
Error: Code=InvalidTemplate; Message=Deployment template validation failed:
'Can not add Newtonsoft.Json.Linq.JValue to Newtonsoft.Json.Linq.JObject.'.
創建儀表板的結構如下所示
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {
"0": {},
"1": {},
...
我在“零件”鍵下有副本 function。
解決這個問題的方法是刪除副本 function 並復制代碼,但是我很難讓它與任何給定數量的“位置”一起工作,因為我需要對它們進行硬編碼。
基本上這就是我最終想要得到的。
有沒有其他好的解決方案來解決這個問題?
更新
這是我從管道中的 Azure DevOps 任務中引用的兩個模板。 請注意,我現在需要執行參數('locationKeys')[0] 並復制所有塊,而不是使用參數('locationKeys')[copyIndex()] 進行復制。
參數.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"locationNames": {
"value": "#{locationNames}"
}
}
}
部署.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"defaultValue" : "myApp"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"dashboardName": "[concat(parameters('appName'), '-dashboard')]"
},
"resources": [
{
"name": "[variables('dashboardName')]",
"type": "Microsoft.Portal/dashboards",
"apiVersion": "2015-08-01-preview",
"location": "westeurope",
"tags": {
"hidden-title": "24/7 Operations"
},
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {
"0": {
"position": {
"x": 0,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[0])]",
"title": "",
"subtitle": ""
}
}
}
}
},
"1": {
"position": {
"x": 4,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[1])]",
"title": "",
"subtitle": ""
}
}
}
}
},
"2": {
"position": {
"x": 8,
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[2])]",
"title": "",
"subtitle": ""
}
}
}
}
}
}
}
}
},
"dependsOn": []
}
],
"outputs": {
"resourceGroupId": {
"type": "string",
"value": "[resourceGroup().id]"
}
}
}
更新 2
這是使用對象而不是數組的工作示例。 I verified it locally with PowerShell by uploading the collector.json and transform.json to http://myjson.com and include them as properties when running the deploy.
參數.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"azureEnvironment": {
"value": "#{azureEnvironment}"
},
"locationKeys": {
"value": "#{locationKeys}"
},
"locationNames": {
"value": "#{locationNames}"
},
"transformTemplateLink": {
"value": "#{transform}"
},
"collectorTemplateLink": {
"value": "#{collector}"
}
}
}
部署.json
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"defaultValue": "myApp"
},
"azureEnvironment": {
"type": "string"
},
"locationKeys": {
"type": "array"
},
"locationNames": {
"type": "array"
},
"transformTemplateLink": {
"type": "string",
"defaultValue": "[uri(deployment().properties.templateLink.uri, 'transform.json')]"
},
"collectorTemplateLink": {
"type": "string",
"defaultValue": "[uri(deployment().properties.templateLink.uri, 'collector.json')]"
}
},
"resources": [
{
"apiVersion": "2015-01-01",
"name": "collector",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('collectorTemplateLink')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"transformTemplateUri": {
"value": "[parameters('transformTemplateLink')]"
},
"locationNames": {
"value": "[parameters('locationNames')]"
}
}
}
},
{
"name": "[concat(parameters('appName'), '-dash-', parameters('azureEnvironment'))]",
"type": "Microsoft.Portal/dashboards",
"apiVersion": "2015-08-01-preview",
"location": "westeurope",
"tags": {
"hidden-title": "[concat('24/7 Operations - (', parameters('azureEnvironment'), ')')]"
},
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": "[reference('collector').outputs.result.value]"
}
}
},
"dependsOn": [
"collector"
]
}
],
"outputs": {
"resourceGroupId": {
"type": "string",
"value": "[resourceGroup().id]"
}
}
}
收集器.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"transformTemplateUri": {
"type": "string"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"count": "[length(parameters('locationNames'))]"
},
"resources": [
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "loop-0",
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [],
"outputs": {
"collection": {
"type": "object",
"value": {}
}
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "[concat('loop-', copyIndex(1))]",
"copy": {
"name": "iterator",
"count": "[variables('count')]",
"mode": "serial"
},
"dependsOn": [
"[concat('loop-', copyIndex())]"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[parameters('transformTemplateUri')]"
},
"parameters": {
"state": {
"value": "[reference(concat('loop-', copyIndex())).outputs.collection.value]"
},
"index": {
"value": "[copyIndex()]"
},
"locationNames": {
"value": "[parameters('locationNames')]"
}
}
}
}
],
"outputs": {
"result": {
"type": "object",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
}
變換.json
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"state": {
"type": "object",
"defaultValue": {}
},
"index": {
"type": "int"
},
"locationNames": {
"type": "array"
}
},
"variables": {
"instance": {
"[string(parameters('index'))]": {
"position": {
"x": "[mul(parameters('index'), 4)]",
"y": 0,
"colSpan": 4,
"rowSpan": 1
},
"metadata": {
"inputs": [],
"type": "Extension/HubsExtension/PartType/MarkdownPart",
"settings": {
"content": {
"settings": {
"content": "[concat('# ', parameters('locationNames')[parameters('index')])]",
"title": "",
"subtitle": ""
}
}
}
}
}
}
},
"resources": [],
"outputs": {
"collection": {
"type": "object",
"value": "[union(parameters('state'), variables('instance'))]"
}
}
}
如果僅在變量部分嘗試相同(但簡化)的方法,則會收到此錯誤:
變量名稱不能是表達式。
我認為這同樣適用於所有地方,您不能使用表達式來計算屬性名稱,而只能計算值。 話雖如此,如果您想創建一個循環,則需要使用嵌套部署作為迭代器。 您將在內部傳遞所需的片段\\根據輸入將它們組裝在那里並創建結果數組:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {
"locations": [
"eastus",
"westeurope"
],
"eastus": {
"red": 1
},
"westeurope": {
"blue": 2
},
"empty": []
},
"resources": [
{
"apiVersion": "2017-05-10",
"name": "[concat('iterator-', copyIndex(1))]",
"type": "Microsoft.Resources/deployments",
"copy": {
"name": "someName",
"count": "[length(variables('locations'))]"
},
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "https://paste.ee/r/t5ca9/0"
},
"parameters": {
"source": {
"value": "[variables(variables('locations')[copyIndex()])]"
},
"state": {
"value": "[if(equals(copyIndex(), 0), variables('empty'), reference(concat('iterator-', copyIndex())).outputs.collection.value)]"
}
}
}
}
],
"outputs": {
"results": {
"type": "array",
"value": "[reference(concat('iterator-', string(length(variables('locations'))))).outputs.collection.value]"
}
} }
您的迭代器如下所示:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"source": {
"type": "object"
},
"state": {
"type": "array",
"defaultValue": []
}
},
"resources": [],
"outputs": {
"collection": {
"type": "array",
"value": "[concat(array(parameters('source')), parameters('state'))]"
}
}
}
ps。 該鏈接是臨時鏈接(1個月),但是您可以將迭代器模板上傳到任何地方,只需硬編碼即可,它不包含任何秘密\\沒有數據。 pps。 更簡單的方法-在模板之外(powershell \\ python \\ whatever)構造此函數,並將其作為參數傳遞給tempate
我的天啊! 落入了完全相同的陷阱! 就像在第一個示例中一樣,復制索引應該可以工作!
"[copyIndex('servers')]": {
至少在閱讀了我的假設的 copyIndex 文檔之后! 看到這篇文章后,我嘗試以同樣的方式做到這一點! 但我幾乎花了半天! 真的覺得使用 PowerShell 創建自己的 JSON(ARM 模板)會節省我的時間!
$header = @'
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"properties": {
"lenses": {
"0": {
"order": 0,
"parts": {
'@
$footer = @"
}}}},
"name": "$($resourceGroupName)",
"type": "Microsoft.Portal/dashboards",
"location": "$($Location)",
"apiVersion": "2015-08-01-preview"
}]
}
"@
$parts = ""
for ($i = 0; $i -le $Totalplans; $i++)
{
$parts += @"
"$($i)": {
"position": {
"x": $($xIndex[$i]),
"y": $($yIndex[$i]),
"colSpan": 4,
"rowSpan": 4
},
"metadata": {
"inputs": [
{
"name": "sharedTimeRange",
"isOptional": true
},
{
"name": "options",
"value": {
"chart": {
"metrics": [
{
"resourceMetadata": {
"id": "$($ResourceIDs[$i])"
},
"name": "$($name[$i])",
"aggregationType": 4,
"namespace": "microsoft.web/serverfarms",
"metricVisualization": {
"displayName":"$($title[$i])",
"resourceDisplayName": "$($ResourceNames[$i])"
}
}
],
"title":"$($title[$i])",
"titleKind": 2,
"visualization": {
"chartType": 2,
"legendVisualization": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axisVisualization": {
"x": {
"isVisible": true,
"axisType": 2
},
"y": {
"isVisible": true,
"axisType": 1
}
}
},
"timespan": {
"relative": {
"duration": 3600000
},
"showUTCTime": false,
"grain": 2
}
}
},
"isOptional": true
}
],
"type": "Extension/HubsExtension/PartType/MonitorChartPart",
"settings": {
"content": {
"options": {
"chart": {
"metrics": [
{
"resourceMetadata": {
"id": "$($ResourceIDs[$i])"
},
"name": "$($name[$i])",
"aggregationType": 4,
"namespace": "microsoft.web/serverfarms",
"metricVisualization": {
"displayName":"$($title[$i])",
"resourceDisplayName":"$($ResourceNames[$i])"
}
}
],
"title": "$($title[$i])",
"titleKind": 2,
"visualization": {
"chartType": 2,
"legendVisualization": {
"isVisible": true,
"position": 2,
"hideSubtitle": false
},
"axisVisualization": {
"x": {
"isVisible": true,
"axisType": 2
},
"y": {
"isVisible": true,
"axisType": 1
}
},
"disablePinning": true
}
}
}
}
},
"filters": {
"MsPortalFx_TimeRange": {
"model": {
"format": "local",
"granularity": "1m",
"relative": "60m"
}
}
}
}
},
"@
}
$parts = $parts.Substring(0,$parts.Length-1)
Remove-Item "template.json" -Force -ErrorAction SilentlyContinue
"$($header)$($parts)$($footer)" >> "template.json"
我知道這是原始的,但上述解決方法也不是正確的方法!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.