在 Azure Resource Manager 範本中實作屬性轉換器與收集器
在Azure Resource Manager 範本的複製迴圈中使用物件作為參數,您可以看到如何在物件中儲存資源屬性值,以及如何在部署期間將它們套用至資源。 這是管理參數的非常有用方式,但每次您在範本中使用 物件時,都需要您將物件的屬性對應至資源屬性。
若要解決此問題,您可以實作屬性轉換和收集器範本,以逐一查看物件陣列,並將其轉換成資源的 JSON 架構。
重要
採取這種做法,您需要十分熟悉 Resource Manager 範本和函式。
讓我們看看實作屬性收集器和轉換器以部署 網路安全性群組的範例。 下圖顯示我們的範本如何與這些範本中的資源相關:
我們的呼叫範本有兩個資源:
- 叫用收集器範本的範本連結
- 要部署的網路安全性群組資源
我們的收集器範本有兩個資源:
- 錨點資源
- 在複製迴圈中叫用轉換範本的範本連結
我們的 轉換範本 包含單一資源:具有變數的空白範本,可將 source
JSON 轉換成 主要範本中網路安全性群組資源預期的 JSON 架構。
參數物件
我們使用 Azure securityRules
Resource Manager 範本中複製迴圈中的參數物件,將物件當做參數使用。 我們的轉換範本會將陣列中的每個物件轉換成呼叫範本中 securityRules
網路安全性群組資源預期的 JSON 架構。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"networkSecurityGroupsSettings": {
"value": {
"securityRules": [
{
"name": "RDPAllow",
"description": "allow RDP connections",
"direction": "Inbound",
"priority": 100,
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "10.0.0.0/24",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"access": "Allow",
"protocol": "Tcp"
},
{
"name": "HTTPAllow",
"description": "allow HTTP connections",
"direction": "Inbound",
"priority": 200,
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "10.0.1.0/24",
"sourcePortRange": "*",
"destinationPortRange": "80",
"access": "Allow",
"protocol": "Tcp"
}
]
}
}
}
}
先來看看轉換範本。
轉換範本
我們的轉換範本包含從收集器範本傳來的兩個參數:
-
source
是物件,會接收屬性陣列的其中一個屬性值物件。 在我們的範例中securityRules
,陣列中的每個物件一次都會傳遞一個。 -
state
是陣列,會接收所有先前轉換後的結果串連。 這是轉換後 JSON 的集合。
我們的參數看起來像這樣:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"source": {
"type": "object"
},
"state": {
"type": "array",
"defaultValue": []
}
},
我們的範本也會定義名為 instance
的變數,將物件 source
轉換成必要的 JSON 架構:
"variables": {
"instance": [
{
"name": "[parameters('source').name]",
"properties": {
"description": "[parameters('source').description]",
"protocol": "[parameters('source').protocol]",
"sourcePortRange": "[parameters('source').sourcePortRange]",
"destinationPortRange": "[parameters('source').destinationPortRange]",
"sourceAddressPrefix": "[parameters('source').sourceAddressPrefix]",
"destinationAddressPrefix": "[parameters('source').destinationAddressPrefix]",
"access": "[parameters('source').access]",
"priority": "[parameters('source').priority]",
"direction": "[parameters('source').direction]"
}
}
]
}
最後,我們的範本的 會 output
串連參數所收集的 state
轉換,以及變數 instance
所執行的目前轉換:
"resources": [],
"outputs": {
"collection": {
"type": "array",
"value": "[concat(parameters('state'), variables('instance'))]"
}
}
接下來,讓我們看看 收集器範本 ,以查看其如何傳遞我們的參數值。
收集器範本
我們的收集器範本包含三個參數:
-
source
是完整的參數物件陣列, 它會由 呼叫範本傳遞。 它的名稱與source
轉換範本中的 參數相同,但有一個主要差異:雖然它是完整的陣列,但我們一次只會將一個陣列元素傳遞至 轉換範本。 -
transformTemplateUri
是轉換範本的 URI。 我們會將其定義為範本重複使用的參數。 -
state
一開始是空陣列,由我們傳遞給轉換範本。 它會在複製迴圈完成後儲存已轉換之參數物件的集合。
我們的參數看起來像這樣:
"parameters": {
"source": {
"type": "array"
},
"transformTemplateUri": {
"type": "string"
},
"state": {
"type": "array",
"defaultValue": []
}
}
接下來,我們要定義名為 count
的變數。 其值是 source
參數物件陣列的長度:
"variables": {
"count": "[length(parameters('source'))]"
}
我們會將其用於複製迴圈中的反復專案數目。
現在,來看看我們的資源。 我們定義兩個資源︰
-
loop-0
是複製迴圈的從零開始編號的資源。 -
loop-
會與copyIndex(1)
函式的結果串連,產生以反覆項目編號的唯一資源名稱,從1
開始。
我們的資源看起來會像這樣:
"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": "array",
"value": "[parameters('state')]"
}
}
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2015-01-01",
"name": "[concat('loop-', copyindex(1))]",
"copy": {
"name": "iterator",
"count": "[variables('count')]",
"mode": "serial"
},
"dependsOn": [
"loop-0"
],
"properties": {
"mode": "Incremental",
"templateLink": { "uri": "[parameters('transformTemplateUri')]" },
"parameters": {
"source": { "value": "[parameters('source')[copyindex()]]" },
"state": { "value": "[reference(concat('loop-', copyindex())).outputs.collection.value]" }
}
}
}
]
讓我們進一步瞭解我們在巢狀範本中傳遞至 轉換範本 的參數。 回想前面,source
參數將目前的物件傳遞給 source
參數物件陣列。 參數 state
是集合發生的位置,因為它會取得複製迴圈先前反復專案的輸出,並將它傳遞至目前的反復專案。 請注意,函 reference()
式會 copyIndex()
使用沒有參數的 函式來參考 name
先前連結範本物件的 。
最後,範本的 output
傳回轉換範本最後一個反覆運算的 output
:
"outputs": {
"result": {
"type": "array",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
將轉換範本的最後一個反復專案傳回 output
至呼叫範本似乎很直覺,因為我們將它儲存在 參數中 source
。 不過,這是 轉換範本 的最後一個反復專案,可保存已轉換屬性物件的完整陣列,這就是我們想要傳回的內容。
最後,讓我們看看如何從呼叫範本呼叫收集器範本。
呼叫範本
我們的呼叫範本會定義一個名為 networkSecurityGroupsSettings
的參數:
...
"parameters": {
"networkSecurityGroupsSettings": {
"type": "object"
}
}
我們的範本會定義一個名為 collectorTemplateUri
的參數:
"variables": {
"collectorTemplateUri": "[uri(deployment().properties.templateLink.uri, 'collector.template.json')]"
}
這是連結範本資源所使用的 收集器範本 URI:
{
"apiVersion": "2020-06-01",
"name": "collector",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('collectorTemplateUri')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"source": {
"value": "[parameters('networkSecurityGroupsSettings').securityRules]"
},
"transformTemplateUri": {
"value": "[uri(deployment().properties.templateLink.uri, 'transform.json')]"
}
}
}
}
我們傳遞兩個參數給收集器範本:
-
source
是屬性物件陣列。 在我們的範例中是networkSecurityGroupsSettings
參數。 -
transformTemplateUri
是我們剛才使用 收集器範本URI 定義的變數。
最後,Microsoft.Network/networkSecurityGroups
資源將 collector
連結範本資源的 output
直接指派給其 securityRules
屬性:
"resources": [
{
"apiVersion": "2020-05-01",
"type": "Microsoft.Network/networkSecurityGroups",
"name": "networkSecurityGroup1",
"location": "[resourceGroup().location]",
"properties": {
"securityRules": "[reference('collector').outputs.result.value]"
}
}
],
"outputs": {
"instance": {
"type": "array",
"value": "[reference('collector').outputs.result.value]"
}
}
試用範本
您可以在 GitHub 上取得範本範例。 若要部署範本,請複製報告並執行下列 Azure CLI 命令:
git clone https://github.com/mspnp/template-examples.git
cd template-examples/example4-collector
az group create --location <location> --name <resource-group-name>
az deployment group create -g <resource-group-name> \
--template-uri https://raw.githubusercontent.com/mspnp/template-examples/master/example4-collector/deploy.json \
--parameters deploy.parameters.json
下一步
- Azure Resource Manager
- 什麼是 ARM 範本?
- 教學課程:建立及部署您的第一個 ARM 範本
- 教學課程:將資源新增至 ARM 範本
- ARM 範本最佳做法
- Azure Resource Manager 文件
- ARM 範本文件