创建Azure映像生成器 Bicep 或 ARM 模板 JSON 模板

适用于:✔️ Linux VM ✔️ Windows VM ✔️ 灵活规模集

Azure映像生成器使用 Bicep 文件或 ARM 模板 JSON 模板文件将信息传递到映像生成器服务。 本文将深入介绍这些文件的各个部分,以帮助你构建自己的文件。 有关最新的 API 版本,请参阅 template 参考。 若要查看完整 .json 文件的示例,请参阅 Azure Image Builder GitHub

基本格式为:

{
  "type": "Microsoft.VirtualMachineImages/imageTemplates",
  "location": "<region>",
  "tags": {
    "<name>": "<value>",
    "<name>": "<value>"
  },
  "identity": {},
  "properties": {
    "buildTimeoutInMinutes": <minutes>,
    "customize": [],
    "errorHandling":[],
    "distribute": [],
    "optimize": [],
    "source": {},
    "stagingResourceGroup": "/subscriptions/<subscriptionID>/resourceGroups/<stagingResourceGroupName>",
    "validate": {},
    "vmProfile": {
      "vmSize": "<vmSize>",
      "osDiskSizeGB": <sizeInGB>,
      "vnetConfig": {
        "subnetId": "/subscriptions/<subscriptionID>/resourceGroups/<vnetRgName>/providers/Microsoft.Network/virtualNetworks/<vnetName>/subnets/<subnetName1>",
        "containerInstanceSubnetId": "/subscriptions/<subscriptionID>/resourceGroups/<vnetRgName>/providers/Microsoft.Network/virtualNetworks/<vnetName>/subnets/<subnetName2>",
        "proxyVmSize": "<vmSize>"
      },
      "userAssignedIdentities": [
              "/subscriptions/<subscriptionID>/resourceGroups/<identityRgName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identityName1>",
        "/subscriptions/<subscriptionID>/resourceGroups/<identityRgName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identityName2>",
        "/subscriptions/<subscriptionID>/resourceGroups/<identityRgName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identityName3>",
        ...
      ]
    }
  }
}

创建映像模板时,请遵循所有 最佳做法

API 版本

随着 API 发生更改,API 版本会随时间相应变化。 有关 Azure VM 映像生成器服务的主要 API 更改和功能更新,请参阅 Azure VM 映像生成器中的新增功能。

类型

type 是资源类型,其值必须是 Microsoft.VirtualMachineImages/imageTemplates

"type": "Microsoft.VirtualMachineImages/imageTemplates",

位置

Azure VM 映像生成器服务在以下区域可用:

注意

你仍然可以在这些区域外部分发映像。

  • 中国北部 3(公共预览版)

重要

注册功能 Microsoft.VirtualMachineImages/MooncakePublicPreview,以access中国北部 3 区域中的Azure映像生成器公共预览版。

若要access中国北部 3 区域中的 Azure VM 映像生成器公共预览版,必须注册 Microsoft.VirtualMachineImages/MooncakePublicPreview 功能。 To do,请在 PowerShell 或 Azure CLI中运行以下命令:

Register-AzProviderPreviewFeature -ProviderNamespace Microsoft.VirtualMachineImages -Name MooncakePublicPreview
"location": "<region>"

数据驻留

Azure VM 映像生成器服务在具有严格数据驻留规则的区域内保留客户数据。 如果服务中断影响到有数据驻留要求的区域,则需要在不同的区域或地理位置创建 Bicep 文件或模板。

区域冗余

分发支持区域冗余,虚拟硬盘(VHD)默认分发到区域冗余Storage(ZRS)帐户,Azure计算库(以前称为Shared Image Gallery)版本支持ZRS storage类型(如果指定)。

标记

标记是可为生成的映像指定的键/值对。

标识

可通过两种方式添加用户分配的标识,如下所述。

Azure映像生成器映像模板资源的用户分配标识

必需 - 对于映像生成器具有读取/写入映像的权限,以及从Azure Storage读取脚本,必须创建一个Azure用户分配的标识,该标识有权访问各个资源。 有关映像生成器权限的工作原理和相关步骤的详细信息,请参阅 创建映像并使用用户分配的托管标识access Azure storage帐户中的文件

"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "<imgBuilderId>": {}
    }
}

映像生成器服务用户分配的标识:

  • 仅支持单个标识。
  • 不支持custom domain名称。

若要了解详细信息,请参阅 Azure 资源的托管标识是什么?。 有关部署此功能的详细信息,请参阅使用 Azure CLI 为Azure VM 上的Azure资源配置托管标识。

映像生成器生成 VM 的用户分配的标识

此属性仅在 API 2021-10-01 或更高版本中可用。

可选 - 订阅中的映像生成器服务创建的映像生成器生成 VM 用来生成和自定义映像。 若要使映像生成器生成 VM 有权向订阅中的其他服务(例如Azure Key Vault)进行身份验证,必须创建一 Azure个或多个对单个资源具有权限的用户分配标识。 然后,Azure映像生成器可以将这些用户分配的标识与生成 VM 相关联。 然后,生成 VM 中运行的自定义工具脚本可以提取这些标识的令牌,并根据需要与其他Azure资源交互。 请注意,Azure映像生成器的用户分配标识必须对所有用户分配的标识分配“托管标识”角色分配,Azure映像生成器才能将它们关联到生成 VM。

注意

请注意,可以为映像生成器生成 VM 指定多个标识,包括为 image 模板资源创建的标识。 默认情况下,为映像模板资源创建的标识不会自动添加到生成 VM。

"properties": {
  "vmProfile": {
    "userAssignedIdentities": [
      "/subscriptions/<subscriptionID>/resourceGroups/<identityRgName>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identityName>"
    ]
  }
}

映像生成器生成 VM 用户分配的标识:

  • 支持在 VM 上配置一个或多个用户分配的托管标识的列表。
  • 支持跨订阅方案(在一个订阅中创建标识,同时在同一租户下的另一个订阅中创建映像模板)。
  • 不支持跨租户方案(在一个租户中创建标识,同时在另一个租户中创建映像模板)。

若要了解更多信息,请参阅以下文章:

属性:buildTimeoutInMinutes

