ARM Template の書き方 その4 VM,Disks,KeyVault

  • VirtualMachine
  • AzureResourceManager
  • AzurePowerShell
  • KeyVault
  • 過去記事

    ARM Template について4本目の記事となります。これまでに、テンプレートの構文や、パラメータファイルの使い方、依存関係や関数 resourceID について確認してきました。

    今回は、VirtualMachine を作成しつつ、Disk を追加する方法や、KeyVault からパスワードを取得することで、テンプレートにパスワードを書かない方法などを紹介していきたいと思います。

    やりたいこと

    以下のような Virtual Machine のシングル構成を作成します。ディスクは osDisk に加え、dataDisk をアタッチしてみたいと思います。

    arm-template-writing-4-3

    テンプレートのベースは 101-1vm-2nics-2subnets-1vnet を参考にしています。

    VirtualMachine の Disk

    osDisk と dataDisk

    Azure の VirtualMachine には大きく分けて2種類の Disk があります。OS がインストールされる osDisk と任意に追加できるストレージである dataDisk です。

    また、dataDisk は事前に作成しておき、VirtualMachine にアタッチする方法を取りますが、osDisk は VirtualMachine 作成時に一緒に新規作成する方法をとります。

    どちらも作成済みの Disk をアタッチしようとすると以下のようなエラーメッセージが出力されます。

    5:20:26 PM - The deployment 'dba-dev-20210118171924' failed with error(s). Showing 1 out of 1 error(s). Status Message: Cannot attach an existing OS disk if the VM is created from a platform, user or a shared gallery image. (Code:InvalidParameter) CorrelationId:

    上記のエラーは、Azure が用意した OS イメージから VirtualMachine を作成するときに発生したものです。今回のやり方では、osDisk に既存の Disk は使用できません。

    dataDisk のサンプルテンプレート

    VirtualMachine の作成前に Disk を用意しておきましょう。

    {
      "type": "Microsoft.Compute/disks",
      "apiVersion": "2019-07-01",
      "name": "[variables('virtualMachines').vm01.dataDiskName01]",
      "location": "[variables('location')]",
      "properties": {
          "osType": "Windows",
          "diskIOPSReadWrite": 500,
          "diskMBpsReadWrite": 60,
          "diskSizeGB": 256,
          "creationData": {
          "createOption": "Empty"
          },
          "encryption": {
          "type": "EncryptionAtRestWithPlatformKey"
          }
      },
      "sku": {
          "name": "StandardSSD_LRS"
      }
    }

    差分チェック

    上記の Disk は StandardSSD_LRS のクラスを使用しています。ポイントは、diskIOPSReadWrite と diskMBpsReadWrite と encryption.type の値を書いていることです。

    diskIOPSReadWrite と diskMBpsReadWrite と encryption.type はデフォルト値が存在しますので、上記の例では、デフォルト値と同じ値を明示的に書いています。もし書かなければ、デプロイ時に毎回差分として出てきてしまいます。

    リソースを作成した後は、下記のようにコンソールから Export template を行って結果と差分がないか確認した方が良いでしょう。

    arm-template-writing-4-2

    KeyVault からパスワードを参照

    パラメータファイルにパスワードを直書きはしたくありません。せっかくなので、KeyVault にパスワードを保存してそれを利用する方法を試してみたいと思います。

    単純に KeyVault のシークレットを参照するだけであれば、とても簡単でした。

    事前準備 KeyVault にシークレット登録

    今回テンプレートからデプロイするリソースグループとは別のリソースグループに、keyVault を作成し、そこに Secrets を登録することと、Azure Resource Manager for template deployment のチェックを入れておきます。

    arm-template-writing-4-5

    arm-template-writing-4-6

    パラメータファイルから KeyVault を参照

    パラメータファイルから KeyVault の値を参照するには以下のように記述します。

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.2.0.0",
      "parameters": {
          "ownerName": {
              "value": "atsushi.koizumi"
          },
          "serviceName": {
              "value": "dba"
          },
          "environmentName": {
              "value": "dev"
          },
          "myhomeIPaddress": {
            "reference": {
                "keyVault": {
                    "id": "/subscriptions/00000000-000-0000-0000-000000000000/resourceGroups/atsushi.koizumi.data/providers/Microsoft.KeyVault/vaults/koizumi-key"
                },
                "secretName": "myhomeIPaddress"
            }
          },
          "adminPassword": {
              "reference": {
                  "keyVault": {
                      "id": "/subscriptions/00000000-000-0000-0000-000000000000/resourceGroups/atsushi.koizumi.data/providers/Microsoft.KeyVault/vaults/koizumi-key"
                  },
                  "secretName": "dba-adminPassword"
              }
          }
      }
    }

    VirtualMachine(WindowsServer)のサンプルテンプレート

    依存関係

    今回、VirtualMachine を作成するにあたっての依存関係は以下のようになります。

    arm-template-writing-4-3

    上記の依存関係を意識しながらテンプレートの dependsOn を書いていきます。

    Virtualmachine(WindowsServer)のサンプルテンプレート

    私は 101-1vm-2nics-2subnets-1vnet を参考にしながら、dataDisk 要素を加えて下記のテンプレートを作成しました。

    {
      "comments": "Virtual Machine",
      "name": "[variables('virtualMachines').vm01.name]",
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2019-07-01",
      "location": "[variables('location')]",
      "dependsOn": [
        "[variables('resourceID').nic01]",
        "[variables('resourceID').vm01dataDisk01]"
      ],
      "tags": "[variables('tags')]",
      "properties": {
        "osProfile": {
          "computerName": "[variables('virtualMachines').vm01.computerName]",
          "adminUsername": "[variables('virtualMachines').vm01.adminUsername]",
          "adminPassword": "[parameters('adminPassword')]",
          "windowsConfiguration": {
            "provisionVmAgent": true,
            "enableAutomaticUpdates": true,
            "timeZone": "Tokyo Standard Time"
          }
        },
        "hardwareProfile": {
          "vmSize": "Standard_F2"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2019-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            // Cannot attach an existing OS disk if the VM is created from a platform, user or a shared gallery image.
            "name": "[variables('virtualMachines').vm01.osDiskName]",
            "osType": "Windows",
            "diskSizeGB": 128,
            "caching": "ReadWrite",
            "createOption": "FromImage",
            "managedDisk": {
              "storageAccountType": "StandardSSD_LRS"
            }
          },
          "dataDisks": [
            // start --> diskmgmt.msc (Disk Management wizard)
            {
              "lun": 0,
              "name": "[variables('virtualMachines').vm01.dataDiskName01]",
              "managedDisk": {
                "id": "[variables('resourceID').vm01dataDisk01]"
              },
              "createOption": "Attach",
              "caching": "ReadWrite"
            }
          ]
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "properties": {
                "primary": true
              },
              "id": "[variables('resourceID').nic01]"
            }
          ]
        },
        "diagnosticsProfile": {
          "bootDiagnostics": {
            "enabled": true,
            "storageUri": "[reference(variables('resourceID').storage01, '2019-06-01').primaryEndpoints['blob']]"
          }
        }
      }
    }

    最後に

    これで何とか Azure 上で Windowsサーバーが使えるようになりました。

    次はこの Virtual Machine を使って、SQL Server や他のデータベースも構築して、SQL が実行できるようにしていきたいと思います。

  • VirtualMachine
  • AzureResourceManager
  • AzurePowerShell
  • KeyVault