Een eigenschappentransformator en -collector implementeren in een Azure Resource Manager-sjabloon

In het artikel Objecten gebruiken als parameters in een kopieerlus in een Azure Resource Manager-sjabloon ziet u hoe u resourceeigenschapswaarden opslaat in een object en hoe u deze tijdens de implementatie toepast op een resource. Dit is een zeer handige manier om uw parameters te beheren, maar vereist dat u de eigenschappen van het object toewijst aan resource-eigenschappen telkens wanneer u het object in uw sjabloon gebruikt.

U kunt dit omzeilen door een eigenschapstransformatie- en collectorsjabloon te implementeren die uw objectmatrix itereert en transformeert in het JSON-schema voor de resource.

Belangrijk

Voor deze aanpak is een grondige kennis van Resource Manager sjablonen en functies vereist.

Laten we eens kijken naar een voorbeeld dat een eigenschappenverzamelaar en -transformator implementeert om een netwerkbeveiligingsgroep te implementeren. In het onderstaande diagram ziet u hoe onze sjablonen zijn gerelateerd aan de resources in deze sjablonen:

architectuur van eigenschappenverzamelaar en transformatieprogramma

Onze aanroepsjabloon bevat twee resources:

  • Een sjabloonkoppeling die onze collectorsjabloon aanroept
  • De te implementeren netwerkbeveiligingsgroepresource

Onze collectorsjabloon bevat twee resources:

  • Een ankerresource
  • Een sjabloonkoppeling die de transformatiesjabloon in een kopieerlus aanroept

Onze transformatiesjabloon bevat één resource: een lege sjabloon met een variabele die onze source JSON transformeert naar het JSON-schema dat wordt verwacht door de resource van de netwerkbeveiligingsgroep in de hoofdsjabloon.

Parameterobject

We gebruiken ons securityRules parameterobject uit Objecten gebruiken als parameters in een kopieerlus in een Azure Resource Manager-sjabloon. Met onze transformatiesjabloon wordt elk object in de securityRules matrix omgezet in het JSON-schema dat wordt verwacht door de resource van de netwerkbeveiligingsgroep in onze aanroepsjabloon.

{
    "$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"
                    }
                ]
            }
        }
    }
}

Laten we eerst onze transformatiesjabloon bekijken.

Sjabloon transformeren

Onze transformatiesjabloon bevat twee parameters die worden doorgegeven vanuit de collectorsjabloon:

  • source is een object dat een van de eigenschapswaardeobjecten van de eigenschappenmatrix ontvangt. In ons voorbeeld wordt elk object uit de securityRules matrix één voor één doorgegeven.
  • state is een matrix die de samengevoegde resultaten van alle vorige transformaties ontvangt. Dit is de verzameling van getransformeerde JSON.

Onze parameters zien er als volgt uit:

{
    "$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": []
        }
    },

Onze sjabloon definieert ook een variabele met de naam instance die ons source object transformeert in het vereiste JSON-schema:

"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]"
            }
        }
    ]
}

Ten slotte voegt de output van onze sjabloon de verzamelde transformaties van onze state parameter samen met de huidige transformatie die wordt uitgevoerd door onze instance variabele:

"resources": [],
"outputs": {
    "collection": {
        "type": "array",
        "value": "[concat(parameters('state'), variables('instance'))]"
    }
}

Laten we nu eens kijken naar onze collectorsjabloon om te zien hoe deze onze parameterwaarden doorgeeft.

Verzamelaarsjabloon

Onze collectorsjabloon bevat drie parameters:

  • source is onze volledige parameterobjectmatrix. Deze wordt doorgegeven door de aanroepende sjabloon. Deze heeft dezelfde naam als de source parameter in onze transformatiesjabloon, maar er is één belangrijk verschil: hoewel het de volledige matrix is, geven we slechts één matrixelement tegelijk door aan de transformatiesjabloon.
  • transformTemplateUri is de URI van onze transformatiesjabloon. We definiëren het als een parameter voor herbruikbaarheid van sjablonen.
  • state is een in eerste instantie lege matrix die wordt doorgegeven aan de transformatiesjabloon. Het slaat de verzameling getransformeerde parameterobjecten op nadat de kopieerlus is voltooid.

