Azureでリソースのデプロイの自動化が可能な Azure Resource Manager (以下、ARM) テンプレート 。

本記事では、初心者の方でもARMテンプレートを作成することができるように、構造の解説や参考サイトなどを記載しています。実際に複数台の仮想マシンを作成するコードも掲載するので、是非参考にしてみてください。

ARM (Azure Resource Manager) テンプレートとは?

ARM (Azure Resource Manager) テンプレートの概要

ARMテンプレートは、リソースの作成、更新、削除を自動化する機能を持っています。これにより、手動操作によるエラーを大幅に減少させることができます。

たとえば、同じテンプレートを使用して異なる環境にリソースをデプロイすることができ、一貫したインフラストラクチャを維持できます。この自動化により、運用コストの削減と作業の迅速化が実現します。

また、ARMテンプレートは宣言型の構文を使用しているため、リソースの状態を定義するだけで作成が可能です。そのため、テンプレート作成の複雑さを軽減し、プログラミング言語初心者の方も扱いやすい点が特長です。

ARM (Azure Resource Manager) テンプレートのメリット

ARMテンプレートのメリットは以下のようなものがあります。

  1. 一元的な管理
    ARMテンプレートはAzure上のさまざまなサービスで利用でき、それらを一括で管理できます。
    複数のリソースを依存関係も整理しつつデプロイしてくれます。これにより、全体の整合性を保ちつつ、効率的に作業を行うことができます。
  1. 簡単な記述
    ARMテンプレートは、人間が理解しやすいJSON形式で記述されます。これにより、誰でも簡単にテンプレートを作成し、読み解くことができます。
  1. 設定の再利用
    一度作成した設定を何度でも再利用できるので、同じリソースを何度も作成する手間を省くことができます。
    たとえば追加で同じ設定のリソースを作成する必要が生じた場合も、ARMテンプレートをデプロイするだけで実現可能です。
  1. 作業の自動化
    ARMテンプレートを使用すると、設定の適用を自動化できます。
    これにより、手動での作業を大幅に削減し、構築や運用の効率化を図ることができます。さらに、これにより人間が手動で設定を行う際に起こり得るミスを防ぐことができます。

ARM (Azure Resource Manager) テンプレートの構造

ARM (Azure Resource Manager) テンプレート構造の概要

ARMテンプレートは、セクションとセクションの中で設定できるプロパティがあらかじめ決められています。以下のコードを例に簡単に解説します。