生成映像模板时等待的最长持续时间(包括所有自定义、验证和分发)。

如果你不指定该属性或将值设置为 0,则会使用默认值,即 240 分钟(4 小时)。 最小值为 6 分钟,最大值为 960 分钟(16 小时)。 达到超时值时(无论映像生成是否完成),你都会看到如下所示的错误:

[ERROR] Failed while waiting for packerizer: Timeout waiting for microservice to
[ERROR] complete: 'context deadline exceeded'

对于 Windows,我们不建议将 buildTimeoutInMinutes 设置为 60 分钟以下。 如果达到超时值,请查看日志,以确定自定义步骤是否正在等待提供信息(例如用户输入)。 如果需要更多时间才能完成自定义,请增大 buildTimeoutInMinutes 值。 但是,不要将它设置得太高,否则可能需要等到它超时才会看到错误。

属性:customize

映像生成器支持多个“定制器”,它们是用于自定义映像(例如运行脚本或重新启动服务器)的函数。

使用 customize 时:

  • 可以使用多个定制器。
  • 定制器按模板中指定的顺序执行。
  • 如果一个定制器失败,则整个自定义组件将会失败并报告错误。
  • 在模板中使用脚本之前对其进行全面测试。 自行调试脚本更方便。
  • 不要将敏感数据放在脚本中。 可以在映像模板定义中查看内联命令。 如果你有敏感信息(包括密码、SAS 令牌、身份验证令牌等),则应将其移动到Azure Storage中的脚本中,access需要身份验证。
  • 脚本位置需要可公开访问,除非您使用的是 User Assigned Identity

customize 节是一个数组。 支持的定制器类型包括:File、PowerShell、Shell、WindowsRestart 和 WindowsUpdate。

"customize": [
  {
    "type": "File",
    "destination": "string",
    "sha256Checksum": "string",
    "sourceUri": "string"
  },
  {
    "type": "PowerShell",
    "inline": [ "string" ],
    "runAsSystem": "bool",
    "runElevated": "bool",
    "scriptUri": "string",
    "sha256Checksum": "string",
    "validExitCodes": [ "int" ]
  },
  {
    "type": "Shell",
    "inline": [ "string" ],
    "scriptUri": "string",
    "sha256Checksum": "string"
  },
  {
    "type": "WindowsRestart",
    "restartCheckCommand": "string",
    "restartCommand": "string",
    "restartTimeout": "string"
  },
  {
    "type": "WindowsUpdate",
    "filters": [ "string" ],
    "searchCriteria": "string",
    "updateLimit": "int"
  }
]

Shell 定制器

Shell 定制器支持在 Linux 上运行 shell 脚本。 shell 脚本必须可公开访问,或者必须已配置映像生成器accessMSI

"customize": [
  {
    "type": "Shell",
    "name": "<name>",
    "scriptUri": "<link to script>",
    "sha256Checksum": "<sha256 checksum>"
  }
],
"customize": [
  {
    "type": "Shell",
    "name": "<name>",
    "inline": "<commands to run>"
  }
]

Customize 属性:

  • type - Shell。

  • name - 用于跟踪自定义项的名称。

  • scriptUri - 文件位置的 URI。

  • inline - shell 命令的数组,以逗号分隔。

  • sha256Checksum - 文件的 sha256 校验和的值,你将在本地生成此值,然后,映像生成器将进行校验和计算与验证。

    若要生成 sha256Checksum,请使用 Mac/Linux 上的终端运行:sha256sum <fileName>

注意

内联命令作为映像模板定义的一部分存储,你可以在转储映像定义时看到这些内联命令。 如果你有敏感命令或值(包括密码、SAS 令牌、身份验证令牌等),建议将这些命令移动到脚本中,并使用用户标识进行身份验证以Azure Storage。

超级用户权限

为命令添加 sudo 前缀,以使用超级用户特权运行这些命令。 可将命令添加到脚本中,或者在内联命令中使用它们,例如:

"type": "Shell",
"name": "setupBuildPath",
"inline": [
    "sudo mkdir /buildArtifacts",
    "sudo cp /tmp/index.html /buildArtifacts/index.html"
]

使用 sudo 的脚本示例,你可以使用 scriptUri 进行引用:

#!/bin/bash -e

echo "Telemetry: creating files"
mkdir /myfiles

echo "Telemetry: running sudo 'as-is' in a script"
sudo touch /myfiles/somethingElevated.txt

Windows restart 定制器

使用 WindowsRestart 定制器可以重启 Windows VM 并等待 VM 重新联机,并可以安装需要重新启动的软件。

"customize": [
  {
    "type": "WindowsRestart",
    "restartCommand": "shutdown /r /f /t 0",
    "restartCheckCommand": "echo Azure-Image-Builder-Restarted-the-VM  > c:\\buildArtifacts\\azureImageBuilderRestart.txt",
    "restartTimeout": "5m"
  }
]

Customize 属性:

  • Type:WindowsRestart。
  • restartCommand - 用于执行重启的命令(可选)。 默认为 'shutdown /r /f /t 0 /c \"packer restart\"'
  • restartCheckCommand - 用于检查重启是否成功的命令(可选)。
  • restartTimeout - 以量值和单位的字符串形式指定的重启超时。 例如,5m(5 分钟)或 2h(2 小时)。 默认值为:5m

注意

没有 Linux 重启定制器。

PowerShell 定制器

PowerShell定制器支持在 Windows 上运行 PowerShell 脚本和内联命令,服务必须公开访问这些脚本才能access这些脚本。

"customize": [
  {
    "type": "PowerShell",
    "name":   "<name>",
    "scriptUri": "<path to script>",
    "runElevated": <true false>,
    "runAsSystem": <true false>,
    "sha256Checksum": "<sha256 checksum>"
  },
  {
    "type": "PowerShell",
    "name": "<name>",
    "inline": "<PowerShell syntax to run>",
    "validExitCodes": [<exit code>],
    "runElevated": <true or false>,
    "runAsSystem": <true or false>
  }
]

