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

使用 Azure VM 映像生成器和 Microsoft Dev Box 配置开发框

在本文中,你将使用 Azure VM 映像生成器通过模板在 Microsoft Dev Box 中创建自定义开发框。 该模板包括安装 Visual Studio Code(VS Code)的自定义步骤。

当组织使用标准化虚拟机(VM)映像时,它可以更轻松地迁移到云,并帮助确保部署中的一致性。 映像通常包括预定义的安全性、配置设置,以及必需的软件。 设置自己的映像管道需要时间、基础结构和许多其他细节。 使用 Azure VM 映像生成器,可以创建描述映像的配置。 然后,该服务将生成映像并将其提交到开发框项目。

尽管可以手动或使用其他工具创建自定义 VM 映像,但该过程可能很繁琐且不可靠。 Azure VM 映像生成器是在 HashiCorp Packer 上生成的,它可以提供托管服务的优势。

若要降低创建 VM 映像的复杂性,Azure VM 映像生成器:

  • 不再需要使用复杂的工具、过程和手动步骤来创建 VM 映像。 Azure VM 映像生成器提取所有这些详细信息并隐藏特定于 Azure 的要求,例如需要通用化映像 (Sysprep)。 它使更高级的用户能够替代此类要求。

  • 适用于现有映像生成管道,实现即点即用体验。 可以从管道调用 VM 映像生成器或使用 Azure VM 映像生成器服务 DevOps 任务。

  • 从各种源提取自定义数据,无需从一个位置收集所有自定义数据。

  • 与 Azure 计算库集成,该库创建映像管理系统,用于全局分发、副本 (replica)处理、版本控制以及缩放映像。 此外,可以分发与虚拟硬盘或一个或多个托管映像相同的结果映像,而无需从头开始重新生成它们。

重要

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

先决条件

若要预配使用 VM 映像生成器创建的自定义映像,需要:

  • Azure PowerShell 6.0 或更高版本。 如果未安装 PowerShell,请按照在 Windows 上安装 Azure PowerShell 中的步骤操作。
  • Azure 订阅或特定资源组的所有者或参与者权限。
  • 资源组。
  • 具有附加网络连接的开发人员中心。 如果没有,请通过配置网络连接,按照连接开发框中的步骤操作。

第一步是使用 Azure VM 映像生成器和 Azure PowerShell 在 Azure 计算库中创建映像版本,然后全局分发映像。 也可以使用 Azure CLI 执行此任务。

  1. 若要使用 VM 映像生成器,则需要注册此功能。

    检查提供程序注册情况。 确保每个命令 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 
    

    如果提供程序注册未返回 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.Network 
    
  2. 安装 PowerShell 模块:

    'Az.ImageBuilder', 'Az.ManagedServiceIdentity' | ForEach-Object {Install-Module -Name $_ -AllowPrerelease}
    
  3. 创建变量以存储多次使用的信息。

    1. 复制以下示例代码。
    2. 替换为 <Resource group> 用于创建开发人员中心的资源组。
    3. 在 PowerShell 中运行更新的代码。
    # Get existing context 
    $currentAzContext = Get-AzContext
    
    # Get your current subscription ID  
    $subscriptionID=$currentAzContext.Subscription.Id
    
    # Destination image resource group  
    $imageResourceGroup="<Resource group>"
    
    # Location  
    $location="eastus2"
    
    # Image distribution metadata reference name  
    $runOutputName="aibCustWinManImg01"
    
    # Image template name  
    $imageTemplateName="vscodeWinTemplate"  
    
  4. 通过在 PowerShell 中运行以下代码,创建用户分配的标识并设置对资源组的权限。

    VM 映像生成器使用提供的用户标识将映像注入 Azure 计算库。 以下示例创建一个 Azure 角色定义,其中包含用于分发映像的特定操作。 然后将角色定义分配给用户标识。

    # Set up role definition names, which 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 -Location $location
    
    $identityNameResourceId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).Id 
    $identityNamePrincipalId=$(Get-AzUserAssignedIdentity -ResourceGroupName $imageResourceGroup -Name $identityName).PrincipalId
    
  5. 为标识分配权限以分发映像。

    使用此命令下载 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 Compute Gallery 配合使用,需要现有的库和映像定义。 VM 映像生成器不会创建库和映像定义。

  1. 运行以下命令以创建新的库和映像定义。

    此代码使用受信任的启动安全类型创建定义,并满足 Windows 365 映像要求。

    # Gallery name 
    $galleryName= "devboxGallery" 
    
    # Image definition name 
    $imageDefName ="vscodeImageDef" 
    
    # Additional 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. 创建一个文件来存储模板定义,例如 c:/temp/mytemplate.txt。

  3. 将 VM 映像生成器的以下 Azure 资源管理器模板复制到新的模板文件中。

    此模板指示已应用的源映像和自定义项。 它安装 Choco 和 VS 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 Vscode",
                "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>"
                   ]
                }
             ]
          }
         }
       ]
      }
    

    在继续执行下一步之前,请关闭模板文件。

  4. 使用变量配置新模板。

    替换为 <Template Path> 模板文件的位置,例如 c:/temp/mytemplate

    $templateFilePath = <Template Path>
    
    (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 
    
  5. 将模板提交到服务。

    以下命令下载任何依赖项目(如脚本),并将其存储在过渡资源组中。 临时资源组的 IT_前缀为 .

    New-AzResourceGroupDeployment  -ResourceGroupName $imageResourceGroup  -TemplateFile $templateFilePath  -Api-Version "2020-02-14"  -imageTemplateName $imageTemplateName  -svclocation $location 
    
  6. 通过调用 Run 模板上的命令生成映像:

    在提示确认运行过程时,输入 “是”。

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

    重要

    创建映像并将其副本 (replica)两个区域可能需要一些时间。 PowerShell 和Azure 门户之间的进度报告可能会有所不同。 在开始创建开发框定义之前,请等待该过程完成。

  7. 获取有关新生成的映像的信息,包括运行状态和预配状态。

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

    示例输出:

    Name                 LastRunStatusRunState    LastRunStatusMessage   ProvisioningState
    ---------------------------------------------------------------------------------------
    vscodeWinTemplate                                                    Creating
    

    还可以在Azure 门户中查看映像的预配状态。 转到库并查看图像定义。

    Screenshot that shows the provisioning state of the customized image version.

在库中预配自定义映像后,可以将库配置为使用开发人员中心中的映像。 有关详细信息,请参阅配置 Azure Compute Gallery

使用自定义映像设置 Microsoft Dev Box

在开发人员中心中提供库映像后,可以将自定义映像与 Microsoft Dev Box 配合使用。 有关详细信息,请参阅 快速入门:配置 Microsoft Dev Box