ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

Azure Resource Manager テンプレートを使って複数の仮想マシンを構築する

ハンズオンなどのトレーニングにおいて、受講者向けに複数の仮想マシンを Azure 上に構築する方法をまとめておきます。
Azure Portal からポチポチと1台ずつ作るのは厳しいため、選択肢としては次の2つの方法があると思います。

  • Azure Resource Manager テンプレート
  • Azure Lab Services

この記事では、Azure Resource Manager テンプレートを使う方法について記載します。
Azure Lab Services を使う方法については、こちらの記事を参照してください。
gooner.hateblo.jp

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

ARM テンプレートと呼ばれ、インフラの構築作業をスクリプトによって実施する考え方の Infrastructure as Code を Azure 上で実現するための機能です。テンプレートとパラメータの2つの JSON ファイルから構成され、Azure CLI や Azure Portal からデプロイできます。

ARM テンプレートでリソースの複数インスタンスを作成する

ARM テンプレートでリソースの複数インスタンスを作成するには、copy オブジェクトを使います。
docs.microsoft.com

仮想マシンのリソースを作成する部分を例に挙げます。

{
    "name": "[concat(variables('virtualMachineName'), copyindex())]",
    "type": "Microsoft.Compute/virtualMachines",
    "apiVersion": "2018-10-01",
    "location": "[resourceGroup().location]",
    "dependsOn": [
        "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]",
        "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', variables('virtualNetworkName'))]",
        "networkInterfaceLoop",
        "[resourceId(resourceGroup().name, 'Microsoft.Storage/storageAccounts', variables('diagnosticsStorageAccountName'))]"
    ],
    "properties": {
        "hardwareProfile": {
            "vmSize": "Standard_DS1_v2"
        },
        "storageProfile": {
            "osDisk": {
                "createOption": "fromImage",
                "managedDisk": {
                    "storageAccountType": "StandardSSD_LRS"
                }
            },
            "imageReference": {
                "publisher": "MicrosoftWindowsServer",
                "offer": "WindowsServer",
                "sku": "2016-Datacenter",
                "version": "latest"
            }
        },
        "networkProfile": {
            "networkInterfaces": [
                {
                    "id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('networkInterfaceName'), copyindex()))]"
                }
            ]
        },
        "osProfile": {
            "computerName": "[concat(variables('virtualMachineName'), copyindex())]",
            "adminUsername": "[parameters('adminUsername')]",
            "adminPassword": "[parameters('adminPassword')]",
            "windowsConfiguration": {
                "enableAutomaticUpdates": true,
                "provisionVmAgent": true
            }
        },
        "diagnosticsProfile": {
            "bootDiagnostics": {
                "enabled": true,
                "storageUri": "[concat('https://', variables('diagnosticsStorageAccountName'), '.blob.core.windows.net/')]"
            }
        }
    },
    "copy": {
        "name": "virtualMachineLoop",
        "count": "[parameters('numberOfInstances')]"
    }
}

ポイントは、下記の3点です。

  • パラメータで指定された作成する仮想マシンの台数を copy オブジェクトの count で指定する
  • 仮想マシンの名前に copyindex() を付加して重複を防ぐ
  • dependsOnnetworkInterfaceLoop を指定して NIC 作成後に仮想マシンを作成する依存関係を設定する

同じように Public IP Addresses と Network Interfaces も、copy オブジェクトで複数作成することで、パラメータで指定された台数分の仮想マシンを作成できます。
Azure CLI を使って、ARM テンプレートを実行してデプロイします。

$ az group create -n <ResourceGroup Name> -l japaneast
$ az group deployment create -g <ResourceGroup Name> --template-file template.json --parameters parameters.json

Custom Image を利用する

前述の ARM テンプレートは、Windows Server 2016 Datacenter のデフォルトのイメージを使っています。ハンズオンなどのトレーニングでの利用を想定すると、カスタムのイメージを使うケースのほうが多いと思います。

必要なアプリケーションなどをインストールした仮想マシンで PowerShell を使って sysprep を実行します。

& "$Env:SystemRoot\system32\sysprep\sysprep.exe" /generalize /oobe /shutdown

続いて、仮想マシンのイメージを作成します。仮想マシンと同じリソースグループにイメージが作成されるので、コマンド実行後に別のリソースグループへ移動しておきましょう。

# VM の割り当てを解除する
$ az vm deallocate -g <myResourceGroup> -n <myVM>

# VM の状態を一般化に設定する
$ az vm generalize -g <myResourceGroup> -n <myVM>

# VM リソースのイメージを作成する
$ az image create -g <myResourceGroup> -n <myImage> --source <myVM>

ARM テンプレートでは、imageReference で利用したいイメージの imageRsourceGroupNameimageName を指定します。

"imageReference": {
    "id": "[resourceId(parameters('imageRsourceGroupName'), 'Microsoft.Compute/images', parameters('imageName'))]"
}

Shared Image Gallery を利用する

Shared Image Gallery は、仮想マシンのイメージをサブスクリプションやテナントをまたいで利用できるリソースです。イメージのバージョンを管理することもできるので、Shared Image Gallery のほうが保守性は高いと思います。

Azure Portal から、作成済みのイメージから Shared Image Gallery を作成できます。
docs.microsoft.com

ARM テンプレートでは、imageReference で利用したい Shared Image Gallery の galleryNamegalleryImageDefinitionNamegalleryImageVersionName を指定します。

"imageReference": {
    "id": "[resourceId('Microsoft.Compute/galleries/images/versions', parameters('galleryName'), parameters('galleryImageDefinitionName'), parameters('galleryImageVersionName'))]"
}

まとめ

Azure Resource Manager テンプレートを使って、複数の仮想マシンを Azure 上に構築してみました。copy オブジェクトは利用頻度が高いので、使いこなせるようになると Infrastructure as Code の効率が上がります。
作成した ARM テンプレートの JSON ファイルは、こちらを参照してください。
github.com