Customize 属性:

  • type - PowerShell。

  • scriptUri - PowerShell 脚本文件位置的 URI。

  • inline - 要运行的内联命令(以逗号分隔)。

  • validExitCodes - 可选,可以从脚本/内联命令返回的有效代码。 该属性可避免脚本/内联命令报告的失败。

  • runElevated - 可选布尔值,支持使用提升的权限运行命令和脚本。

  • runAsSystem - 可选,布尔型,决定是否应以系统用户身份运行 PowerShell 脚本。

  • sha256Checksum - 在本地生成文件的 SHA256 校验和,将校验和值更新为小写,映像生成器会在部署镜像模板时验证校验和。

    若要生成 sha256Checksum,请在 PowerShell 中使用 Get-FileHash cmdlet。

File 定制器

File 定制器允许映像生成器从GitHub存储库或Azure storage下载文件。 该定制器支持 Linux 和 Windows。 如果你有依赖于生成artifacts的映像生成管道,则可以将文件定制器设置为从生成共享下载,并将artifacts移动到映像中。

"customize": [
  {
    "type": "File",
    "name": "<name>",
    "sourceUri": "<source location>",
    "destination": "<destination>",
    "sha256Checksum": "<sha256 checksum>"
  }
]

File 定制器属性:

  • sourceUri - 可访问的storage终结点,此终结点可以GitHub或Azure storage。 只能下载一个文件,而不能下载整个目录。 如果需要下载目录,请使用压缩文件,然后使用 Shell 或 PowerShell 定制器将其解压缩。

    注意

    如果 sourceUri 是Azure Storage帐户,无论 blob 是否标记为公共,则需要授予托管用户标识权限来读取 blob 上的access。 请参阅此 example 设置storage权限。

  • destination - 完整的目标路径和文件名。 任何被引用的路径和子目录必须存在,请使用 Shell 或 PowerShell 定制器提前设置这些路径。 可以使用脚本定制器创建路径。

Windows 目录和 Linux 路径支持此定制器,但存在一些差别:

  • Linux - 映像生成器唯一能够写入到的路径是 /tmp。
  • Windows - 无路径限制,但路径必须存在。

如果尝试下载文件时或将文件放在指定的目录中时出错,则自定义步骤将会失败,customization.log 中会记录此错误。

注意

File 定制器仅适用于下载小于 20MB 的小文件。 要下载较大的文件,请使用脚本或内联命令,然后使用代码下载文件,例如,在 Linux 中使用 wgetcurl,在 Windows 中使用 Invoke-WebRequest。 对于Azure storage中的文件,请确保按照以下文档为生成 VM 分配具有查看该文件的权限的标识:映像生成器生成 VM 的分配标识。 Azure映像生成器必须公开访问未存储在Azure中的任何文件才能下载它。

  • sha256Checksum - 在本地生成文件的 SHA256 校验和,将校验和值更新为小写,映像生成器会在部署镜像模板时验证校验和。

    若要生成 sha256Checksum,请在 PowerShell 中使用 Get-FileHash cmdlet。

Windows update定制器

WindowsUpdate定制器基于 Pack open source project er 社区维护的 community Windows Update Provisioner构建。 Microsoft使用映像生成器服务测试和验证预配程序,并支持调查其问题,并努力解决问题,但Microsoft不支持open source project。 有关Windows Update预配程序的详细文档和帮助,请参阅project存储库。

"customize": [
  {
    "type": "WindowsUpdate",
    "searchCriteria": "IsInstalled=0",
    "filters": [
      "exclude:$_.Title -like '*Preview*'",
      "include:$true"
    ],
    "updateLimit": 20
  }
]

定制器属性:

  • type - WindowsUpdate。
  • searchCriteria -(可选)定义安装的更新类型(例如“建议”或“重要”),默认设置为 BrowseOnly=0 且 IsInstalled=0(建议)。
  • filters - 可选,用于指定一个筛选器来包含或排除更新。
  • updateLimit - 可选,定义可安装的更新数,默认值为 1000。

注意

如果有任何未完成的 Windows 重启或应用程序安装仍在运行,则Windows Update自定义工具可能会失败,通常可能会在 customization.log System.Runtime.InteropServices.COMException (0x80240016): Exception from HRESULT: 0x80240016中看到此错误。 我们强烈建议你考虑在 Windows 重启中添加和/或允许应用程序有足够的时间使用 sleep 或等待内联命令或脚本中的命令,然后再运行Windows Update。

通用化

默认情况下,Azure映像生成器还将在每个映像自定义阶段结束时运行 deprovision 代码,以通用化映像。 通用化是设置映像并使其可重复用于创建多个 VM 的过程。 对于 Windows VM,Azure映像生成器使用 Sysprep。 对于 Linux,Azure映像生成器运行 waagent -deprovision

用于通用化映像生成器的命令可能不适合每种情况,因此Azure映像生成器允许根据需要自定义此命令。

如果你要迁移现有的自定义项,而使用的是不同的 Sysprep/waagent 命令,则可以使用映像生成器泛型命令;如果 VM 创建失败,请使用你自己的 Sysprep 或 waagent 命令。

如果Azure映像生成器成功创建 Windows 自定义映像,并从中创建 VM,然后发现 VM 创建失败或未成功完成,则需要查看 Windows Server Sysprep 文档,或者向 Windows Server Sysprep 客户服务支持团队提出支持请求,他们可以对正确的 Sysprep 使用情况进行故障排除和建议。

默认的 Sysprep 命令

