💪

BicepでVMを作成する

2023/08/06に公開

タイトルの通り、Bicepを使用してWindowsVMを作成したので備忘として残しておきます。

事前準備

以下のMicroSoft公式サイトに記載があるので、準備を行います。大きく以下3点の対応が必要です。
 1.VisualStudioCodeのインストール 
 2.VisualStudioCodeの Bicep 拡張機能インストール 
 3.AzureCLI or AzurePowershellへのbicepインストール
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/install

bicepファイルの作成

bicepをインストールできたらファイルを作成していきます。ARMよりだいぶ分かりやすくコメントも記載できます。
以下Windows作成のサンプルファイルです。
作成出来たら、.bicepの拡張子で保存します。
※参考
https://learn.microsoft.com/ja-jp/azure/virtual-machines/windows/quick-create-bicep?tabs=PowerShell

//VMユーザ名
@description('Username for the Virtual Machine.')
param adminUsername string

//VMパスワード
@description('Password for the Virtual Machine.')
@minLength(12)
@secure()
param adminPassword string

//パブリックIPのDNSラベル
@description('Unique DNS Name for the Public IP used to access the Virtual Machine.')
param dnsLabelPrefix string = toLower('${vmName}-${uniqueString(resourceGroup().id, vmName)}')

//パブリックIP名
@description('Name for the Public IP used to access the Virtual Machine.')
param publicIpName string = 'myPublicIP'

//パブリックIPの種別
@description('Allocation method for the Public IP used to access the Virtual Machine.')
@allowed([
  'Dynamic'
  'Static'
])
param publicIPAllocationMethod string = 'Dynamic'

//パブリックIPのSKU
@description('SKU for the Public IP used to access the Virtual Machine.')
@allowed([
  'Basic'
  'Standard'
])
param publicIpSku string = 'Basic'

//VM種別(Windows)
@description('The Windows version for the VM. This will pick a fully patched image of this given Windows version.')
@allowed([
  '2016-datacenter-gensecond'
  '2016-datacenter-server-core-g2'
  '2016-datacenter-server-core-smalldisk-g2'
  '2016-datacenter-smalldisk-g2'
  '2016-datacenter-with-containers-g2'
  '2016-datacenter-zhcn-g2'
  '2019-datacenter-core-g2'
  '2019-datacenter-core-smalldisk-g2'
  '2019-datacenter-core-with-containers-g2'
  '2019-datacenter-core-with-containers-smalldisk-g2'
  '2019-datacenter-gensecond'
  '2019-datacenter-smalldisk-g2'
  '2019-datacenter-with-containers-g2'
  '2019-datacenter-with-containers-smalldisk-g2'
  '2019-datacenter-zhcn-g2'
  '2022-datacenter-azure-edition'
  '2022-datacenter-azure-edition-core'
  '2022-datacenter-azure-edition-core-smalldisk'
  '2022-datacenter-azure-edition-smalldisk'
  '2022-datacenter-core-g2'
  '2022-datacenter-core-smalldisk-g2'
  '2022-datacenter-g2'
  '2022-datacenter-smalldisk-g2'
])
param OSVersion string = '2022-datacenter-azure-edition'

//仮想マシンのサイズ
@description('Size of the virtual machine.')
param vmSize string = 'Standard_B1s'

//仮想マシンのロケーション
@description('Location for all resources.')
param location string = resourceGroup().location

//仮想マシン名
@description('Name of the virtual machine.')
param vmName string = 'simple-vm'

//仮想マシンのセキュリティの種類
@description('Security Type of the Virtual Machine.')
@allowed([
  'Standard'
  'TrustedLaunch'
])
param securityType string = 'Standard'

//診断ストレージアカウント名定義
var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
//NIC名定義
var nicName = 'myVMNic'
//仮想ネットワークアドレス範囲定義
var addressPrefix = '10.0.0.0/16'
//サブネット名定義
var subnetName = 'Subnet'
//サブネットネットワークアドレス範囲定義
var subnetPrefix = '10.0.0.0/24'
//仮想ネットワーク名範囲定義
var virtualNetworkName = 'MyVNET'
//NSG名定義
var networkSecurityGroupName = 'default-NSG'
//ブート診断設定定義
var securityProfileJson = {
  uefiSettings: {
    secureBootEnabled: true
    vTpmEnabled: true
  }
  securityType: securityType
}
var extensionName = 'GuestAttestation'
var extensionPublisher = 'Microsoft.Azure.Security.WindowsAttestation'
var extensionVersion = '1.0'
var maaTenantName = 'GuestAttestation'
var maaEndpoint = substring('emptyString', 0, 0)
//ストレージアカウント設定
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = {
  name: storageAccountName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'Storage'
}
//パブリックIP設定
resource publicIp 'Microsoft.Network/publicIPAddresses@2022-05-01' = {
  name: publicIpName
  location: location
  sku: {
    name: publicIpSku
  }
  properties: {
    publicIPAllocationMethod: publicIPAllocationMethod
    dnsSettings: {
      domainNameLabel: dnsLabelPrefix
    }
  }
}
//NSG設定
resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2022-05-01' = {
  name: networkSecurityGroupName
  location: location
  properties: {
    securityRules: [
      {
        name: 'default-allow-3389'
        properties: {
          priority: 1000
          access: 'Allow'
          direction: 'Inbound'
          destinationPortRange: '3389'
          protocol: 'Tcp'
          sourcePortRange: '*'
          sourceAddressPrefix: '*'
          destinationAddressPrefix: '*'
        }
      }
    ]
  }
}
//仮想ネットワーク設定
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2022-05-01' = {
  name: virtualNetworkName
  location: location
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
    subnets: [
      {
        name: subnetName
        properties: {
          addressPrefix: subnetPrefix
          networkSecurityGroup: {
            id: networkSecurityGroup.id
          }
        }
      }  
    ]
