你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure VM 映像生成器创建开发框映像

本文介绍如何使用 Azure VM 映像生成器模板在 Azure 计算库中创建自定义 VM 映像并将其全局分发。 然后,可以使用映像在 Microsoft Dev Box 中创建开发框。

标准化 VM 映像可以通过包含预定义的安全性、配置和软件,帮助您确保开发环境的部署一致性。 但手动设置映像管道非常耗时且复杂,创建自定义虚拟机(VM)映像可能困难且不可靠。

Azure VM 映像生成器是基于 HashiCorp Packer 的托管服务,简化了为开发框创建和生成 VM 映像的过程。 本文中的映像生成器模板包括安装 Visual Studio Code 和 Chocolatey 的自定义步骤。

VM 映像生成器可以:

  • 抽象化手动步骤或复杂的工具和流程,并隐藏特定于 Azure 的需求。 例如,通过运行 sysprep 通用化映像,但允许高级用户替代它。
  • 使用现有的映像生成管道。 可以从管道调用 VM 映像生成器或使用 Azure Pipelines 中的 Azure VM 映像生成器服务任务。
  • 从不同来源收集自定义数据,这样您就不必再自行收集。
  • 与 Azure 计算库集成,为全局分发、复制、版本控制和缩放创建映像管理系统。 可以将映像作为虚拟硬盘和托管映像分发,而无需重新生成它。

重要说明

Microsoft Dev Box 只支持使用受信任的启动安全类型的映像。

Prerequisites

本文中的示例使用 Azure PowerShell。 还可以使用 Azure CLI。

类别 要求
工具和权限 拥有 所有者参与者 权限的 Azure 资源组。
Tools 已安装 Azure PowerShell 6.0 或更高版本。 有关说明,请参阅 在 Windows 上安装 Azure PowerShell

设置工具和角色

如需设置工具和角色,请执行以下操作:

  1. 安装必要的 Azure PowerShell 模块。
  2. 为多次使用的信息设置变量。
  3. 注册必要的 Azure 资源提供程序。
  4. 为资源组创建用户标识,并为其分配一个允许分发映像的角色。

安装 PowerShell 模块

运行以下命令安装必要的 PowerShell 模块:

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

对有关不受信任的存储库的提示做出 Y 响应。

设置变量

创建变量以存储多次使用的信息。 运行以下代码,将其 <resource-group> 替换为资源组名称和 <location> 要使用的 Azure 区域。

# Get existing context 
$currentAzContext = Get-AzContext

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

# Destination image resource group  
$imageResourceGroup="<resource-group>"

# Location
$location="<location>"

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

# Image template name  
$imageTemplateName="vscodeWinTemplate"  

注册 Azure 资源提供程序

若要使用 VM 映像生成器,必须注册以下 Azure 资源提供程序:

  • Microsoft.VirtualMachineImages
  • Microsoft.Compute
  • Microsoft.Network
  • Microsoft.Storage
  • Microsoft.KeyVault
  • Microsoft.ContainerInstance
  1. 运行以下命令检查提供程序注册:

      Get-AzResourceProvider -ProviderNamespace "Microsoft.VirtualMachineImages", "Microsoft.Compute", "Microsoft.Network", "Microsoft.Storage", "Microsoft.KeyVault", "Microsoft.ContainerInstance" | Format-table -Property ProviderNamespace,RegistrationState
    
  2. 如果任何提供程序注册未返回 Registered,请通过运行命令 Register-AzResourceProvider 来注册提供程序。 以下示例注册 Microsoft.VirtualMachineImages 资源提供程序。

      Register-AzResourceProvider -ProviderNamespace Microsoft.VirtualMachineImages
    

创建和分配用户标识

创建允许分发映像的 Azure 角色定义。 然后为资源组创建用户分配的标识,并将角色分配给用户标识。 VM 映像生成器使用用户标识将映像存储在 Azure 计算库中。

  1. 运行以下代码来创建 Azure 角色定义和用户标识。

    # Set up a unique role definition name
    $timeInt=$(get-date -UFormat "%s") 
    $imageRoleDefName="Azure Image Builder Image Def"+$timeInt 
    $identityName="aibIdentity"+$timeInt 
    
    # Create an identity 
    New-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName -Location $location
    
    $identityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id 
    $identityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId
    
  2. 运行以下代码下载 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" 
    

