[検証]Azure専用プログラミング言語Bicepを試してみた(第2弾VMデプロイ編)~Infrastructure as Code~#Azure リレー

FIXER藤井です。先週の弊社多田の「従量課金のAPI ManagementとLogicAppsでIP制限する #Azure リレー」に続き、今週のAzure リレーを担当します。先月5月25日にAzure リレーとして寄稿した「[検証]Azure専用プログラミング言語Bicepを試してみた~Infrastructure as Code~#Azure リレー」の第二弾として、Azure のInfrastructure as Code用言語「Bicep」のさらなる検証結果を報告いたします。

前回の記事について

「そもそもInfrastructure as Codeとは何か」と「その中でBicepの位置づけとは何か」については、前回の「[検証]Azure専用プログラミング言語Bicepを試してみた~Infrastructure as Code~#Azure リレー」で詳しく解説しておりますので、まだ読んでいない方は今回の記事を読む前にどうか先にお読みください。

前回の記事を寄稿した2021年5月25日以降では、2021年6月2日にVersion 0.4が 公開されています。

With Bicep v0.4 available June 2, 2021, developers can enjoy better day-to-day authoring as well as overall quality and improved stability, with the following additional capabilities:

https://azure.microsoft.com/en-us/blog/new-azure-capabilities-to-simplify-deployment-and-management/

検証

今回の検証では前回の検証にてBicepを利用してデプロイしたAzure Virtual Network に接続するAzure仮想マシンを、Bicepを利用してデプロイします。

観点としては以下の2段階に分けて検証します。

  • 検証(1)パラメーターファイルを利用したデプロイ
  • 検証(2)Azure Keyvaultを利用したデプロイ

今回はVMのデプロイの成功を主眼とし、ログイン確認までは行わないものとします。もしこの記事をお読みの方が自分でもやってみるときに、ログイン確認まで行いたいのであれば、パブリックIPアドレスの追加とNetwork Security Groupの受信規則の追加を実施してください。

検証(1)パラメーターファイルを利用したデプロイ

検証(1)では以下のStep1~Step3の順番で実施します。

  • Step1.ARMテンプレートのテンプレートファイルおよびパラメーターファイルの作成
  • Step2.ARMテンプレートからBicepへの変換
  • Step3.Bicepでのデプロイ

Bicep及び前身となったARMテンプレートでは、テンプレートファイルとは独立したパラメーターファイルを組み合わせて利用することもできます。両者の基本的な役割分担は以下のようなものです。

  • テンプレートファイル:文字通り「テンプレート」ととして複数の環境に標準的に共通して適用される設定が記載されます。基本的にあまり編集はされずに使いまわしされることが想定されます。
  • パラメーターファイル:環境ごとに個別に適用される設定が記載されます。今回のVMのログインアカウント&パスワードの設定は最も典型的な使用例です。

前回の記事でAzure Virtual Network 及びNetwork Security Groupをデプロイしたときのように、パラメーターファイルを使用せずテンプレートファイルに全ての設定情報を記載し、テンプレートファイル単独でデプロイすることも可能です。

Step1.ARMテンプレートのテンプレートファイルおよびパラメーターファイルの作成

今回の検証で使用するARMテンプレートのテンプレートファイルおよび、パラメーターファイルについて、それぞの詳細は以下の通りです。

