Windows イメージを作成して Azure Compute Gallery に配布する

適用対象: ✔️ Windows VM

この記事では、Azure VM Image Builder と Azure PowerShell を使用して Azure Compute Gallery (旧称 Shared Image Gallery) でイメージ バージョンを作成し、そのイメージをグローバルに配布する方法について説明します。 この操作は Azure CLI で実行することもできます。

この記事では、イメージを構成するために JSON テンプレート (armTemplateWinSIG.json から取得可能) を使用します。 ここではテンプレートのローカル バージョンをダウンロードして編集するため、ローカルの PowerShell セッションも使用します。

イメージを Azure Compute Gallery に配布するため、テンプレートでは distribute セクションの値として sharedImage が使われています。

VM Image Builder によって Sysprep が自動的に実行され、イメージが一般化されます。 このコマンドは一般的な Sysprep コマンドで、必要であればオーバーライドすることができます。

カスタマイズを重ねる回数に注意してください。 1 つの Windows イメージに対して、Sysprep コマンドを実行できる回数には制限があります。 Sysprep の制限回数に達した後は、Windows イメージを再作成する必要があります。 詳細は、Sysprep の実行回数制限に関するページを参照してください。

プロバイダーを登録する

VM Image Builder を使用するには、プロバイダーを登録する必要があります。

  1. プロバイダー登録を確認してください。 それぞれが Registered を返していることを確認します。

    Get-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.Storage | Format-table -Property ResourceTypes,RegistrationState 
    Get-AzResourceProvider -ProviderNamespace Microsoft.Compute | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.KeyVault | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.Network | Format-table -Property ResourceTypes,RegistrationState
    Get-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance | Format-table -Property ResourceTypes,RegistrationState
    
  2. Registered が返されない場合は、次のコマンドを実行してプロバイダーを登録します。

    Register-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages
    Register-AzResourceProvider -ProviderNamespace Microsoft.Storage
    Register-AzResourceProvider -ProviderNamespace Microsoft.Compute
    Register-AzResourceProvider -ProviderNamespace Microsoft.KeyVault
    Register-AzResourceProvider -ProviderNamespace Microsoft.ContainerInstance
    
  3. PowerShell モジュールをインストールします。

    'Az.ImageBuilder', 'Az.ManagedServiceIdentity' | ForEach-Object {Install-Module -Name $_ -AllowPrerelease}
    

変数の作成

いくつかの情報を繰り返し使用するので、その情報を格納するいくつかの変数を作成します。

usernamevmpassword などの変数の値は、実際の情報に置き換えてください。

# Get existing context
$currentAzContext = Get-AzContext

# Get your current subscription ID. 
$subscriptionID=$currentAzContext.Subscription.Id

# Destination image resource group
$imageResourceGroup="aibwinsig"

# Location
$location="westus"

# Image distribution metadata reference name
$runOutputName="aibCustWinManImg02ro"

# Image template name
$imageTemplateName="helloImageTemplateWin02ps"

# Distribution properties object name (runOutput).
# This gives you the properties of the managed image on completion.
$runOutputName="winclientR01"

# Create a resource group for the VM Image Builder template and Azure Compute Gallery
New-AzResourceGroup `
   -Name $imageResourceGroup `
   -Location $location

ユーザー割り当て ID を作成し、リソース グループにアクセス許可を設定する

VM Image Builder は、指定されたユーザー ID を使用して、Azure Compute Gallery にイメージを挿入します。 この例では、イメージを配布するための特定のアクションを使用して、Azure ロールの定義を作成します。 このロール定義はその後、ユーザー ID に割り当てられます。

# setup role def names, these need to be unique
$timeInt=$(get-date -UFormat "%s")
$imageRoleDefName="Azure Image Builder Image Def"+$timeInt
$identityName="aibIdentity"+$timeInt

## Add an Azure PowerShell module to support AzUserAssignedIdentity
Install-Module -Name Az.ManagedServiceIdentity

# Create an identity
New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName

$identityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id
$identityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId

ID にイメージを配布するためのアクセス許可を割り当てます

このコマンドを使用して Azure ロール定義テンプレートをダウンロードし、前に指定したパラメーターで更新します。

$aibRoleImageCreationUrl="https://raw.githubusercontent.com/azure/azvmimagebuilder/master/solutions/12_Creating_AIB_Security_Roles/aibRoleImageCreation.json"
$aibRoleImageCreationPath = "aibRoleImageCreation.json"