//カスタムDNS設定    
    dhcpOptions: {
      dnsServers:[
        '10.0.0.1'
        '10.0.0.2'
      ]
      }
  }
}
//NIC設定
resource nic 'Microsoft.Network/networkInterfaces@2022-05-01' = {
  name: nicName
  location: location
  properties: {
    ipConfigurations: [
      {
        name: 'ipconfig1'
        properties: {
          privateIPAllocationMethod: 'Dynamic'
          publicIPAddress: {
            id: publicIp.id
          }
          subnet: {
            id: resourceId('Microsoft.Network/virtualNetworks/subnets', virtualNetworkName, subnetName)
          }
        }
      }
    ]
//NICNSG設定
    networkSecurityGroup: {
      id: networkSecurityGroup.id
    }
  }
  dependsOn: [

    virtualNetwork
  ]
}
//VM設定
resource vm 'Microsoft.Compute/virtualMachines@2022-03-01' = {
  name: vmName
  location: location
  properties: {
    hardwareProfile: {
      vmSize: vmSize
    }
    osProfile: {
      computerName: vmName
      adminUsername: adminUsername
      adminPassword: adminPassword
    }
    storageProfile: {
      imageReference: {
        publisher: 'MicrosoftWindowsServer'
        offer: 'WindowsServer'
        sku: OSVersion
        version: 'latest'
      }
      osDisk: {
        createOption: 'FromImage'
        managedDisk: {
          storageAccountType: 'StandardSSD_LRS'
        }
      }
      dataDisks: [
        {
          diskSizeGB: 30
          lun: 0
          createOption: 'Empty'
        }
      ]
    }
    networkProfile: {
      networkInterfaces: [
        {
          id: nic.id
        }
      ]
    }
    diagnosticsProfile: {
      bootDiagnostics: {
        enabled: true
        storageUri: storageAccount.properties.primaryEndpoints.blob
      }
    }     
    securityProfile: ((securityType == 'TrustedLaunch') ? securityProfileJson : null)
  }
}
//自動シャットダウン設定
resource shutdown 'Microsoft.DevTestLab/schedules@2018-09-15' = {
  name: 'shutdown-computevm-${vmName}'
  location: location
  properties: {
    status: 'Enabled'
    taskType: 'ComputeVmShutdownTask'
    dailyRecurrence: {
      time: '21:00'
    }
    timeZoneId: 'Tokyo Standard Time'
    targetResourceId: vm.id
    notificationSettings: {
      status: 'Disabled'
    }
  }
}
//VM拡張機能設定
resource vmExtension 'Microsoft.Compute/virtualMachines/extensions@2022-03-01' = if ((securityType == 'TrustedLaunch') && ((securityProfileJson.uefiSettings.secureBootEnabled == true) && (securityProfileJson.uefiSettings.vTpmEnabled == true))) {
  parent: vm
  name: extensionName
  location: location
  properties: {
    publisher: extensionPublisher
    type: extensionName
    typeHandlerVersion: extensionVersion
    autoUpgradeMinorVersion: true
    enableAutomaticUpgrade: true
    settings: {
      AttestationConfig: {
        MaaSettings: {
          maaEndpoint: maaEndpoint
          maaTenantName: maaTenantName
        }
      }
    }
  }
}

//RBAC付与
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
  scope: resourceGroup()
  name: guid(resourceGroup().id, '5b1c99bd-d6d0-4ac6-b4d8-fc38d9d50cdd', '/subscriptions/a6b4bab3-e89e-47ad-b02e-0803f44c09e9/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c')
  properties: {
    roleDefinitionId: '/subscriptions/a6b4bab3-e89e-47ad-b02e-0803f44c09e9/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c'
    principalId: '5b1c99bd-d6d0-4ac6-b4d8-fc38d9d50cdd'
    principalType: 'User'
  }
}

output hostname string = publicIp.properties.dnsSettings.fqdn

デプロイ

Powershellの場合、以下を実行します
実行するとパスワードの入力を求められます。

 New-AzResourceGroup -Name exampleRG -Location japaneast
New-AzResourceGroupDeployment -ResourceGroupName exampleRG -TemplateFile .\mkvm.bicep -adminUsername "winuser"

※モジュール定義ができるようなので、今後こちらの方式も調べる予定です。
https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/bicep/modules

Discussion