Implementace transformátoru vlastností a sběrače v šabloně Azure Resource Manager

V použití objektu jako parametru v šabloně Azure Resource Managerjste zjistili, jak uložit hodnoty vlastností prostředku do objektu a použít je v prostředku během nasazení. I když je to velmi užitečný způsob, jak spravovat parametry, stále vyžaduje, abyste namapovali vlastnosti objektu na vlastnosti prostředků pokaždé, když ho použijete v šabloně.

Chcete-li se tomuto problému vyhnout, můžete implementovat transformaci a šablonu kolekce vlastností, která provede iteraci pole objektů a převede ji do schématu JSON očekávaného prostředkem.

Důležité

Tento přístup vyžaduje, abyste měli hlubokou porozumět Správce prostředků šablon a funkcí.

Pojďme se podívat, jak můžeme implementovat kolektor vlastností a transformátor s příkladem, který nasazuje skupinu zabezpečení sítě. Následující diagram znázorňuje vztah mezi našimi šablonami a našimi prostředky v rámci těchto šablon:

kolektor vlastností a architektura transformátoru

Naše Šablona volání obsahuje dva prostředky:

  • Odkaz šablony, který vyvolá naši šablonu kolektoru.
  • Prostředek skupiny zabezpečení sítě, který se má nasadit

Naše Šablona kolektoru obsahuje dva prostředky:

  • Prostředek ukotvení .
  • Odkaz šablony, který vyvolá transformaci šablony ve smyčce kopírování.

Naše transformační šablona obsahuje jeden prostředek: prázdnou šablonu s proměnnou, která transformuje náš source kód JSON na schéma JSON očekávané prostředkem skupiny zabezpečení sítě v hlavní šabloně.

Objekt parametru

Budeme používat náš securityRules objekt parametrů z objektů jako parametrů. Naše transformační šablona převede každý objekt v securityRules poli do schématu JSON, které je očekávané prostředkem skupiny zabezpečení sítě v naší volající šabloně.

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

Pojďme se nejdřív podívat na naši transformaci šablony .

Transformovat šablonu

Naše transformační šablona obsahuje dva parametry, které jsou předány ze šablony kolektoru:

  • source je objekt, který přijímá jeden z objektů hodnot vlastnosti z pole vlastností. V našem příkladu se každý objekt z "securityRules" pole předává v jednom okamžiku.
  • state je pole, které přijímá zřetězené výsledky všech předchozích transformací. Toto je kolekce transformovaných JSON.

Naše parametry vypadají takto:

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

Naše šablona také definuje proměnnou s názvem instance . Provede skutečnou transformaci našeho source objektu do požadovaného schématu 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]"
            }
        }
    ]
}

Nakonec output Šablona zřetězí shromážděné state transformace našeho parametru s aktuální transformací provedenou v naší instance proměnné:

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

Teď se podíváme na naši šablonu kolektoru , abychom viděli, jak přecházejí do hodnot parametrů.

Šablona kolekce

Naše Šablona kolektoru obsahuje tři parametry:

  • source je naše kompletní pole objektů parametrů. Je předána volající šablonou. Má stejný název jako source parametr v naší transformaci , ale existuje jeden klíčový rozdíl, který jste už možná všimli: Toto je úplné pole, ale pouze jeden prvek tohoto pole předáváme transformaci šabloně v daném okamžiku.
  • transformTemplateUri je identifikátor URI naší transformační šablony. Definujeme ho jako parametr pro opětovné použití šablony.
  • state je počáteční prázdné pole, které předáte naší transformaci šablony. Ukládá kolekci transformovaných objektů parametrů po dokončení smyčky kopírování.

Naše parametry vypadají takto:

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

Dále definujeme proměnnou s názvem count . Jeho hodnota je délka source pole objektu parametru:

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

Jak byste mohli být podezření, používáme ho pro počet iterací v naší smyčce kopírování.

Teď se podíváme na naše prostředky. Definujeme dva prostředky:

  • loop-0 je prostředek založený na nule pro naši kopírovací smyčku.
  • loop- je zřetězen s výsledkem copyIndex(1) funkce za účelem generování jedinečného názvu na základě iterace pro náš prostředek, počínaje 1 .

Naše prostředky vypadají takto:

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

Pojďme se podrobněji podívat na parametry, které předáváme do naší transformační šablony ve vnořené šabloně. Odvolat z dříve, že náš source parametr předá aktuální objekt v source poli objektu parametru. stateParametr je místo, kde se kolekce stane, protože vezme výstup předchozí iterace naší smyčky kopírování — , že reference() funkce používá copyIndex() funkci bez parametru pro odkaz na name náš předchozí propojený objekt šablony — a předá ho do aktuální iterace.

Nakonec bude output naše šablona vracet output poslední iteraci naší transformační šablony:

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

Může se zdát, že neintuitivní vrátí output poslední iteraci naší transformační šablony k naší volání šablony , protože se objevila v našem source parametru. Mějte ale na paměti, že se jedná o poslední iteraci naší šablony transformace , která obsahuje kompletní pole transformovaných objektů vlastností a to, co chceme vrátit.

Nakonec se podívejme na to, jak volat šablonu kolektoru z naší šablony volání.

Volání šablony

Naše Šablona volání definuje jeden parametr s názvem networkSecurityGroupsSettings :

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

Dále naše Šablona definuje jednu proměnnou s názvem collectorTemplateUri :

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

Jak byste očekávali, je to identifikátor URI pro šablonu kolektoru , kterou bude používat náš propojený prostředek šablony:

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

Do šablony kolektoru předáte dva parametry:

  • source je naše pole objektů vlastností. V našem příkladu je to náš networkSecurityGroupsSettings parametr.
  • transformTemplateUri je proměnná, kterou jsme právě definovali s identifikátorem URI naší šablony kolektoru.

Nakonec náš Microsoft.Network/networkSecurityGroups prostředek přiřadí přímo k output collector vlastnosti prostředku propojené šablony 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]"
    }
}

Vyzkoušejte šablonu

V GitHubje k dispozici příklad šablony. Pokud chcete nasadit šablonu, naklonujte úložiště a spusťte následující příkazy rozhraní příkazového řádku Azure :

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