parameters“: {
  “<parameter-name>”: {
    “type”: “<type-of-parameter-value>”,
    “defaultValue”: “<default-value-of-parameter>”
}

「”parameters”」がセクションであり、「”type”」「”defaultValue”」があらかじめ使用できることが決められたプロパティ(要素)です。プロパティは、自由に設定できる値もありますが、指定できる値が決まっているものもあります。詳細はこちらをご覧ください。

ARM (Azure Resource Manager) テンプレートのセクション解説

ARMテンプレートにはいくつかのセクションが用意されておりますが、ここではよく使用する5セクションについて簡単に解説します。詳細は上記の公式サイトをご確認ください。

  1. $schema
    必須のセクションです。テンプレート言語のバージョンが記述されている JSONスキーマ ファイルの場所を指定します。
  1. contentVersion
    必須のセクションです。任意の値のテンプレートのバージョン (1.0.0.0 など)を指定でき、適切なテンプレートが使用されていることの確認に使用できます。
  1. parameters
    任意のセクションです。リソース名やSKU、デプロイ先のリージョンなど、ユーザーが入力する必要がある情報を指定します。GUIで作成する際に手入力する部分を定義して、代入できるようにします。
    parametersセクションを活用することで、再利用性を高めることができます。
  1. variables
    任意のセクションです。テンプレート内で再利用可能な値を定義します。
    特定のリソースの名前や設定値を変数として定義することで、後から変更が必要になった場合でも、変数の値を一箇所変更するだけで済みます。parametersと異なり基本的に固定値として利用したい値の定義に役立ちます。
  1. resources
    必須のセクションです。デプロイするリソースを定義します。リソース間の依存関係を明示することで、Resource Managerは正しい順序でリソースをデプロイし、効率的な管理を実現します。これにより、複雑なインフラストラクチャを簡単に構築できるようになります。

ARM (Azure Resource Manager) テンプレートのベストプラクティス

ARMテンプレートを利用する際のポイントについて説明します。

  1. モジュール化
    テンプレートを小さなモジュールに分割し、再利用性を高めます。同じ機能を持つリソースを複数作成する際に、同じコードを何度も書く必要がなくなります。また、モジュール化することでテンプレート全体の見通しが良くなり、保守性も向上します。
  1. バージョン管理
    テンプレートをGitなどでバージョン管理し、変更履歴を追跡できるようにすると便利です。そうすることで、誤って削除や変更した場合でも元に戻すことができ、複数人での開発時にも、各メンバーの変更内容を確認しやすくなります。
  1. テスト
    デプロイ前にテンプレートをテストします。テストを行うことで、構文チェックや環境への影響なども最小限でARMテンプレートの確認が行えます。
  1. ドキュメント化
    テンプレートの目的や使用方法をドキュメント化しておきます。ARMテンプレート内でもコメントを記述することができますが、ドキュメント化しておくことで内容が一目で分かるので、修正や再利用が行いやすくなります。

ARM (Azure Resource Manager) テンプレートでVM (仮想マシン)を複製

今回は、ARMテンプレートを利用して、VMを複製する方法について解説します。まずは元のVMのスナップショットを手動で取得して、スナップショットIDを利用してARMテンプレートでAzure Virtual Machinesを一括デプロイしていきます。

ARMテンプレート複製構成

元となる仮想マシンのスナップショット取得

複製したい仮想マシンのOSディスクのスナップショットを作成します。Windowsの場合、スナップショットの前にsysprepする必要があります。

スナップショット作成

ARMテンプレート作成

ARMテンプレートを作成します。今回は、以下公式サイトを参考にテンプレートを作成しました。

クイック スタート: テンプレートを使用して Windows 仮想マシンを作成する
ARM テンプレートでのリソースの反復処理

また、今回は元となるVMがあるので、該当VMの「テンプレートのエクスポート」からJSONファイルを出力して、そちらを元に作成しても良いと思います。

テンプレートのエクスポート

{
  “$schema“: “https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#”,
  “contentVersion”: “1.0.0.0”,
  “parameters“: {
    “location”: {
      “type”: “string”,
      “defaultValue”: “[resourceGroup().location]”
    },
    “Names”: {
      “type”: “array”,
      “defaultValue”: [
        “test2”,
        “test3”
      ]
    },
    “vmSize”: {
      “type”: “string”,
      “defaultValue”: “Standard_B2s”
    }
  },
  “variables“: {
    “snapshotName”: “test-snapshot”,
    “subnetName”: “default”,
    “virtualNetworkName”: “test-vnet”
  },
  “resources“: [
    {
      “type”: “Microsoft.Compute/disks”,
      “apiVersion”: “2023-01-02”,
      “copy”: {
        “name”: “diskCopy”,
        “count”: “[length(parameters(‘Names’))]”
      },
      “name”: “[format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-disk’)]”,
      “location”: “[parameters(‘location’)]”,
      “sku”: {
        “name”: “StandardSSD_LRS”
      },
      “properties”: {
        “creationData”: {
          “createOption”: “Copy”,
          “sourceResourceId”: “[resourceId(‘Microsoft.Compute/snapshots’, variables(‘snapshotName’))]”
        }
      }
    },
    {

      “type”: “Microsoft.Network/publicIPAddresses”,
      “apiVersion”: “2022-05-01”,
      “copy”: {
        “name”: “ipCopy”,
        “count”: “[length(parameters(‘Names’))]”
      },
      “name”: “[format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-ip’)]”,
      “location”: “[parameters(‘location’)]”,
      “sku”: {
        “name”: “basic”
      },
      “properties”: {
        “publicIPAllocationMethod”: “Dynamic”
      }
    },
    {
      “type”: “Microsoft.Network/networkInterfaces”,
      “apiVersion”: “2022-05-01”,
      “copy”: {
        “name”: “nicCopy”,
        “count”: “[length(parameters(‘Names’))]”
      },
      “name”: “[format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-nic’)]”,
      “location”: “[parameters(‘location’)]”,
      “properties”: {
        “ipConfigurations”: [
          {
            “name”: “ipconfig1”,
            “properties”: {
              “privateIPAllocationMethod”: “Dynamic”,
              “publicIPAddress”: {
                “id”: “[resourceId(‘Microsoft.Network/publicIPAddresses’, format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-ip’))]”
              },
              “subnet”: {
                “id”: “[resourceId(‘Microsoft.Network/virtualNetworks/subnets’, variables(‘virtualNetworkName’), variables(‘subnetName’))]”
              }
            }
          }
        ]
      },
      “dependsOn”: [
        “[resourceId(‘Microsoft.Network/publicIPAddresses’, format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-ip’))]”
      ]
    },
    {
      “type”: “Microsoft.Compute/virtualMachines”,
      “apiVersion”: “2022-03-01”,
      “copy”: {
        “name”: “vmCopy”,
        “count”: “[length(parameters(‘Names’))]”
      },
      “name”: “[format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-vm’)]”,
      “location”: “[parameters(‘location’)]”,
      “properties”: {
        “hardwareProfile”: {
          “vmSize”: “[parameters(‘vmSize’)]”
        },
        “storageProfile”: {
          “osDisk”:{
            “osType”: “Windows”,
            “createOption”: “Attach”,
            “managedDisk”: {
              “storageAccountType”: “StandardSSD_LRS”,
              “id”: “[resourceId(‘Microsoft.Compute/disks’, format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-disk’))]”
            }
          },
          “dataDisks”: []
        },
        “networkProfile”: {
          “networkInterfaces”: [
            {
              “id”: “[resourceId(‘Microsoft.Network/networkInterfaces’, format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-nic’))]”
            }
          ]
        },
        “diagnosticsProfile”: {
          “bootDiagnostics”: {
            “enabled”: true
          }
        }
      },
      “dependsOn”: [
        “[resourceId(‘Microsoft.Network/networkInterfaces’, format(‘{0}{1}’, parameters(‘Names’)[copyIndex()], ‘-nic’))]”
      ]
    }
  ],
  “outputs”: {}
}