若要将 VM 映像生成器与 Azure 计算库配合使用,需要一个库和一个映像定义。 以下步骤创建新的库和映像定义并自定义 VM 映像生成器模板。

  1. 运行以下命令以创建新库和映像定义,该定义具有 Windows 365 映像所需的受信任启动安全类型。

    # Gallery name 
    $galleryName= "devboxGallery" 
    
    # Image definition name 
    $imageDefName ="vscodeImageDef" 
    
    # Second replication region 
    $replRegion2="eastus" 
    
    # Create the gallery 
    New-AzGallery -GalleryName $galleryName -ResourceGroupName $imageResourceGroup -Location $location 
    
    $SecurityType = @{Name='SecurityType';Value='TrustedLaunch'} 
    $features = @($SecurityType) 
    
    # Create the image definition
    New-AzGalleryImageDefinition -GalleryName $galleryName -ResourceGroupName $imageResourceGroup -Location $location -Name $imageDefName -OsState generalized -OsType Windows -Publisher 'myCompany' -Offer 'vscodebox' -Sku '1-0-0' -Feature $features -HyperVGeneration "V2" 
    
  2. 将 VM 映像生成器的以下 Azure 资源管理器模板复制并粘贴到新文件中。 将文件保存到 c:\temp\mytemplate.js等位置,然后关闭该文件。

    该模板定义应用的源映像和自定义项,安装 Chocolatey 和 Visual Studio Code,并指示映像分发位置。

    {
       "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
       "contentVersion": "1.0.0.0",
       "parameters": {
         "imageTemplateName": {
          "type": "string"
         },
         "api-version": {
          "type": "string"
         },
         "svclocation": {
          "type": "string"
         }
       },
       "variables": {},
       "resources": [
         {
          "name": "[parameters('imageTemplateName')]",
          "type": "Microsoft.VirtualMachineImages/imageTemplates",
          "apiVersion": "[parameters('api-version')]",
          "location": "[parameters('svclocation')]",
          "dependsOn": [],
          "tags": {
            "imagebuilderTemplate": "win11multi",
            "userIdentity": "enabled"
          },
          "identity": {
            "type": "UserAssigned",
            "userAssignedIdentities": {
             "<imgBuilderId>": {}
            }
          },
          "properties": {
            "buildTimeoutInMinutes": 100,
            "vmProfile": {
             "vmSize": "Standard_DS2_v2",
             "osDiskSizeGB": 127
            },
          "source": {
             "type": "PlatformImage",
             "publisher": "MicrosoftWindowsDesktop",
             "offer": "Windows-11",
             "sku": "win11-21h2-ent",
             "version": "latest"
          },
            "customize": [
             {
                "type": "PowerShell",
                "name": "Install Choco and VS Code",
                "inline": [
                   "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))",
                   "choco install -y vscode"
                ]
             }
            ],
             "distribute": 
             [
                {   
                   "type": "SharedImage",
                   "galleryImageId": "/subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/galleries/<sharedImageGalName>/images/<imageDefName>",
                   "runOutputName": "<runOutputName>",
                   "artifactTags": {
                      "source": "azureVmImageBuilder",
                      "baseosimg": "win11multi"
                   },
                   "replicationRegions": [
                     "<region1>",
                     "<region2>"
                   ]
                }
             ]
          }
         }
       ]
      }
    
  3. 通过运行以下代码使用设置配置新模板,并将 <template-location> 替换为模板文件位置和名称。

    $templateFilePath = "<template-location>"
    
    (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>',$galleryName| 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 
    

生成和查看映像

将自定义模板提交到 VM 映像生成器服务并生成映像。

  1. 运行以下命令,将模板提交到服务。 该命令下载任何依赖项目(如脚本),并将其存储在前缀为 IT_ 的过渡资源组中。

    New-AzResourceGroupDeployment  -ResourceGroupName $imageResourceGroup  -TemplateFile $templateFilePath  -Api-Version "2020-02-14"  -imageTemplateName $imageTemplateName  -svclocation $location 
    
  2. 通过在模板上调用 Run 操作来生成镜像。 在确认提示符下,输入 YYes

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

重要说明

创建映像并将其复制到两个区域可能需要一些时间。 PowerShell 和 Azure 门户之间可能会看到不同的进度报告。 等待该过程完成后,再开始从映像中创建开发环境定义。

获取有关图像的信息

运行以下命令以获取有关新生成的映像的信息,包括运行状态和预配状态。

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

示例输出:

Name              LastRunStatusRunState LastRunStatusMessage ProvisioningState
----              --------------------- -------------------- -----------------
vscodeWinTemplate Running                                    Succeeded

你还可以在 Azure 门户中查看映像的预配状态。 转到图库以查看图像分辨率。

显示自定义映像版本的预配状态的屏幕截图。

自定义映像存储在库中后,可以将库配置为在 Microsoft Dev Box 开发中心使用这些映像。 有关详细信息,请参阅 为 Microsoft Dev Box 配置 Azure 计算库

在开发中心发布库映像后,你可以将自定义映像附加到开发箱项目,并使用它创建开发箱。 有关详细信息,请参阅 快速入门:配置 Microsoft Dev Box