Implementieren eines Transformers und Collectors für Eigenschaften in eine Azure Resource Manager-Vorlage
Im Artikel Verwenden von Objekten als Parameter in einer Kopierschleife in einer Azure Resource Manager-Vorlage erfahren Sie, wie die Werte von Ressourceneigenschaften in einem Objekt gespeichert und bei der Bereitstellung auf eine Ressource angewendet werden. Dies ist eine sehr gute Möglichkeit, um Ihre Parameter zu verwalten. Bei jeder Verwendung des Objekts in Ihrer Vorlage müssen Sie aber trotzdem weiterhin die Eigenschaften des Objekts den Ressourceneigenschaften zuordnen.
Zur Umgehung dieses Problems können Sie eine Vorlage für die Transformation und Sammlung von Eigenschaften (Transformer und Collector) implementieren, mit der das Objektarray durchlaufen und in das JSON-Schema für die Ressource transformiert wird.
Wichtig
Für diesen Ansatz ist es erforderlich, dass Sie eingehend mit Resource Manager-Vorlagen und -Funktionen vertraut sind.
Sehen wir uns ein Beispiel an, das einen Eigenschaften-Collector und -Transformer für die Bereitstellung einer Netzwerksicherheitsgruppe implementiert. Das folgende Diagramm veranschaulicht die Beziehungen unserer Vorlagen zu den Ressourcen in diesen Vorlagen:
Unsere aufrufende Vorlage enthält zwei Ressourcen:
- Ein Vorlagenlink, über den die Collector-Vorlage aufgerufen wird
- Die bereitzustellende Ressource der Netzwerksicherheitsgruppe
Unsere Collector-Vorlage enthält zwei Ressourcen:
- Eine anchor-Ressource
- Ein Vorlagenlink, über den die Transformer-Vorlage in einer Kopierschleife aufgerufen wird
Unsere Transformer-Vorlage enthält eine einzelne Ressource: eine leere Vorlage mit einer Variablen, die den source
-JSON-Code in das JSON-Schema transformiert, der von der Netzwerksicherheitsgruppen-Ressource in der Hauptvorlage erwartet wird.
Parameterobjekt
Wir verwenden unser securityRules
-Parameterobjekt aus Verwenden von Objekten als Parameter in einer Kopierschleife in einer Azure Resource Manager-Vorlage. Mit der Transformer-Vorlage wird jedes Objekt im Array securityRules
in das JSON-Schema transformiert, das von der Netzwerksicherheitsgruppen-Ressource in unserer aufrufenden Vorlage erwartet wird.
{
"$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"
}
]
}
}
}
}
Wir sehen uns zuerst die Transformer-Vorlage an.
Transformer-Vorlage
Die Transformer-Vorlage enthält zwei Parameter, die von der Collector-Vorlage übergeben werden:
-
source
ist ein Objekt, das eines der Eigenschaftswertobjekte aus dem Eigenschaftenarray empfängt. In unserem Beispiel wird jedes Objekt aus demsecurityRules
-Array einzeln übergeben. -
state
ist ein Array, das die verketteten Ergebnisse aller vorherigen Transformationen empfängt. Dies ist die Sammlung mit dem transformierten JSON-Code.
Unsere Parameter sehen wie folgt aus:
{
"$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": []
}
},
Unsere Vorlage definiert auch eine Variable namens instance
, die unser source
-Objekt in das erforderliche JSON-Schema transformiert:
"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]"
}
}
]
}
Abschließend werden in der Ausgabe (output
) unserer Vorlage die gesammelten Transformationen des Parameters state
mit der aktuellen Transformation verkettet, die von der Variablen instance
durchgeführt wird:
"resources": [],
"outputs": {
"collection": {
"type": "array",
"value": "[concat(parameters('state'), variables('instance'))]"
}
}
Als Nächstes sehen wir uns unsere Collector-Vorlage an, um zu sehen, wie die Parameterwerte übergeben werden.
Collector-Vorlage
Die Collector-Vorlage enthält drei Parameter:
-
source
ist unser vollständiges Parameterobjektarray. Es wird von der aufrufenden Vorlage übergeben. Es weist den gleichen Namen wie dersource
-Parameter in unserer Transformer-Vorlage auf. Es gibt jedoch einen wichtigen Unterschied: Obwohl es sich um das vollständige Array handelt, wird jeweils nur ein Arrayelement an die Transformer-Vorlage übergeben. -
transformTemplateUri
ist der URI der Transformer-Vorlage. Wir definieren ihn als Parameter, um die Vorlage wiederverwenden zu können. -
state
ist ein ursprünglich leeres Array, das wir an die Transformer-Vorlage übergeben. Darin wird die Sammlung mit den transformierten Parameterobjekten gespeichert, nachdem die Kopierschleife beendet wurde.
Unsere Parameter sehen wie folgt aus:
"parameters": {
"source": {
"type": "array"
},
"transformTemplateUri": {
"type": "string"
},
"state": {
"type": "array",
"defaultValue": []
}
}
Als Nächstes definieren wir eine Variable mit dem Namen count
. Ihr Wert ist die Länge des Parameterobjektarrays source
:
"variables": {
"count": "[length(parameters('source'))]"
}
Wir verwenden sie für die Anzahl von Iterationen in unserer Kopierschleife.
Wir sehen uns nun die Ressourcen an. Es werden zwei Ressourcen definiert:
-
loop-0
ist die nullbasierte Ressource für unsere Kopierschleife. -
loop-
wird mit dem Ergebnis der FunktioncopyIndex(1)
verkettet, um einen eindeutigen iterationsbasierten Namen für die Ressource zu generieren, der mit1
beginnt.
Unsere Ressourcen sehen wie folgt aus:
"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]" }
}
}
}
]
Lassen Sie uns einen genaueren Blick auf die Parameter werfen, die an die Transformer-Vorlage in der geschachtelten Vorlage übergeben werden. Sie erinnern sich, dass mit dem Parameter source
das aktuelle Objekt im Parameterobjektarray source
übergeben wird. Die Sammlung erfolgt im state
-Parameter, da er die Ausgabe der vorherigen Iteration der Kopierschleife übernimmt und an die aktuelle Iteration übergibt. Beachten Sie, dass die reference()
-Funktion die copyIndex()
Funktion ohne Parameter verwendet, um auf das name
-Element des vorherigen verknüpften Vorlagenobjekts zu verweisen.
Abschließend gibt die Ausgabe (output
) unserer Vorlage die Ausgabe (output
) des letzten Durchlaufs unserer Transformer-Vorlage zurück:
"outputs": {
"result": {
"type": "array",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
Es kann ungewöhnlich erscheinen, dass die Ausgabe (output
) der letzten Iteration der Transformer-Vorlage an die aufrufende Vorlage übergeben wird, da sie anscheinend im Parameter source
gespeichert wurde. Allerdings handelt es sich um die letzte Iteration der Transformer-Vorlage, die das gesamte Array mit den Eigenschaftsobjekten enthält, und dass dies die Daten sind, die wir zurückgeben möchten.
Zum Schluss sehen wir uns noch an, wie die Collector-Vorlage aus der aufrufenden Vorlage aufgerufen wird.
Aufrufende Vorlage
Mit der aufrufenden Vorlage wird ein einzelner Parameter mit dem Namen networkSecurityGroupsSettings
definiert:
...
"parameters": {
"networkSecurityGroupsSettings": {
"type": "object"
}
}
Als Nächstes definiert unsere Vorlage eine einzelne Variable mit dem Namen collectorTemplateUri
:
"variables": {
"collectorTemplateUri": "[uri(deployment().properties.templateLink.uri, 'collector.template.json')]"
}
Dies ist der URI für die Collector-Vorlage, die von der verknüpften Vorlagenressource verwendet wird:
{
"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')]"
}
}
}
}
Wir übergeben zwei Parameter an die Collector-Vorlage:
-
source
ist unser Eigenschaftsobjektarray. In unserem Beispiel ist dies der ParameternetworkSecurityGroupsSettings
. -
transformTemplateUri
ist die Variable, die wir soeben mit dem URI der Collector-Vorlage definiert haben.
Zuletzt weist die Ressource Microsoft.Network/networkSecurityGroups
die Ausgabe (output
) der verknüpften Vorlagenressource collector
direkt der dazugehörigen securityRules
-Eigenschaft zu:
"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]"
}
}
Testen der Vorlage
Eine Beispielvorlage finden Sie auf GitHub. Klonen Sie zum Bereitstellen der Vorlage das Repository, und führen Sie die folgenden Befehle der Azure-Befehlszeilenschnittstelle aus:
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
Nächste Schritte
- Azure Resource Manager
- Was sind ARM-Vorlagen?
- Tutorial: Erstellen und Bereitstellen Ihrer ersten ARM-Vorlage
- Tutorial: Hinzufügen einer Ressource zu Ihrer ARM-Vorlage
- Bewährte Methoden für ARM-Vorlagen
- Dokumentation zu Azure Resource Manager
- Dokumentation zu ARM-Vorlagen