「resources」セクションでは、以下の流れでリソースを作成しています。
①ディスク作成(”type”: “Microsoft.Compute/disks”)
②パブリックIP作成(”type”: “Microsoft.Network/publicIPAddresses”)
③ネットワークインタフェース作成(”type”: “Microsoft.Network/networkInterfaces”)
④VM作成(”type”: “Microsoft.Compute/virtualMachines”)

ARMテンプレートのデプロイ

「カスタムテンプレートのデプロイ」を選択します。

ARMテンプレートのデプロイ1

「エディターで独自のテンプレートを作成する」を選択します。

ARMテンプレートのデプロイ2

「ファイルの読み込み」で、作成したARMテンプレートを選択します。

ARMテンプレートのデプロイ3

リソースグループを選択し、「作成」をクリックしてデプロイします。

ARMテンプレートのデプロイ4

デプロイ後、以下のようにVMが作成されれば成功です。

ARMテンプレートのデプロイ5

まとめ

今回は、VM(仮想マシン)を複製する方法を元に、ARMテンプレートの利用方法について解説しました。今回私自身初めてARMテンプレートを利用してみましたが、公式サイトにも多くの情報が掲載されているので、作成のしやすさを感じました。

本記事を読んで、ARMテンプレートの学習が取り組みやすくなったら嬉しいなと思います!