# Download the configuration
Invoke-WebRequest -Uri $aibRoleImageCreationUrl -OutFile $aibRoleImageCreationPath -UseBasicParsing

((Get-Content -path $aibRoleImageCreationPath -Raw) -replace '<subscriptionID>',$subscriptionID) | Set-Content -Path $aibRoleImageCreationPath
((Get-Content -path $aibRoleImageCreationPath -Raw) -replace '<rgName>', $imageResourceGroup) | Set-Content -Path $aibRoleImageCreationPath
((Get-Content -path $aibRoleImageCreationPath -Raw) -replace 'Azure Image Builder Service Image Creation Role', $imageRoleDefName) | Set-Content -Path $aibRoleImageCreationPath

# Create a role definition
New-AzRoleDefinition -InputFile  ./aibRoleImageCreation.json

# Grant the role definition to the VM Image Builder service principal
New-AzRoleAssignment -ObjectId $identityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"

Note

[New-AzRoleDefinition]というエラーが表示された場合。役割定義の制限を超えました。 [ロールの定義をこれ以上作成することはできません] というエラーが表示された場合は、「Azure RBAC のトラブルシューティング(ロールベースのアクセス制御)」を参照してください。

Azure Compute Gallery で VM Image Builder を使用するには、既存のギャラリーとイメージ定義が必要です。 VM Image Builder では、ギャラリーとイメージ定義は自動的には作成されません。

使用するギャラリーとイメージ定義がまだない場合は、最初に作成します。

# Gallery name
$sigGalleryName= "myIBSIG"

# Image definition name
$imageDefName ="winSvrimage"

# Additional replication region
$replRegion2="eastus"

# Create the gallery
New-AzGallery `
   -GalleryName $sigGalleryName `
   -ResourceGroupName $imageResourceGroup  `
   -Location $location

# Create the image definition
New-AzGalleryImageDefinition `
   -GalleryName $sigGalleryName `
   -ResourceGroupName $imageResourceGroup `
   -Location $location `
   -Name $imageDefName `
   -OsState generalized `
   -OsType Windows `
   -Publisher 'myCompany' `
   -Offer 'WindowsServer' `
   -Sku 'WinSrv2019'

テンプレートをダウンロードし、構成する

.JSON テンプレートをダウンロードし、変数を使用して構成します。


$templateFilePath = "armTemplateWinSIG.json"

Invoke-WebRequest `
   -Uri "https://raw.githubusercontent.com/azure/azvmimagebuilder/master/quickquickstarts/1_Creating_a_Custom_Win_Shared_Image_Gallery_Image/armTemplateWinSIG.json" `
   -OutFile $templateFilePath `
   -UseBasicParsing

(Get-Content -path $templateFilePath -Raw ) `
   -replace '<subscriptionID>',$subscriptionID | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<rgName>',$imageResourceGroup | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<runOutputName>',$runOutputName | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<imageDefName>',$imageDefName | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<sharedImageGalName>',$sigGalleryName | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<region1>',$location | Set-Content -Path $templateFilePath
(Get-Content -path $templateFilePath -Raw ) `
   -replace '<region2>',$replRegion2 | Set-Content -Path $templateFilePath
((Get-Content -path $templateFilePath -Raw) -replace '<imgBuilderId>',$identityNameResourceId) | Set-Content -Path $templateFilePath

イメージ バージョンの作成

テンプレートをサービスに送信する必要があります。 以下のコマンドは、スクリプトなどの依存する成果物をダウンロードし、IT_ というプレフィックスが付けられたステージング リソース グループにそれらを保存します。

New-AzResourceGroupDeployment `
   -ResourceGroupName $imageResourceGroup `
   -TemplateFile $templateFilePath `
   -ApiVersion "2022-02-14" `
   -imageTemplateName $imageTemplateName `
   -svclocation $location

イメージをビルドするには、テンプレート上で "Run" を呼び出します。

