Azure Resource Manager - テンプレートの階層化（テンプレートのリンク）

# 概要

[チュートリアル](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/template-specs-deploy-linked-template?tabs=azure-cli)を参考にARMテンプレートの階層化を行う

Childテンプレートからテンプレート スペックを生成し、
Parentテンプレートでテンプレート スペックのリソース IDを使用してリンクする



## ファイル構成

```
  ├─ storage/
  │   └─ template.json  # Childテンプレート
  │
  ├─ template.json      # Parentテンプレート
  └─ parameters.json    # パラメータ定義
```

# 前提

- デプロイ先のリソースグループの作成
- VSCode拡張機能`Azure Resource Manager (ARM) Tools`のインストール

`Azure Resource Manager (ARM) Tools`でARM テンプレートのひな型作成、値の検証、入力候補表示等が可能（[参考](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/quickstart-create-templates-use-visual-studio-code?tabs=CLI#create-an-arm-template)）

![image-20211125112244786.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/05d98a4d-47be-c014-7be4-8a8208e418ac.png)


# テンプレート スペックの生成

Childテンプレートからテンプレート スペックを生成する



## Childテンプレート（`storage/template.json`）

```json:storage/template.json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "prefix": {  // Parentテンプレートから値を渡す
      "type": "string"
    },
    "location": {  // Parentテンプレートから値を渡す
      "type": "string"
    },
    "storageAccountType": {
      "type": "string",
      "defaultValue": "Standard_LRS"
    }
  },
  "functions": [],
  "variables": {
    "storageAccountName": "[concat(parameters('prefix'), 'storageaccount')]"
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2021-04-01",
      "kind": "Storage",
      "name": "[variables('storageAccountName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[parameters('storageAccountType')]"
      }
    }
  ],
  "outputs": {}
}
```

形式はARMテンプレートと同じで、ストレージアカウントを定義し、
`parameters`の`prefix`, `location`は、Parentテンプレートから値を渡すため`defaultValue`は設定しない



## デプロイ

```
az ts create --name storageSpec --version "1.0" --resource-group arm-test-resource-group --template-file "storage\template.json" --yes
```

`--name`で指定した名前と、`--version`で指定したバージョンは、Parentテンプレートデプロイ時に使用する
`--yes`オプションで既にリソースが存在する場合に上書きの確認ダイアログを表示しないようにしている

# ARMテンプレートからリソースの生成

## Parentテンプレート（`template.json`）

```json:template.json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "prefix": {
      "type": "string",
      "defaultValue": "prefix"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    },
    "tsVersion": {  // テンプレートスペックデプロイ時に指定した値  ※デプロイ時にparameters.jsonの値で上書きする
      "type": "string",
      "defaultValue": "1.0"
    },
    "tsName": {  // テンプレートスペックデプロイ時に指定した値  ※デプロイ時にparameters.jsonの値で上書きする
      "type": "string",
      "defaultValue": "storageSpec"
    }
  },
  "functions": [],
  "variables": {},
  "resources": [
    {
      "name": "StorageDeployment",
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "properties": {
        "mode": "Incremental",
        "templateLink": {
          "id": "[resourceId('Microsoft.Resources/templateSpecs/versions', parameters('tsName'), parameters('tsVersion'))]"  // テンプレート スペックのリソースID
        },
        "parameters": {  // Childテンプレートに渡すパラメータ
          "prefix": {"value": "[parameters('prefix')]"},
          "location": {"value": "[parameters('location')]"}
        }
      }
    }
  ],
  "outputs": {}
}
```

Childテンプレートから生成したテンプレート スペックのリソースIDを指定して、テンプレートをリンクする
[`resourceId()`](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/template-functions-resource#resourceid)関数にリソースタイプ（`Microsoft.Resources/templateSpecs/versions`）、リソース名、リソースバージョンをしてリソースIDを取得する



## パラメータ定義（`parameters.json`）

```json:parameters.json
{
  "prefix": {"value": "armtest2"},
  "tsVersion": {"value": "1.0"}
}
```



## デプロイ

```
az deployment group create --name test-deploy --resource-group arm-test-resource-group --template-file template.json --parameters parameters.json
```

### デプロイ結果

![image-20211128155513225.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/695430/2c0906c0-b54d-6960-c5c5-3a42eecaf3e3.png)