Implementera en egenskapsomvandel och insamlare i Azure Resource Manager mall
I Använda ett objekt som en parameter i en Azure Resource Manager mallhar du lärt dig att lagra resursegenskapsvärden i ett objekt och tillämpa dem på en resurs under distributionen. Detta är ett mycket användbart sätt att hantera parametrarna, men det kräver fortfarande att du mappar objektets egenskaper till resursegenskaper varje gång du använder det i mallen.
Du kan komma runt detta genom att implementera en egenskapstransform och en insamlarmall som itererar objektmatrisen och transformerar den till det JSON-schema som förväntas av resursen.
Viktigt
Den här metoden kräver att du har en djup förståelse Resource Manager mallar och funktioner.
Låt oss ta en titt på hur vi kan implementera en egenskapsinsamlare och transformering med ett exempel som distribuerar en nätverkssäkerhetsgrupp. Diagrammet nedan visar relationen mellan våra mallar och våra resurser i dessa mallar:

Vår anropsmall innehåller två resurser:
- En malllänk som anropar vår insamlarmall.
- Nätverkssäkerhetsgruppens resurs som ska distribueras.
Vår insamlingsmall innehåller två resurser:
- En fästpunktsresurs.
- En malllänk som anropar transformeringsmallen i en kopieringsloop.
Vår transformeringsmall innehåller en enskild resurs: en tom mall med en variabel som omvandlar vår JSON till det JSON-schema som förväntas av nätverkssäkerhetsgruppens resurs i huvudmallen.
Parameterobjekt
Vi använder parameterobjektet securityRules från objekt som securityRules. Vår transformeringsmall omvandlar varje objekt i matrisen till det JSON-schema som förväntas av nätverkssäkerhetsgruppens resurs i vår anropande mall.
{
"$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"
}
]
}
}
}
}
Låt oss titta på vår transformeringsmall först.
Transformera mall
Vår transformeringsmall innehåller två parametrar som skickas från insamlarmallen:
sourceär ett objekt som tar emot ett av egenskapsvärdets objekt från egenskapsmatrisen. I vårt exempel skickas varje objekt"securityRules"från matrisen i ett i taget.stateär en matris som tar emot de sammanfogade resultaten från alla tidigare transformeringar. Det här är samlingen med transformerade JSON.
Våra parametrar ser ut så här:
{
"$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": []
}
},
Vår mall definierar också en variabel med namnet instance . Den utför den faktiska transformeringen av objektet source till det JSON-schema som krävs:
"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]"
}
}
]
}
Slutligen sammanfogar för vår mall de insamlade transformeringarna av parametern med den aktuella outputstate transformeringen som utförs av instance variabeln:
"resources": [],
"outputs": {
"collection": {
"type": "array",
"value": "[concat(parameters('state'), variables('instance'))]"
}
}
Nu ska vi ta en titt på vår insamlarmall för att se hur den skickar in våra parametervärden.
Mall för insamlare
Vår insamlarmall innehåller tre parametrar:
sourceär vår fullständiga parameterobjektmatris. Den skickas via den anropande mallen. Detta har samma namn som parametern i vår transformeringsmall, men det finns en viktig skillnad som du kanske redan har märkt: det här är den fullständiga matrisen, men vi skickar bara ett element i matrisen till transformeringsmallensourcei taget.sourcetransformTemplateUriär URI:en för vårtransformTemplateUri. Vi definierar det som en parameter här för återanvändning av mallar.stateär en ursprungligen tom matris som vi skickar tillstate. Den lagrar samlingen med transformerade parameterobjekt när kopieringsloopen är klar.
Våra parametrar ser ut så här:
"parameters": {
"source": {
"type": "array"
},
"transformTemplateUri": {
"type": "string"
},
"state": {
"type": "array",
"defaultValue": []
}
}
Därefter definierar vi en variabel med namnet count . Dess värde är längden på source parameterobjektmatrisen:
"variables": {
"count": "[length(parameters('source'))]"
}
Som du misstänker använder vi den för antalet iterationer i vår kopieringsloop.
Nu ska vi ta en titt på våra resurser. Vi definierar två resurser:
loop-0är den nollbaserade resursen för vår kopieringsloop.loop-sammanfogas med resultatet av funktionen för att generera ett unikt iterationsbaserat namn för vår resurs, medcopyIndex(1)början från1.
Våra resurser ser ut så här:
"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]" }
}
}
}
]
Låt oss ta en närmare titt på de parametrar som vi vidarebefordrar till transformeringsmallen i den kapslade mallen. Kom ihåg att parametern source skickar det aktuella objektet i source parameterobjektmatrisen. Parametern är den plats där samlingen sker, eftersom den tar utdata från den tidigare iterationen av vår kopieringsloop – observera att funktionen använder funktionen utan parameter för att referera till för vårt tidigare länkade mallobjekt – och skickar den till den aktuella statereference()copyIndex()name iterationen.
Slutligen returnerar output för vår mall den senaste output iterationen av output:
"outputs": {
"result": {
"type": "array",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
Det kan verka kontraintuitivt att returnera den senaste iterationen av transformeringsmallen till vår anropande mall eftersom den visade sig att vi lagrar den output i output parametern. Kom dock ihåg att det är den senaste iterationen av vår transformeringsmall som innehåller hela matrisen med transformerade egenskapsobjekt, och det är vad vi vill returnera.
Slutligen tar vi en titt på hur du anropar insamlarmallen från vår anropande mall.
Anropa mall
Vår anropsmall definierar en enda parameter med namnet :
...
"parameters": {
"networkSecurityGroupsSettings": {
"type": "object"
}
}
Sedan definierar mallen en enskild variabel med namnet collectorTemplateUri :
"variables": {
"collectorTemplateUri": "[uri(deployment().properties.templateLink.uri, 'collector.template.json')]"
}
Som förväntat är detta URI:en för insamlarmallen som ska användas av vår länkade mallresurs:
{
"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')]"
}
}
}
}
Vi skickar två parametrar till insamlarmallen:
sourceär vår egenskapsobjektmatris. I vårt exempel är det vårnetworkSecurityGroupsSettingsparameter.transformTemplateUriär variabeln som vi precis definierade med URI:en för vårtransformTemplateUri.
Slutligen Microsoft.Network/networkSecurityGroups tilldelar vår resurs den länkade outputcollector mallresursens egenskap securityRules direkt:
"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]"
}
}
Testa mallen
En exempelmall finns på GitHub. Om du vill distribuera mallen klonar du lagringsplatsen och kör följande Azure CLI-kommandon:
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