パラメーターファイル
  • l.5にてパラメーターの変数名として「adminUsername」を宣言しています。
  • l.6にてパラメーターの変数「adminUsername」の設定値を指定しています。
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "value": "blogadmin"
    }
  }
}
テンプレートファイル
  • l.5-l.9にてパラメータファイルで定義されている同じ変数名「adminUsername」が定義されています。
  • l.11-l.17にて定義されている「adminPassword」では、l.12でパスワード用に”securestring”というデータ型が指定されています。
  • l.20に作成するVMのリソース名「FixerBlog-Vm」を指定しています。
  • l.21にて作成する仮想NICのリソース名「FixerBlog-Nic」を指定しています。
  • l.22-l.24にてすでに作成済みのAzure Virtual Network所属のSubnetのリソースIDを指定しています。
  • l.40にて上記l.22-l.24で取得したSubnetのリソースIDを仮想NICの作成時に参照しています。
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Username for the Virtual Machine."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "minLength": 12,
      "metadata": {
        "description": "Password for the Virtual Machine."
      }
    }
  },
  "variables": {
    "vmName": "FixerBlog-Vm",
    "nicName": "FIXERblog-Nic",
    "subnetName": "FIXERblog-Subnet",
    "virtualNetworkName": "FIXERblog-Vnet",
    "subnetRef": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]"
  },
  "resources": [
    {
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2020-06-01",
      "name": "[variables('nicName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [],
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[variables('subnetRef')]"
              }
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2020-06-01",
      "name": "[variables('vmName')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "Standard_A2_v2"
        },
        "osProfile": {
          "computerName": "fixerblogvm",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "2019-Datacenter",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage",
            "managedDisk": {
              "storageAccountType": "StandardSSD_LRS"
            }
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('nicName'))]"
            }
          ]
        }
      }
    }
  ],
  "outputs": {
  }
}

Step2.ARMテンプレートからBicepへの変換

PowerShellのコマンドによりARMテンプレートからBicepへの変換をします。事前に必要なコンポーネントのインストール手順については前回の記事にて解説しているのでそちらをご参照ください。

  1. PowerShellにてカレントディレクトリを対象ARMテンプレートの保存パスに変更します
    cd %保存ディレクトリ%
  2. 以下のコマンドによりBicepファイルへの変換を実行します。
    bicep decompile 【ファイル名】
  3. 以下のようにPowerShell上で表示されればOKです。

実際に作成されたBicepファイルの内容は以下のようなものです。元のARMテンプレートでは90行だったのが、Bicepファイルでは68行まで圧縮されています。

@description('Username for the Virtual Machine.')
param adminUsername string

@minLength(12)
@description('Password for the Virtual Machine.')
@secure()
param adminPassword string

var vmName_var = 'FixerBlog-Vm'
var nicName_var = 'FIXERblog-Nic'
var subnetName = 'FIXERblog-Subnet'
var virtualNetworkName = 'FIXERblog-Vnet'
var subnetRef = resourceId('Microsoft.Network/virtualNetworks/subnets', virtualNetworkName, subnetName)

resource nicName 'Microsoft.Network/networkInterfaces@2020-06-01' = {
  name: nicName_var
  location: resourceGroup().location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          subnet: {
            id: subnetRef
          }
        }
      }
    ]
  }
  dependsOn: []
}

resource vmName 'Microsoft.Compute/virtualMachines@2020-06-01' = {
  name: vmName_var
  location: resourceGroup().location
  properties: {
    hardwareProfile: {
      vmSize: 'Standard_A2_v2'
    }
    osProfile: {
      computerName: 'fixerblogvm'
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'MicrosoftWindowsServer'
        offer: 'WindowsServer'
        sku: '2019-Datacenter'
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: 'StandardSSD_LRS'
        }
      }
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nicName.id
        }
      ]
    }
  }
}

Step3.Bicepでのデプロイ

Azure PowerShellを使用してBicepをデプロイします。Azure PowerShellを触ったことが無い方は手前味噌ですが、過去の拙記事「Azure PowerShell に初めて挑戦する人のための手引き①【入門編】」を併せてご参照ください。

  1. 以下のコマンドAzureにログインします。
    Login-AzAccount
  2. 以下のコマンドによりサブスクリプションを選択します
    Select-AzSubscription -SubscriptionId 【サブスクリプションID】
  3. 以下のコマンドにより作成先のリソースグループ名を指定します。(前回の記事で作成済みのリソースグループです。)
    $rg = ‘bicep’
  4. 以下の対象のBicepのテンプレートファイルのローカルのフルパス(ドライブ文字からファイル名まで全て)を指定します。
    $templatefilepath = '【フルパス】'
  5. 以下の対象のパラメーターファイルのローカルのフルパス(ドライブ文字からファイル名まで全て)を指定します。
    $parameterfilepath = '【フルパス】'
  6. 以下のコマンドによりAzureのデプロイを実行します。
    New-AzResourceGroupDeployment -ResourceGroupName $rg -TemplateFile $templatefilepath -TemplateParameterFile $parameterfilepath
  7. PowerShell上でVMのログインパスワードを入力し、以下のように表示されれれば作成が完了です。