Write-Output '>>> Waiting for GA Service (RdAgent) to start ...'
while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }
Write-Output '>>> Waiting for GA Service (WindowsAzureTelemetryService) to start ...'
while ((Get-Service WindowsAzureTelemetryService) -and ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running')) { Start-Sleep -s 5 }
Write-Output '>>> Waiting for GA Service (WindowsAzureGuestAgent) to start ...'
while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }
if( Test-Path $Env:SystemRoot\system32\Sysprep\unattend.xml ) {
  Write-Output '>>> Removing Sysprep\unattend.xml ...'
  Remove-Item $Env:SystemRoot\system32\Sysprep\unattend.xml -Force
}
if (Test-Path $Env:SystemRoot\Panther\unattend.xml) {
  Write-Output '>>> Removing Panther\unattend.xml ...'
  Remove-Item $Env:SystemRoot\Panther\unattend.xml -Force
}
Write-Output '>>> Sysprepping VM ...'
& $Env:SystemRoot\System32\Sysprep\Sysprep.exe /oobe /generalize /quiet /quit
while($true) {
  $imageState = (Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\State).ImageState
  Write-Output $imageState
  if ($imageState -eq 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { break }
  Start-Sleep -s 5
}
Write-Output '>>> Sysprep complete ...'

默认的 Linux deprovision 命令

WAAGENT=/usr/sbin/waagent
waagent -version 1> /dev/null 2>&1
if [ $? -eq 0 ]; then
  WAAGENT=waagent
fi
$WAAGENT -force -deprovision+user && export HISTSIZE=0 && sync

重写命令

若要重写命令,请使用 PowerShell 或 Shell 脚本预配程序创建具有确切文件名的命令文件,并将其放到正确的目录中:

  • Windows:C:\DeprovisioningScript.ps1
  • Linux:/tmp/DeprovisioningScript.sh

映像生成器会读取这些命令,这些命令将写出到 AIB 日志 customization.log 中。 请参阅故障排除,了解如何收集日志。

属性:errorHandling

通过 errorHandling 属性可以配置在创建映像期间如何处理错误。

{
  "errorHandling": {
    "onCustomizerError": "abort",
    "onValidationError": "cleanup"
  }
}

通过 errorHandling 属性可以配置在创建映像期间如何处理错误。 它具有两个属性:

  • onCustomizerError - 指定在创建映像的定制器阶段发生错误时要执行的操作
  • onValidationError - 指定在验证映像模板期间发生错误时要执行的操作

errorHandling 属性还具有两个用于在创建映像期间处理错误的可能值:

  • cleanup - 确保清理 Packer 创建的临时资源,即使 Packer 或其中一个自定义/验证遇到错误。 这保持与现有行为的向后兼容性。
  • abort - 如果 Packer 遇到错误,则 Azure 映像生成器 (AIB) 服务会跳过临时资源的清理。 作为 AIB 模板的所有者,你负责从订阅中清理这些资源。 这些资源可能包含有用的信息,例如临时 VM 中留下的日志和文件,这有助于调查 Packer 遇到的错误。

属性:distribute

Azure映像生成器支持三个分发目标:

  • ManagedImage - 托管映像。
  • sharedImage - Azure计算库。
  • VHD - storage 帐户中的 VHD。

可将映像分发到同一配置中的两种目标类型。

注意

默认的 AIB sysprep 命令不包括“/mode:vm”,但是,在创建将安装 HyperV 角色的映像时,可能需要此属性。 如果你需要添加此命令参数,则必须覆盖 sysprep 命令。

由于可以分发到多个目标,映像生成器会维护每个分发目标的状态,可通过查询 runOutputName 来访问该状态。 分发后,可以在 runOutputName 对象中查询有关该分发的信息。 例如,可以查询 VHD 的位置、映像版本复制到的区域,或者创建的 SIG 映像版本。 这是每个分发目标的属性。 对于每个分发目标,runOutputName 必须独一无二。 下面是查询Azure计算库分布的示例:

subscriptionID=<subcriptionID>
imageResourceGroup=<resourceGroup of image template>
runOutputName=<runOutputName>

az resource show \
  --ids "/subscriptions/$subscriptionID/resourcegroups/$imageResourceGroup/providers/Microsoft.VirtualMachineImages/imageTemplates/ImageTemplateLinuxRHEL77/runOutputs/$runOutputName" \
--api-version=2023-07-01

输出:

{
  "id": "/subscriptions/xxxxxx/resourcegroups/rheltest/providers/Microsoft.VirtualMachineImages/imageTemplates/ImageTemplateLinuxRHEL77/runOutputs/rhel77",
  "identity": null,
  "kind": null,
  "location": null,
  "managedBy": null,
  "name": "rhel77",
  "plan": null,
  "properties": {
    "artifactId": "/subscriptions/xxxxxx/resourceGroups/aibDevOpsImg/providers/Microsoft.Compute/galleries/devOpsSIG/images/rhel/versions/0.24105.52755",
    "provisioningState": "Succeeded"
  },
  "resourceGroup": "rheltest",
  "sku": null,
  "tags": null,
  "type": "Microsoft.VirtualMachineImages/imageTemplates/runOutputs"
}

Distribute:managedImage

映像输出是托管映像资源。

{
  "type":"ManagedImage",
  "imageId": "<resource ID>",
  "location": "<region>",
  "runOutputName": "<name>",
  "artifactTags": {
      "<name>": "<value>",
      "<name>": "<value>"
  }
}

Distribute 属性:

  • type - ManagedImage
  • imageId - 目标映像的资源 ID,预期格式:/subscriptions/subscriptionId</resourceGroups/>destinationResourceGroupName</providers/Microsoft.Compute/images/>imageName<
  • location - 托管映像的位置。
  • runOutputName - 用于标识分发的唯一名称。
  • artifactTags -(可选)用户指定的键值对标记。

注意

目标资源组必须存在。 将映像分发到不同的区域会增加部署时间。

Distribute:sharedImage

Azure计算库是一个新的映像管理服务,用于管理映像区域复制、版本控制以及共享自定义映像。 Azure映像生成器支持使用此服务进行分发,因此可以将映像分发到Azure计算库支持的区域。

Azure计算库由:

  • 库 - 多个映像的容器。 库部署在一个区域。
  • 映像定义 - 映像的概念分组。
  • 映像版本 - 用于部署 VM 或规模集的映像类型。 可将映像版本复制到需要部署 VM 的其他区域。

必须先创建库和映像定义,然后才能分发到库,详见创建库

注意

映像版本 ID 需要不同于现有Azure计算库中的任何映像版本。

{
  "type": "SharedImage",
  "galleryImageId": "<resource ID>",
  "runOutputName": "<name>",
  "artifactTags": {
      "<name>": "<value>",
      "<name>": "<value>"
  }
}

以下 JSON 是如何使用 replicationRegions 字段分发到Azure计算库的示例。

  "replicationRegions": [
      "<region where the gallery is deployed>",
      "<region>"
  ]

注意

库分发已弃用 replicationRegions,因为 targetRegions 是更新后的属性。 有关详细信息,请参阅 targetRegions

分发:targetRegions

以下 JSON 是如何使用 targetRegions 字段分发到Azure计算库的示例。

"distribute": [
      {
        "type": "SharedImage",
        "galleryImageId": "<resource ID>",
        "runOutputName": "<name>",
        "artifactTags": {
          "<name>": "<value>",
          "<name>": "<value>"
        },
        "targetRegions": [
             {
              "name": "chinanorth",
              "replicaCount": 2,
              "storageAccountType": "Standard_ZRS"
             },
             {
              "name": "chinanorth2",
              "replicaCount": 3,
              "storageAccountType": "Premium_LRS"
             }
          ]
       },
    ]

分发库的属性:

  • 类型 - sharedImage

  • galleryImageId - Azure计算库的 ID,可以使用两种格式指定此属性:

    • 自动版本控制 - 映像生成器会为你生成单调的版本号,当你想要继续通过同一模板重建映像时,此属性很有用,格式为:/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/galleries/<sharedImageGalleryName>/images/<imageGalleryName>
    • 显式版本 - 你可以传递希望映像生成器使用的版本号。 格式是:/subscriptions/<subscriptionID>/resourceGroups/<rgName>/providers/Microsoft.Compute/galleries/<sharedImageGalName>/images/<imageDefName>/versions/<version - for example: 1.1.1>
  • runOutputName - 用于标识分发的唯一名称。

  • artifactTags -(可选)用户指定的键值对标记。

  • replicationRegions - 用于复制的区域数组。 必须有一个区域是部署库的区域。 添加区域意味着增加生成时间,因为在复制完成之前,生成不会完成。 从 API 版本 2022-07-01 开始,此字段已弃用,在分发“SharedImage”类型时请使用 targetRegions

  • targetRegions - 用于复制的区域数组。 它是作为 2022-07-01 API 的一部分新推出的,仅适用于 SharedImage 类型分发。

  • excludeFromLatest(可选)- 用于标记创建的映像版本,而不是用作库定义中的最新版本,默认值为“false”。

  • storageAccountType(可选) - AIB 支持为要创建的映像版本指定这些类型的storage:

    • “Standard_LRS”
    • “Standard_ZRS”,”

注意

如果映像模板和引用的 image definition 不在同一位置,你将看到创建映像的额外时间。 映像生成器目前没有映像版本资源的 location 参数,我们从其父 image definition 中获取它。 例如,如果映像定义在 chinanorth 中,并且你要将映像版本复制到 chinanorth,将 Blob 复制到 chinanorth,在 chinanorth 中创建映像版本资源,然后复制到 chinanorth。 为了避免额外的复制时间,请确保 image definition 和映像模板位于同一位置。

版本控制

versioning 属性仅适用于 分发类型。 它是一个具有两个可能值的枚举:

  • latest - 使用符合设计的新的严格递增架构
  • source - 使用基于源映像版本号的架构。

默认版本号架构为 latest。 最新架构有一个附加属性“major”,该属性指定要在其中生成最新版本的主版本。

注意

sharedImage 分发的现有版本生成逻辑已被弃用。 提供了两个新选项:单调递增版本(始终是库中的最新版本)、基于源映像的版本号生成的版本。 指定版本生成架构的枚举允许将来使用其他版本生成架构进行扩展。

    "distribute": [
        "versioning": {
            "scheme": "Latest",
            "major": 1
        }
    ]

版本控制属性:

  • scheme - 为分发生成新版本号。 LatestSource 是两个可能的值。
  • major - 指定要在哪个主版本下生成最新版本。 仅当 scheme 设置为 Latest 时适用。 例如,在发布了以下版本的库中:0.1.1、0.1.2、1.0.0、1.0.1、1.1.0、1.1.1、1.2.0、2.0.0、2.0.1、2.1.0
    • 如果 major 未设置或 major 设置为 2,则 Latest 方案会生成版本 2.1.1
    • 将 major 设置为 1 时,Latest 方案会生成版本 1.2.1
    • 将 major 设置为 0 时,Latest 方案会生成版本 0.1.3

Distribute:VHD

可以输出到 VHD。 然后,可以复制 VHD,并将其用于发布到Azure MarketPlace,或与Azure Stack一起使用。

{
  "type": "VHD",
  "runOutputName": "<VHD name>",
  "artifactTags": {
      "<name>": "<value>",
      "<name>": "<value>"
  }
}

OS 支持:Windows 和 Linux

Distribute VHD 参数:

  • type - VHD。
  • runOutputName - 用于标识分发的唯一名称。
  • tags -(可选)用户指定的键值对标记。

Azure映像生成器不允许用户指定storage帐户位置,但你可以查询 runOutputs的状态以获取位置。

az resource show \
  --ids "/subscriptions/$subscriptionId/resourcegroups/<imageResourceGroup>/providers/Microsoft.VirtualMachineImages/imageTemplates/<imageTemplateName>/runOutputs/<runOutputName>"  | grep artifactUri

注意

创建 VHD 后,请尽快将它复制到其他位置。 VHD 存储在将映像模板提交到Azure映像生成器服务时创建的临时资源组中的storage帐户中。 如果删除该映像模板,将会丢失 VHD。

以下 JSON 将映像作为 VHD 分发到自定义storage帐户。

"distribute": [
  {
    "type": "VHD",
    "runOutputName": "<VHD name>",
    "artifactTags": {
        "<name>": "<value>",
        "<name>": "<value>"
    },
    "uri": "<replace with Azure storage URI>"
  }
]

VHD 分发属性:

uri - 分布式 VHD blob 的可选Azure Storage URI。 省略使用默认的(空字符串),在这种情况下,VHD 将发布到暂存资源组中的storage帐户。

属性:optimize

可以在创建 VM 映像时启用 optimize 属性,通过该属性,VM 优化可以缩短映像创建时间。

"optimize": {
      "vmBoot": {
        "state": "Enabled"
      }
    }
  • vmBoot:与虚拟机 (VM) 的启动过程相关的配置,用于控制可改进启动时间或其他性能方面的优化。
  • 状态:vmBoot 中启动优化功能的状态,值 Enabled 指示该功能已打开以缩短映像创建时间。

若要了解详细信息,请参阅VM 优化,了解具有 Azure VM 映像生成器的库映像

属性:source

source 节包含有关映像生成器要使用的源映像的信息。 Azure映像生成器仅支持通用化映像作为源映像,目前不支持专用映像。

API 需要通过一个 SourceType 来定义用于生成映像的源,目前有三种类型:

  • PlatformImage - 表示源映像是市场映像。
  • ManagedImage - 从常规托管映像开始生成时使用。
  • SharedImageVersion - 在Azure计算库中使用映像版本作为源时使用。

注意

使用现有的 Windows 自定义映像时,可在单个 Windows 7 或 Windows Server 2008 R2 映像上运行 Sysprep 命令(最多运行三次,或在更高版本的单个 Windows 映像上运行 1001 次);有关详细信息,请参阅 sysprep 文档。

PlatformImage 源

Azure映像生成器支持 Windows Server 和客户端以及 Linux Azure Marketplace 映像,有关完整列表,请参阅 Learn about Azure Image Builder

"source": {
  "type": "PlatformImage",
  "publisher": "Canonical",
  "offer": "UbuntuServer",
  "sku": "18.04-LTS",
  "version": "latest"
}

此处的属性与用于创建 VM 的属性相同。请使用 AZ CLI 运行以下命令来获取属性:

az vm image list -l chinanorth -f UbuntuServer -p Canonical --output table --all

可以在版本中使用 latest,将在生成映像(而不是提交模板)时评估版本。 如果将此功能用于Azure计算库目标,则可以避免重新提交模板,并按间隔重新运行映像生成,以便从最新的映像重新创建映像。

支持市场计划信息

你还可以指定计划信息,例如:

"source": {
  "type": "PlatformImage",
  "publisher": "RedHat",
  "offer": "rhel-byos",
  "sku": "rhel-lvm75",
  "version": "latest",
  "planInfo": {
    "planName": "rhel-lvm75",
    "planProduct": "rhel-byos",
    "planPublisher": "redhat"
  }
}

ManagedImage 源

将源映像设置为通用化 VHD 或 VM 的现有托管映像。

注意

源托管映像必须是受支持的 OS,并且映像必须与Azure映像生成器模板位于同一订阅和区域中。

"source": {
  "type": "ManagedImage",
  "imageId": "/subscriptions/<subscriptionId>/resourceGroups/{destinationResourceGroupName}/providers/Microsoft.Compute/images/<imageName>"
}

imageId 应是托管映像的 ResourceId。 使用 az image list 可以列出可用映像。

SharedImageVersion 源

将源映像设置为Azure计算库中的现有映像版本。

注意

源共享映像版本必须是受支持的 OS,并且映像版本必须与Azure映像生成器模板位于同一区域中,否则,请将映像版本复制到映像生成器模板区域。

"source": {
  "type": "SharedImageVersion",
  "imageVersionId": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroup>/providers/Microsoft.Compute/galleries/<sharedImageGalleryName>/images/<imageDefinitionName/versions/<imageVersion>"
}
  • imageVersionId - 映像版本的 ARM 模板资源 ID。 当映像版本名称为“latest”时,在生成映像时会评估版本。 imageVersionId 应是映像版本的 ResourceId。 使用 az sig 映像版本列表列出映像版本。

以下 JSON 将源映像设置为存储在Azure计算库中的映像的最新映像版本。

"properties": {
    "source": {
        "type": "SharedImageVersion",
        "imageVersionId": "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.Compute/galleries/<azureComputeGalleryName>/images/<imageDefinitionName>/versions/latest"
    }
},

SharedImageVersion 属性:

imageVersionId - 映像版本的 ARM 模板资源 ID。 当映像版本名称为“latest”时,在生成映像时会评估版本。

属性:stagingResourceGroup

stagingResourceGroup 包含映像生成器服务为在映像生成过程中使用而创建的暂存资源组的信息。 对于希望在映像生成过程中对映像生成器创建的资源组进行更多控制的人,stagingResourceGroup 是一个可选属性。 可以创建自己的资源组并在 stagingResourceGroup 部分指定它,或者让映像生成器代表你创建一个资源组。

重要

指定的暂存资源组不能与另一个映像模板关联,必须在映像模板所在的同一区域中为空(无资源),并且将“参与者”或“所有者”RBAC 应用于分配给Azure映像生成器映像模板资源的标识。 映像生成器使用键 imageTemplateResourceGroupNameimageTemplateName 检查暂存资源组上的标记,以确定是否有任何映像模板使用该暂存资源组。 如果这些标记在映像模板提交之前存在,或者在映像生成期间与正在运行的映像模板不匹配,则操作将失败。

"properties": {
  "stagingResourceGroup": "/subscriptions/<subscriptionID>/resourceGroups/<stagingResourceGroupName>"
}

模板创建方案

  • stagingResourceGroup 属性保留为空

    如果未指定 stagingResourceGroup 属性或者为其指定了空字符串,则映像生成器服务会使用约定的默认名称“IT_***”创建一个暂存资源组。 该暂存资源组将具有应用于它的以下默认标记:createdByimageTemplateNameimageTemplateResourceGroupName。 此外,默认 RBAC 将应用于分配给Azure映像生成器模板资源的标识,即“参与者”。

  • 使用存在的资源组指定 stagingResourceGroup 属性

    如果将 stagingResourceGroup 属性指定为存在资源组,则映像生成器服务会检查以确保资源组未与另一个映像模板关联,与映像模板位于同一区域中为空(无资源),并且已将“参与者”或“所有者”RBAC 应用于分配给Azure映像生成器映像模板资源的标识。 如果不满足上述任一要求,都将引发错误。 该暂存资源组将具有添加到它的以下标记:usedByimageTemplateNameimageTemplateResourceGroupName。 不会删除预先存在的标记。

重要

尝试使用 Windows 源映像将预先存在的资源组和 VNet 指定到Azure映像生成器服务时,需要将参与者角色分配给与Azure映像生成器的第一方应用对应的服务主体的资源组。 有关如何将参与者角色分配到资源组的 CLI 命令和门户说明,请参阅以下文档Troubleshoot VM Azure映像生成器:创建磁盘时授权错误

  • 使用不存在的资源组指定 stagingResourceGroup 属性

    如果为 stagingResourceGroup 属性指定了不存在的资源组,则映像生成器服务会使用 stagingResourceGroup 属性中提供的名称创建一个暂存资源组。 如果给定名称不符合资源组的Azure命名要求,则会出现错误。 该暂存资源组将具有应用于它的以下默认标记:createdByimageTemplateNameimageTemplateResourceGroupName。 默认情况下,分配给Azure映像生成器映像模板资源的标识在资源组中应用了“参与者”RBAC。

模板删除

映像生成器服务创建的任何暂存资源组将在删除映像模板后删除。 删除的内容包括已在 stagingResourceGroup 属性中指定的、但在映像生成之前不存在的暂存资源组。

如果映像生成器未创建暂存资源组,但在资源组中创建了资源,则只要映像生成器服务具有删除资源所需的适当权限或角色,在删除映像模板后就会删除这些资源。

属性:验证

可以使用 validate 属性验证平台映像和创建的任何自定义映像,而不考虑是否使用Azure映像生成器创建它们。

Azure映像生成器支持可以使用 sourceValidationOnly 属性设置的“仅限源验证”模式。 如果 sourceValidationOnly 属性设置为 true,则直接验证 source 节中指定的映像。 不会运行单独的构建来生成,然后验证自定义映像。

inVMValidations 属性获取将在映像上执行的验证程序的列表。 Azure映像生成器支持文件、PowerShell 和 Shell 验证程序。

continueDistributeOnFailure 属性负责确定在验证失败时是否分发输出映像。 默认情况下,如果验证失败,并且此属性设置为 false,则不分发输出映像 。 如果验证失败,并且此属性设置为 true,则仍会分发输出映像。 请谨慎使用此选项,因为它可能会导致分发失败的映像以供使用。 无论哪种情况(true 或 false),在验证失败时,端到端映像运行都将报告为失败。 此属性对验证是否成功没有任何影响。

使用 validate 时:

  • 可以使用多个验证程序。
  • 验证程序按模板中指定的顺序执行。
  • 如果一个验证程序失败,则整个验证组件将会失败并报告错误。
  • 建议在模板中使用脚本之前对其进行全面的测试。 在自己的 VM 上调试脚本会更方便。
  • 不要将敏感数据放在脚本中。
  • 脚本位置需可公开访问,除非使用的是 MSI

如何使用 validate 属性验证 Windows 映像:

{
   "properties":{
      "validate":{
         "continueDistributeOnFailure":false,
         "sourceValidationOnly":false,
         "inVMValidations":[
            {
               "type":"File",
               "destination":"string",
               "sha256Checksum":"string",
               "sourceUri":"string"
            },
            {
               "type":"PowerShell",
               "name":"test PowerShell validator inline",
               "inline":[
                  "<command to run inline>"
               ],
               "validExitCodes":"<exit code>",
               "runElevated":"<true or false>",
               "runAsSystem":"<true or false>"
            },
            {
               "type":"PowerShell",
               "name":"<name>",
               "scriptUri":"<path to script>",
               "runElevated":"<true false>",
               "sha256Checksum":"<sha256 checksum>"
            }
         ]
      }
   }
}

inVMValidations 属性:

  • type - PowerShell。

  • name - 验证程序的名称

  • scriptUri - PowerShell 脚本文件的 URI。

  • inline –要运行的命令数组(以逗号分隔)。

  • validExitCodes - 可从脚本/内联命令返回的可选有效代码,这可用来避免脚本/内联命令报告失败。

  • runElevated - 可选布尔值,支持使用提升的权限运行命令和脚本。

  • sha256Checksum - 文件的 sha256 校验和的值。你将在本地生成此校验和,然后,映像生成器会对其进行验证。

    若要生成 sha256Checksum,请使用 Windows 上的 PowerShell Get-Hash

如何使用 validate 属性验证 Linux 映像:

{
  "properties": {
    "validate": {
      "continueDistributeOnFailure": false,
      "sourceValidationOnly": false,
      "inVMValidations": [
        {
          "type": "Shell",
          "name": "<name>",
          "inline": [
            "<command to run inline>"
          ]
        },
        {
          "type": "Shell",
          "name": "<name>",
          "scriptUri": "<path to script>",
          "sha256Checksum": "<sha256 checksum>"
        },
        {
          "type": "File",
          "destination": "string",
          "sha256Checksum": "string",
          "sourceUri": "string"
        }
      ]
    }
  }
}

inVMValidations 属性:

  • type - Shell 或 File,指定为要执行的验证类型。

  • name - 验证程序的名称

  • scriptUri - 脚本文件的 URI

  • inline –要运行的命令数组(以逗号分隔)。

  • sha256Checksum - 文件的 sha256 校验和的值。你将在本地生成此校验和,然后,映像生成器会对其进行验证。

    若要生成 sha256Checksum,请使用 Mac/Linux 上的终端运行:sha256sum <fileName>

  • destination - 文件的目的地。

  • sha256Checksum - 指定文件的 SHA256 校验和。

  • sourceUri - 文件的源 URI。

属性:vmProfile

vmSize(可选)

映像生成器对 Gen1 映像使用默认 SKU 大小 Standard_D1_v2,对 Gen2 映像使用 Standard_D2ds_v4。 代系由 source 中指定的映像定义。 可以出于以下原因替代 vmSize:

  • 执行自定义时需要增加内存、CPU 以及处理大型文件 (GB)。
  • 运行 Windows 版本时,应使用“Standard_D2_v2”或等效的 VM 大小。
  • 需要 VM 隔离
  • 自定义需要特定硬件的映像。 例如,对于 GPU VM,需要一种 GPU VM 大小。
  • 需要生成 VM 的其余部分进行端到端加密,需要指定不使用本地临时磁盘的支持生成VM 大小

osDiskSizeGB

映像生成器默认不会更改映像的大小,它会使用源映像中的大小。 可以选择性地仅增大 OS 磁盘(Win 和 Linux)的大小,0 值表示保留与源映像相同的大小。 无法将 OS 磁盘大小缩小到小于源映像的大小。

{
  "osDiskSizeGB": 100
}

vnetConfig(可选)

如果你未指定任何 VNet 属性,则映像生成器会创建自己的 VNet、公共 IP 和网络安全组 (NSG)。 服务使用公共 IP 来与生成 VM 通信。 如果不想拥有公共 IP,或者希望映像生成器access现有 VNet 资源,例如配置服务器(DSC、Chef、Puppet、Ansible),则可以指定 VNet。 有关详细信息,请查看网络文档

"vnetConfig": {
  "subnetId": "/subscriptions/<subscriptionID>/resourceGroups/<vnetRgName>/providers/Microsoft.Network/virtualNetworks/<vnetName>/subnets/<subnetName1>",
  "containerInstanceSubnetId": "/subscriptions/<subscriptionID>/resourceGroups/<vnetRgName>/providers/Microsoft.Network/virtualNetworks/<vnetName>/subnets/<subnetName2>",
  "proxyVmSize": "<vmSize>"
}

子网 ID

在其中部署生成 VM 和验证 VM 的预先存在子网的资源 ID。 如果生成或验证 VM 中运行的任何自定义或验证脚本都需要出站access,则此子网还应允许此类access。

containerInstanceSubnetId(可选)

Isolated Builds 部署Azure容器实例(ACI)的预先存在的子网的资源 ID。 如果未指定此字段,则除了其他网络资源(专用终结点、Private Link服务、Azure Load Balancer和代理 VM)外,还会在临时资源组中部署临时Virtual Network以及子网和网络安全组,以启用 ACI 与生成 VM 之间的通信。

[此属性仅在 API 版本 2024-02-01 或较新版本中可用,但可以更新使用早期 API 版本创建的现有模板以指定此属性。]

仅当同时指定 subnetId 并且必须满足以下要求时,才能指定此字段:

  • 此子网必须与 subnetId 中指定的子网位于同一Virtual Network。
  • 此子网不得与 subnetId 中指定的子网相同。
  • 必须将此子网委托给 ACI 服务,以便其可用于部署 ACI 资源。 可以阅读有关 Azure 服务子网委派的详细信息here此处提供了特定于 ACI 的子网委派信息。
  • 此子网必须允许出站access到 Internet 和 subnetId 中指定的子网。 需要这些访问才能预配 ACI,以及与生成 VM 通信以执行自定义/验证。 另一端,subnetId中指定的子网必须允许来自此子网的入站access。 通常,Azure网络安全组(NSG)0 的默认安全规则允许这些访问。 但是,如果将更多安全规则添加到 NSG,则仍必须允许以下访问:
    1. containerInstanceSubnetId 中指定的子网出站access到:
      1. 端口 443 上的 Internet(用于预配容器映像)
      2. 在端口 445(从 Azure Storage 装载文件共享)上的 Internet。
      3. 端口 22(对于 ssh/Linux)和端口 5986(对于 WinRM/Windows)上 subnetId 中指定的子网(用于连接到生成 VM)
    2. subnetId中指定的子网的入站access:
      1. containerInstanceSubnetId 中指定的子网到端口 22(对于 ssh/Linux)和端口 5986(对于 WinRM/Windows)(供 ACI 连接到生成 VM)
  • template identity必须具有在此子网范围内执行“Microsoft.Network/virtualNetworks/subnets/join/action”作的权限。 可以阅读有关网络 here Azure 权限的详细信息。

proxyVmSize(可选)

用于将流量传递到生成 VM 和验证 VM 的代理虚拟机的大小。 如果指定了 containerInstanceSubnetId,则不能指定此字段,因为在这种情况下未部署代理虚拟机。 省略或指定空字符串以使用默认值 (Standard_A1_v2)。

属性:autoRun

可以使用 autoRun 属性控制在创建模板时是否自动启动映像模板生成过程。 它是一个具有两个可能值的枚举:

  • 已启用 - 启用自动运行,因此在创建模板时,映像模板生成过程自动启动
  • 已禁用 - 禁用自动运行,因此必须在创建模板后手动启动映像生成过程
"properties": {
    "autoRun": {
        "state": "Enabled"
    }
 }

注意

autoRun 设置为“已启用”时,映像生成过程在创建模板时运行一次。 这可确保系统无缝构建初始映像。 但是,此设置无法实现一致且持续的映像构建。

autoRun 不同,通过Azure映像生成器触发器资源自动创建映像可确保映像生成一致。 每当模板发生更改时,Azure映像生成器服务将自动触发映像生成过程。

选择 autoRun 可在模板创建时立即生成映像。 对于映像构建,如需确保持续一致性,请选择自动创建映像。 考虑具体要求,并根据工作流使用适当的选项。

属性:managedResourceTags

可以使用 managedResourceTags 属性将标记应用于映像生成期间Azure映像生成器服务在过渡资源组中创建的资源。 有关暂存资源组的详细信息,请参阅 Azure 映像生成器概述

"properties": {
    "managedResourceTags": {
      "tag1": "value1",
            "tag2": "value2"
              }
}

映像模板操作

启动映像生成

若要启动生成,需要对映像模板资源调用“Run”,如 run 命令的示例:

Invoke-AzResourceAction -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2023-07-01" -Action Run -Force
az resource invoke-action \
  --resource-group $imageResourceGroup \
  --resource-type  Microsoft.VirtualMachineImages/imageTemplates \
  -n helloImageTemplateLinux01 \
  --action Run

取消映像生成

如果你正在运行你认为不正确的映像生成、等待用户输入,或者你觉得永远不会成功完成,则可以取消生成。

可随时取消生成。 如果分发阶段已经开始,你仍然可以取消,但需要清理可能尚未完成的任何映像。 取消命令不会等待取消完成,请使用这些状态lastrunstatus.runstate监视取消进度的

cancel 命令的示例:

Invoke-AzResourceAction -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2023-07-01" -Action Cancel -Force
az resource invoke-action \
  --resource-group $imageResourceGroup \
  --resource-type  Microsoft.VirtualMachineImages/imageTemplates \
  -n helloImageTemplateLinux01 \
  --action Cancel

后续步骤

Azure映像生成器GitHub中存在不同方案的示例 .json 文件。