Terapkan transformator dan pengumpul properti dalam template Azure Resource Manager

Dalam artikel Menggunakan objek sebagai parameter dalam perulangan salinan di templat Azure Resource Manager Anda dapat melihat cara menyimpan nilai properti sumber daya dalam objek dan cara menerapkannya ke sumber daya selama penyebaran. Ini adalah cara yang sangat berguna untuk mengelola parameter Anda, tetapi mengharuskan Anda memetakan properti objek ke properti sumber daya setiap kali Anda menggunakan objek di templat Anda.

Untuk mengatasinya, Anda dapat menerapkan transformasi properti dan templat kolektor yang menguraikan array objek Anda dan mengubahnya menjadi skema JSON untuk sumber daya.

Penting

Pendekatan ini mengharuskan Anda memiliki pemahaman yang mendalam tentang template dan fungsi Resource Manager.

Mari kita lihat contoh yang mengimplementasikan pengumpul dan transformator properti untuk menyebarkan kelompok keamanan jaringan. Diagram di bawah ini menunjukkan bagaimana templat kami terkait dengan sumber daya dalam templat tersebut:

arsitektur pengumpul dan transformator properti

Template panggilan kami mencakup dua sumber daya:

  • Tautan templat yang memanggil templat kolektor kami
  • Sumber daya grup keamanan jaringan untuk disebarkan

Template pengumpul kami mencakup dua sumber daya:

  • Sumber daya jangkar
  • Tautan templat yang memanggil templat transformasi dalam perulangan salinan

Templat transformasi kami mencakup satu sumber daya: templat kosong dengan variabel yang mengubah JSON kami source ke skema JSON yang diharapkan oleh sumber daya grup keamanan jaringan kami di templat utama.

Objek parameter

Kami menggunakan objek parameter kami securityRules dari Gunakan objek sebagai parameter dalam perulangan salinan di templat Azure Resource Manager. Templat transformasi kami mengubah setiap objek dalam securityRules array menjadi skema JSON yang diharapkan oleh sumber daya grup keamanan jaringan dalam templat panggilan kami.

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

Mari lihat template transformasi kami terlebih dahulu.

Ubah templat

Template transformasi kami menyertakan dua parameter yang diteruskan dari template pengumpul:

  • source adalah objek yang menerima salah satu objek nilai properti dari array properti. Dalam contoh kami, setiap objek dari securityRules array diteruskan satu per satu.
  • state adalah array yang menerima hasil gabungan dari semua transformasi sebelumnya. Ini adalah kumpulan JSON yang diubah.

Parameter kami terlihat seperti ini:

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

Templat kami juga mendefinisikan variabel bernama instance yang mengubah objek kita source menjadi skema JSON yang diperlukan:

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

Akhirnya, output templat kami menggabungkan transformasi parameter yang state dikumpulkan dengan transformasi saat ini yang dilakukan oleh variabel kami instance :

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

Selanjutnya, mari kita lihat templat kolektor kita untuk melihat bagaimana templat tersebut melewati nilai parameter kita.

Template pengumpul

Template pengumpul kami mencakup tiga parameter:

  • source adalah array objek parameter lengkap kami. Ini diteruskan oleh templat panggilan. Ini memiliki nama yang sama dengan source parameter dalam templat transformasi kami, tetapi ada satu perbedaan utama: meskipun ini adalah array lengkap, kami hanya meneruskan satu elemen array sekaligus ke templat transformasi.
  • transformTemplateUri adalah URI dari template transformasi kami. Kami mendefinisikannya sebagai parameter untuk penggunaan kembali templat.
  • state adalah array yang awalnya kosong yang kami teruskan ke template transformasi kami. Ini menyimpan koleksi objek parameter yang diubah setelah perulangan salinan selesai.

Parameter kami terlihat seperti ini:

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

Selanjutnya, kami mendefinisikan sebuah variabel bernama count. Nilainya adalah panjang array objek parameter source:

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

Kami menggunakannya untuk jumlah perulangan dalam perulangan salinan kami.

Sekarang mari lihat sumber daya kami. Kami mendefinisikan dua sumber daya:

  • loop-0 adalah sumber daya berbasis nol untuk loop penyalinan kami.
  • loop- digabungkan dengan hasil fungsi copyIndex(1) untuk menghasilkan nama berbasis iterasi yang unik untuk sumber daya kami, dimulai dengan 1.

Sumber daya kami terlihat seperti ini:

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

Mari kita lihat lebih dekat parameter yang kita berikan ke templat transformasi kita di templat berlapis. Ingat dari sebelumnya bahwa parameter source kami meneruskan objek saat ini dalam array objek parameter source. Parameter state adalah tempat pengumpulan terjadi, karena dibutuhkan output dari iterasi sebelumnya dari perulangan salinan kami dan meneruskannya ke iterasi saat ini. Perhatikan bahwa reference() fungsi menggunakan copyIndex() fungsi tanpa parameter untuk mereferensikan name objek templat tertaut kami sebelumnya.

Terakhir, output template kami mengembalikan output dari iterasi terakhir template transformasi kami:

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

Mungkin tampak berlawanan dengan mengembalikan output iterasi terakhir templat transformasi kami ke templat panggilan kami, karena tampaknya kami menyimpannya di parameter kami source . Namun, ini adalah iterasi terakhir dari templat transformasi kami yang menyimpan array lengkap objek properti yang diubah, dan itulah yang ingin kami kembalikan.

Terakhir, mari lihat cara memanggil template pengumpul dari template panggilan kami.

Template panggilan

Template panggilan kami menetapkan satu parameter bernama networkSecurityGroupsSettings:

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

Selanjutnya, template kami mendefinisikan satu variabel bernama collectorTemplateUri:

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

Ini adalah URI untuk templat kolektor yang digunakan oleh sumber daya templat tertaut kami:

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

Kami meneruskan dua parameter ke template pengumpul:

  • source adalah array objek properti kami. Dalam contoh kami, ini adalah parameter networkSecurityGroupsSettings kami.
  • transformTemplateUri adalah variabel yang baru saja kami tentukan dengan URI templat kolektor kami.

Terakhir, sumber daya Microsoft.Network/networkSecurityGroups kami secara langsung menetapkan output dari collector sumber daya kerangka tertaut ke properti securityRules-nya:

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

Coba templatenya

Contoh template tersedia di GitHub. Untuk menerapkan templat, klon repositori dan jalankan perintah Azure CLI berikut:

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

Langkah berikutnya