Invoke-AzResourceAction `
   -ResourceName $imageTemplateName `
   -ResourceGroupName $imageResourceGroup `
   -ResourceType Microsoft.VirtualMachineImages/imageTemplates `
   -ApiVersion "2022-02-14" `
   -Action Run

イメージの作成、および両方のリージョンへのレプリケートには、しばらくかかる場合があります。 VM の作成を開始する前に、この部分が完了するまで待ちます。

Get-AzImageBuilderTemplate -ImageTemplateName $imageTemplateName -ResourceGroupName $imageResourceGroup |
  Select-Object -Property Name, LastRunStatusRunState, LastRunStatusMessage, ProvisioningState

VM の作成

VM Image Builder で作成されたイメージ バージョンから VM を作成します。

  1. 作成したイメージ バージョンを取得します。

    $imageVersion = Get-AzGalleryImageVersion `
    -ResourceGroupName $imageResourceGroup `
    -GalleryName $sigGalleryName `
    -GalleryImageDefinitionName $imageDefName
    $imageVersionId = $imageVersion.Id
    
  2. イメージがレプリケートされた 2 番目のリージョンで VM を作成します。

    $vmResourceGroup = "myResourceGroup"
    $vmName = "myVMfromImage"
    
    # Create user object
    $cred = Get-Credential -Message "Enter a username and password for the virtual machine."
    
    # Create a resource group
    New-AzResourceGroup -Name $vmResourceGroup -Location $replRegion2
    
    # Network pieces
    $subnetConfig = New-AzVirtualNetworkSubnetConfig -Name mySubnet -AddressPrefix 192.168.1.0/24
    $vnet = New-AzVirtualNetwork -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name MYvNET -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig
    $pip = New-AzPublicIpAddress -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name "mypublicdns$(Get-Random)" -AllocationMethod Static -IdleTimeoutInMinutes 4
    $nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name myNetworkSecurityGroupRuleRDP  -Protocol Tcp `
    -Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
    -DestinationPortRange 3389 -Access Deny
    $nsg = New-AzNetworkSecurityGroup -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -Name myNetworkSecurityGroup -SecurityRules $nsgRuleRDP
    $nic = New-AzNetworkInterface -Name myNic -ResourceGroupName $vmResourceGroup -Location $replRegion2 `
    -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
    
    # Create a virtual machine configuration using $imageVersion.Id to specify the image
    $vmConfig = New-AzVMConfig -VMName $vmName -VMSize Standard_D1_v2 | `
    Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred | `
    Set-AzVMSourceImage -Id $imageVersion.Id | `
    Add-AzVMNetworkInterface -Id $nic.Id
    
    # Create a virtual machine
    New-AzVM -ResourceGroupName $vmResourceGroup -Location $replRegion2 -VM $vmConfig
    

カスタマイズの確認

VM を作成するときに設定したユーザー名とパスワードを使用して、VM へのリモート デスクトップ接続を作成します。 VM でコマンド プロンプト ウィンドウを開き、次のコマンドを実行します。

dir c:\

イメージのカスタマイズ中に作成された buildActions という名前のディレクトリが表示されます。

リソースをクリーンアップする

Note

同じイメージの新しいバージョンを作成するように、イメージ バージョンを再カスタマイズしてみる場合は、ここで説明する手順をスキップしてVM Image Builder を使用した別のイメージ バージョンの作成に関するページに進みます。

この記事のプロセスに従って作成したリソースが不要になった場合は、削除することができます。

以下のプロセスにより、作成したイメージと他のすべてのリソース ファイルの両方が削除されます。 リソースを削除する前に、このデプロイが完了していることを確認してください。

最初にリソース グループ テンプレートを削除します。 そうしないと、VM Image Builder で使用されるステージング リソース グループ (IT_) はクリーンアップされません。

  1. イメージ テンプレートの ResourceID を取得します。

    $resTemplateId = Get-AzResource -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2022-02-14"
    
  2. イメージ テンプレートを削除します。

    Remove-AzResource -ResourceId $resTemplateId.ResourceId -Force
    
  3. ロールの割り当てを削除します。

    Remove-AzRoleAssignment -ObjectId $identityNamePrincipalId -RoleDefinitionName $imageRoleDefName -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
  4. 定義を削除します。

    Remove-AzRoleDefinition -Name "$identityNamePrincipalId" -Force -Scope "/subscriptions/$subscriptionID/resourceGroups/$imageResourceGroup"
    
  5. ID を削除します。

    Remove-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Force
    
  6. リソース グループを削除します。

    Remove-AzResourceGroup $imageResourceGroup -Force
    

次のステップ

この記事で作成したイメージ バージョンを更新するには、VM Image Builder を使用して別のイメージ バージョンを作成する方法に関する記事をご覧ください。