Onze parameters zien er als volgt uit:

"parameters": {
    "source": {
        "type": "array"
    },
    "transformTemplateUri": {
        "type": "string"
    },
    "state": {
        "type": "array",
        "defaultValue": []
    }
}

Vervolgens definiëren we een variabele met de naam count. De waarde is de lengte van de source parameterobjectmatrix:

"variables": {
    "count": "[length(parameters('source'))]"
}

We gebruiken deze voor het aantal iteraties in onze kopieerlus.

Laten we nu eens kijken naar onze resources. We definiëren twee resources:

  • loop-0 is de op nul gebaseerde resource voor onze kopieerlus.
  • loop- wordt samengevoegd met het resultaat van de copyIndex(1) functie om een unieke op iteratie gebaseerde naam voor onze resource te genereren, te beginnen met 1.

Onze resources zien er als volgt uit:

"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]" }
            }
        }
    }
]

Laten we eens kijken naar de parameters die we doorgeven aan de transformatiesjabloon in de geneste sjabloon. U weet nog dat onze source parameter het huidige object doorgeeft in de source parameterobjectmatrix. De state parameter is waar de verzameling plaatsvindt, omdat deze de uitvoer van de vorige iteratie van de kopieerlus neemt en deze doorgeeft aan de huidige iteratie. U ziet dat de reference() functie de copyIndex() functie zonder parameter gebruikt om te verwijzen naar de van het name vorige gekoppelde sjabloonobject.

Ten slotte retourneert de output van onze sjabloon de output van de laatste iteratie van de transformatiesjabloon:

"outputs": {
    "result": {
        "type": "array",
        "value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
    }
}

Het kan contra-intuïtief lijken om de van de output laatste iteratie van de transformatiesjabloon te retourneren naar de aanroepende sjabloon, omdat het lijkt alsof we deze hebben opgeslagen in onze source parameter. Het is echter de laatste iteratie van onze transformatiesjabloon die de volledige matrix met getransformeerde eigenschapsobjecten bevat, en dat is wat we willen retourneren.

Laten we ten slotte eens kijken hoe u de collectorsjabloon aanroept vanuit onze aanroepsjabloon.

Aanroepende sjabloon

Onze aanroepsjabloon definieert één parameter met de naam networkSecurityGroupsSettings:

...
"parameters": {
    "networkSecurityGroupsSettings": {
        "type": "object"
    }
}

Vervolgens definieert onze sjabloon één variabele met de naam collectorTemplateUri:

"variables": {
    "collectorTemplateUri": "[uri(deployment().properties.templateLink.uri, 'collector.template.json')]"
}

Dit is de URI voor de collectorsjabloon die wordt gebruikt door onze gekoppelde sjabloonresource:

{
    "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')]"
            }
        }
    }
}

We geven twee parameters door aan de collectorsjabloon:

  • source is onze eigenschapsobjectmatrix. In ons voorbeeld is dit onze networkSecurityGroupsSettings parameter.
  • transformTemplateUri is de variabele die we zojuist hebben gedefinieerd met de URI van onze collectorsjabloon.

Ten slotte wijst onze Microsoft.Network/networkSecurityGroups resource de van de output gekoppelde sjabloonresource rechtstreeks toe aan de collectorsecurityRules bijbehorende eigenschap:

"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]"
    }
}

Probeer de sjabloon

Er is een voorbeeldsjabloon beschikbaar op GitHub. Als u de sjabloon wilt implementeren, kloont u de opslagplaats en voert u de volgende Azure CLI-opdrachten uit:

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

Volgende stappen