AzureのARMテンプレートを理解する part1(基本編)

# ARMとは

~~Azure(特に)を使っていると、必ず出てきては頭を混乱させてくるヤツ~~
 
ARMは__Azure Resource Manager__の略になっており、現行のAzureの核となる概念です。
各サービスに必要な要素をリソースという単位で扱い、グルーピングしたりすることが肝となっています。
Azureの[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-overview)には以下のような利点があると書かれています。

* ソリューションのリソースを個別に処理するのではなく、すべてのリソースをグループとしてデプロイ、管理、監視できます。
* ソリューションを開発のライフサイクル全体で繰り返しデプロイできます。また、常にリソースが一貫した状態でデプロイされます。
* スクリプトではなく宣言型のテンプレートを使用してインフラストラクチャを管理できます。
* 正しい順序でデプロイされるようにリソース間の依存性を定義できます。
* ロールベースのアクセス制御 (RBAC) が管理プラットフォームにネイティブ統合されるため、リソース グループのすべてのサービスにアクセス制御を適用できます。
* タグをリソースに適用し、サブスクリプションのすべてのリソースを論理的に整理できます。
* 同じタグを共有するリソース グループのコストを表示することで、組織の課金をわかりやすくすることができます。

上記の利点にもある宣言型のテンプレートが通称__ARMテンプレート__と呼ばれるものになっています。
このテンプレートはJSON形式で書いていきます。
こういったテンプレートを用いてインフラを管理することを__Infrastructure as a Code__といいます。
毎回毎回お手製でインフラを作成しているとオペレーションミスの危険性がはらんでいます。
しかし、ARMテンプレートを使用することによって誰がやっても全く同じ環境を作成することができるようになり、
さらには一度作成した環境をすぐにデプロイできることによる効率化も図れます。

長々と説明しても冗長になるのでこれくらいにしておきますが、要するに__使いこなせれば大変すばらしい機能__なのです。

#ARMテンプレート概要

```json:sample.json
{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "variables": {},
    "resources": [],
    "output": []
}
```

ARMテンプレートは上記のような構成になっています。ユーザーがカスタマイズするのは下の4つの項目です。
それぞれどのようなことを書いていけばいいのかを記載したいきます。

###parameters

リソースを作成する際に毎回、ユーザーが指定したい項目を定義します。
例えば__各リソースの名前__や__ログインユーザー名/パスワード__などです。
以下はサンプルになっています。使用している要素は個人的によく使うもののみに抑えてあります。
要素の詳細は後述します。

```json:parameters.json
"parameters": {
     "VMName": {
          "type": "string"
     },
     "AdminPassword": {
          "defaultValue": "1A2b3C4d5E6f7G",
          "type": "secureString"
     },
    "OSType": {
          "allowedValue": [
                "Windows",
                "Linux"
                ],
          "type": "string"
          }
}
```

__"type"__は__必須な要素__でパラメーターの値の型を指定します。文字列の場合は"string"、数字の場合は"int"、またパスワードやキーは"secureString"を使用するとパラメーターを非表示で入力することができます。

__"defaultValue"__を指定することによって規定の値を設定することができ、別で値の指定がない限りは既定の設定を使用することができるようになります。

__"allowedValue"__を指定することによって、値に使用できる範囲を指定することができます。上記の例だとパラメーターOSTypeの値はWindowsかLinuxしか指定できない様にしています。

###variables

毎回変更の必要がない固定値や、上記のparametersを組み合わせて値として定義します。
例えばユーザーが入力したリソース名に特定の識別子を必ず追加したい場合などです。
以下はサンプルになります。

```json:variables.json
"variables": {
     "publicIPAddressType": "Dynamic",
     "vmName": "[concat(parameters('VMName'), '-arm')]"
     }
```

単純に固定値を指定することもできますし、上記の"vmName"のように値を組み合わせて構成することもできます。

__concat__は複数の値を結合する際に使用します。使用方法は__[concat("値1","値2","...)]__といった形になります。

またparametersの値を使用する場合は__parameters('パラメーター名')__という形で呼び出します。

###resources

Azureで実際に作成するリソースを定義します。
上で定義したparametersやvariablesを使用してリソースの構成を書き下していきます。
各リソースごとに必要とされるオブジェクトや要素がありますのでそれらは[ここ](https://docs.microsoft.com/en-us/azure/templates/)を参照ください。
以下はサンプルになります。仮想マシン等の複雑なリソースだと長くなってしまうので、パブリックIPを定義する場合の例になっています。

```json:resources.json
"resources": [
     {
          "type": "Microsoft.Network/publicIPAddresses",
          "apiVersion": "2017-03-01",
          "name": "armtest-pip",
          "location": "[resourceGroup().location]",
          "properties: {
                "publicIPAllocationMethod": "Dynamic",
                "publicIPAddressversion": "IPv4"
                }
      }
]


```

上記のように各リソースを一つのオブジェクトと定義します。
typeからlocationでどの種類のリソースをどこに作成するのかを定義します。
apiVersionは古いバージョンだと、新しいサービスを定義することができないので注意が必要です。

properties内はリソースの詳しい設定を定義します。
基本的にこの部分は各リソースごとに違いますので、上記の必要なオブジェクトや要素をまとめたページを参照して書いていく必要があります。

###outputs

デプロイのリクエストに対する返り値を定義します。
作成した仮想マシンのパブリックIPを返したり、デプロイが成功したことをコメントで返したりする際に使用します。
以下はサンプルになります。

```json:outputs.json
"outputs": {
    "adminUsername": {
        "type": "string",
        "value": "[parameters('adminUsername')]"
    }
}
```

上記は作成した仮想マシンのユーザー名をデプロイ後に返すサンプルになっています。
このように、作成したユーザに通知したい項目を定義します。

#おわりに

今回はARMテンプレートとは何か、どのような項目が書かれているのかという部分にフォーカスしました。
正直、かなり難しく感じますが、世の中には様々な人が誰でも使用できるようにテンプレートを用意しています。
それらのテンプレートは[こちら](https://azure.microsoft.com/ja-jp/resources/templates/)から確認できます。
上記に記載されているテンプレートはGithubで確認もできますが、そのままボタン一つでAzureで動かすことができます。便利ですね。自分でガシガシと書いていくよりも圧倒的に楽です。
自分で作成していく際にも、上記リンクに記載されている中から似ているものを選び自分流にカスタマイズしていくのが楽です。
今回はここまでとなりますが次のパートでは__自分で書いていきたい！__という特殊な人向けに私が一から作ったときに引っかかったポイントを交えてテンプレート作成の流れを書いていきたいと思います。
では。

#参考情報

* https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-overview
* https://docs.microsoft.com/en-us/azure/templates/
* https://azure.microsoft.com/ja-jp/resources/templates/