Azure Keyvaultの登場以降、ARMテンプレートではVMのパスワードの情報はAzure Keyvaultを利用することが推奨とされています。次の検証(2)ではAzure KeyvaultとBicepの組み合わせを見ていきます。

検証(2)Azure Keyvaultを利用したデプロイ

検証(2)では以下のStep1とStep2で段階を分けて実施します。

  • Step1.Azure Keyvaultの作成
  • Step2.Azure KeyvaultとBicepの組み合わせによるデプロイ

Step1.Azure Keyvaultの作成

  1. 以下のコマンドAzureにログインします。
    Login-AzAccount
  2. 以下のコマンドによりサブスクリプションを選択します
    Select-AzSubscription -SubscriptionId 【サブスクリプションID】
  3. 以下のコマンドにより作成先のリソースグループ名を指定します。(前回の記事で作成済みのリソースグループです。)
    $rg = ‘bicep’
  4. 以下のコマンドにより作成対象のAzure Keyvaultのリソース名を指定します。
    $KeyVaultName = 'FixerBlog-Kv'
  5. 以下のコマンドにより作成対象のシークレットのリソース名を指定します。
    $SecretName = 'FixerBlog-Secret'
  6. 以下のコマンドによりAzure Keyvaultのデプロイを実行します。
    New-AzKeyVault -VaultName $KeyVaultName -resourceGroupName $rg -Location japaneast -EnabledForTemplateDeployment
  7. 以下のコマンドによりVMに設定予定のパスワードを入力します。
    $secretvalue = ConvertTo-SecureString '【パスワード】' -AsPlainText -Force
  8. 以下のコマンドによりシークレットとしてAzure Keyvaultに登録します。
    $secret = Set-AzKeyVaultSecret -VaultName $KeyVaultName -Name $SecretName -SecretValue $secretvalue
  9. Azure Portal上で作成を確認します。

Step2.Azure KeyvaultとBicepの組み合わせによるデプロイ

  1. 以下のコマンドによりAzure KeyvaultのリソースIDを確認します。
    Get-AzKeyVault -ResourceGroupName $rg
  2. 上記で確認したリソースIDでパラメーターファイルを以下のように編集します。
  3. 検証(1)のStep3と同様の手順でデプロイを実行します。
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "value": "blogadmin"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "【リソースID】"
        },
        "secretName": "FixerBlog-Secret"
      }
    }
  }
}

最後に

Bicepは今後、どんどんとバージョンアップし機能が追加されることが予想されます。もしまたバージョンアップが発表されたら検証記事の第3弾、第4弾を書くのが個人的な目論見です。

FIXER Inc. 藤井 廉
  • FIXER Inc. 藤井 廉
  • Cloud Solutions Engineer
    保有資格:
    Microsoft DevOps Engineer Expert(AZ-400)
    Microsoft Azure Solutions Architect Expert(AZ-300 & AZ-301)
    Azure Database Administrator Associate(DP-300)
    Microsoft Azure Developer Associate(AZ-203)
    Microsoft Azure Security Engineer Associate(AZ-500)
    Microsoft Azure Administrator Associate(AZ-102:制度変更により廃止された「70-533 Microsoft Azure Infrastructure Solutions の実装」の既合格者を対象とした移行試験で、AZ-103と同等の資格)