Azure Resource Manager テンプレートでプロパティのトランスフォーマーとコレクターを実装する
記事「Azure Resource Manager テンプレートのコピー ループのパラメーターとしてオブジェクトを使用する」で、オブジェクトにリソース プロパティ値を格納する方法と、デプロイ中にリソースにそれらを適用する方法を確認できます。 これはパラメーターの管理には非常に便利な方法ですが、テンプレートでオブジェクトを使用するたびに、オブジェクトのプロパティをリソースのプロパティにマップする必要があります。
これを回避するために、オブジェクト配列を反復処理してリソースの JSON スキーマに変換するプロパティ変換とコレクターのテンプレートを実装できます。
重要
この方法では、Resource Manager のテンプレートと関数について深い理解があることが必要です。
ネットワーク セキュリティ グループをデプロイするためのプロパティ コレクターとトランスフォーマーを実装する例を見てみましょう。 以下の図は、テンプレートがそのテンプレート内のリソースにどのように関連しているかを示しています。
この呼び出し元テンプレートには 2 つのリソースが含まれています。
- コレクター テンプレートを呼び出す、テンプレート リンク
- デプロイするネットワーク セキュリティ グループ リソース
このコレクター テンプレートには 2 つのリソースが含まれています。
- アンカー リソース
- コピー ループ内で変換テンプレートを呼び出すテンプレート リンク
変換テンプレートには、source
JSON をメイン テンプレート内のネットワーク セキュリティ グループ リソースで想定されている JSON スキーマに変換する変数を持つ空のテンプレートという 1 つのリソースが含まれています。
パラメーター オブジェクト
「Azure Resource Manager テンプレートのコピー ループのパラメーターとしてオブジェクトを使用する」の securityRules
パラメーター オブジェクトを使用します。
変換テンプレートは、securityRules
配列内の各々のオブジェクトを、呼び出し元テンプレート内のネットワーク セキュリティ グループ リソースで想定されている JSON スキーマに変換します。
{
"$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"
}
]
}
}
}
}
最初に変換テンプレートを見てみましょう。
変換テンプレート
この変換テンプレートには、コレクター テンプレートから渡される 2 つのパラメーターが含まれています。
-
source
は、プロパティ配列からプロパティ値オブジェクトの 1 つを受け取るオブジェクトです。 例では、securityRules
配列の各オブジェクトが一度に 1 つ渡されます。 -
state
は、以前の変換のすべてを連結した結果を受け取る配列です。 これは、変換された JSON のコレクションです。
パラメーターは次のようになります。
{
"$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": []
}
},
テンプレートでは、source
オブジェクトを必要な JSON スキーマに変換する instance
という名前の変数の定義も行います。
"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]"
}
}
]
}
最後に、テンプレートの output
によって、state
パラメーターの収集された変換が instance
変数によって実行される現在の変換と連結されます。
"resources": [],
"outputs": {
"collection": {
"type": "array",
"value": "[concat(parameters('state'), variables('instance'))]"
}
}
次に、コレクター テンプレートによってパラメーター値がどのように渡されているかを見てみましょう。
コレクター テンプレート
このコレクター テンプレートには 3 つのパラメーターが含まれています。
-
source
は完全なパラメーター オブジェクトの配列です。 これは、呼び出し元テンプレートによって渡されます。 変換テンプレートのsource
パラメーターと同じ名前ですが、重要な違いが 1 つあります。これは完全な配列ですが、一度に 1 つの配列要素のみを変換テンプレートに渡します。 -
transformTemplateUri
は、この変換テンプレートの URI です。 テンプレートが再利用できるように、パラメーターとして定義します。 -
state
は、変換テンプレートに渡す、最初は空である配列です。 これにより、コピー ループの完了後に、変換されたパラメーター オブジェクトのコレクションが格納されます。
パラメーターは次のようになります。
"parameters": {
"source": {
"type": "array"
},
"transformTemplateUri": {
"type": "string"
},
"state": {
"type": "array",
"defaultValue": []
}
}
次に、count
という名前の変数を定義します。 その値は、source
パラメーター オブジェクトの配列の長さです。
"variables": {
"count": "[length(parameters('source'))]"
}
コピー ループでのイテレーションの回数に使用しています。
ここで、リソースを見てみましょう。 2 つのリソースを定義します。
-
loop-0
はコピー ループの 0 から始まるリソースです。 -
loop-
はcopyIndex(1)
関数の結果と連結され、リソースに、1
で始まるイテレーションに基づく一意の名前を生成します。
リソースは次のようになります。
"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]" }
}
}
}
]
入れ子になったテンプレート内の変換テンプレートに渡すパラメーターを詳しく見てみましょう。
source
パラメーターは source
パラメーター オブジェクトの配列にある現在のオブジェクトを渡していることを思い出してください。
state
パラメーターは収集の発生点です。これがコピー ループの前のイテレーションの出力を受け取って、現在のイテレーションに渡します。
reference()
関数は、パラメーターのない copyIndex()
関数を使用して、前にリンクされたテンプレート オブジェクトの name
を参照しています。
最後に、テンプレートの output
は、変換テンプレートの最後のイテレーションの output
を返します。
"outputs": {
"result": {
"type": "array",
"value": "[reference(concat('loop-', variables('count'))).outputs.collection.value]"
}
}
変換テンプレートの最後のイテレーションの output
を呼び出し元テンプレートに返すのは、それを source
パラメーターに格納していたように感じられるため、直感に反するかもしれません。 しかし、これは変換されたプロパティ オブジェクトの完全な配列を持つ変換テンプレートの最後のイテレーションであり、まさに返そうとしているものです。
最後に、呼び出し元テンプレートからコレクター テンプレートを呼び出す方法を見てみましょう。
呼び出し元テンプレート
この呼び出し元テンプレートは、networkSecurityGroupsSettings
という名前の単一パラメーターを定義します。
...
"parameters": {
"networkSecurityGroupsSettings": {
"type": "object"
}
}
次に、テンプレートは collectorTemplateUri
という名前の単一の変数を定義します。
"variables": {
"collectorTemplateUri": "[uri(deployment().properties.templateLink.uri, 'collector.template.json')]"
}
これはリンクされたテンプレート リソースによって使用されるコレクター テンプレートの URI です。
{
"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')]"
}
}
}
}
コレクター テンプレートに 2 つのパラメーターを渡します。
-
source
はプロパティ オブジェクトの配列です。 この例では、networkSecurityGroupsSettings
パラメーターです。 -
transformTemplateUri
はコレクター テンプレートの URI で定義した変数です。
最後に、Microsoft.Network/networkSecurityGroups
リソースで、collector
がリンクされたテンプレート リソースの output
をその 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]"
}
}
テンプレートを試行する
テンプレートの例は GitHub で入手できます。 テンプレートをデプロイするには、リポジトリを複製し、次の Azure CLI コマンドを実行します。
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
次のステップ
- Azure Resource Manager
- ARM テンプレートとは
- チュートリアル:初めての ARM テンプレートを作成してデプロイする
- チュートリアル:ARM テンプレートにリソースを追加する
- ARM テンプレートのベスト プラクティス
- Azure Resource Manager のドキュメント
- ARM テンプレートのドキュメント