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

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

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

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

基本格式为:

{
  "type": "Microsoft.VirtualMachineImages/imageTemplates",
  "apiVersion": "2022-02-14",
  "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/<subnetName>",
        "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 版本

type 是资源类型,其值必须是 Microsoft.VirtualMachineImages/imageTemplatesapiVersion 会随着 API 的更改而不断更改。 有关 Azure VM 映像生成器服务的所有重大 API 更改和功能更新,请参阅 Azure VM 映像生成器中的新增功能

"type": "Microsoft.VirtualMachineImages/imageTemplates",
"apiVersion": "2022-02-14",

位置

位置是创建自定义映像的区域。 支持以下区域:

  • 美国东部
  • 美国东部 2
  • 美国中西部
  • 美国西部
  • 美国西部 2
  • 美国西部 3
  • 美国中南部
  • 北欧
  • 西欧
  • 东南亚
  • Australia Southeast
  • 澳大利亚东部
  • 英国南部
  • 英国西部
  • 巴西南部
  • 加拿大中部
  • 印度中部
  • 美国中部
  • 法国中部
  • 德国中西部
  • 日本东部
  • 美国中北部
  • 挪威东部
  • 瑞士北部
  • Jio 印度西部
  • 阿拉伯联合酋长国北部
  • 东亚
  • 韩国中部
  • 南非北部
  • 卡塔尔中部
  • USGov 亚利桑那州(公共预览版)
  • USGov 弗吉尼亚州(公共预览版)
  • 中国北部 3(公共预览版)
  • 瑞典中部
  • 波兰中部

重要

注册功能 Microsoft.VirtualMachineImages/FairfaxPublicPreview 以访问 Azure 政府区域(USGov 亚利桑那州和 USGov 弗吉尼亚州)中的 Azure 映像生成器公共预览版。

重要

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

若要访问 Azure 政府区域(USGov 亚利桑那州和 USGov 弗吉尼亚州)中的 Azure VM 映像生成器公共预览版,必须注册 Microsoft.VirtualMachineImages/FairfaxPublicPreview 功能。 为此,请在 PowerShell 或 Azure CLI 中运行以下命令:

Register-AzProviderPreviewFeature -ProviderNamespace Microsoft.VirtualMachineImages -Name FairfaxPublicPreview

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

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

数据驻留

当客户在具有严格单区域数据驻留要求的区域内请求生成时,Azure VM 映像生成器服务不会在该区域之外存储或处理客户数据。 如果服务中断影响到有数据驻留要求的区域,则需要在不同的区域或地理位置创建 Bicep 文件或模板。

区域冗余

分发支持区域冗余,VHD 默认分发到区域冗余存储 (ZRS) 帐户,而 Azure Compute Gallery(以前称为共享映像库)版本将支持 ZRS 存储类型(如果已指定)。

标记

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

标识

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

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

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

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

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

  • 仅支持单个标识。
  • 不支持自定义域名。

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

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

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

可选 - 订阅中的映像生成器服务创建的映像生成器生成 VM 用来生成和自定义映像。 要使映像生成器生成 VM 有权对其他服务(例如订阅中的 Azure 密钥保管库)进行身份验证,必须创建对各个资源拥有权限的一个或多个 Azure 用户分配的标识。 然后,Azure 映像生成器可将这些用户分配的标识与生成 VM 相关联。 然后,在生成 VM 中运行的定制器脚本可以获取这些标识的令牌,并根据需要与其他 Azure 资源交互。 请注意,Azure 映像生成器的用户分配标识必须在所有用户分配的标识上具有“托管标识操作员”角色分配,这样,Azure 映像生成器才能将这些标识与生成 VM 相关联。

注意

请注意,可为映像生成器生成 VM 指定多个标识,包括为映像模板资源创建的标识。 默认情况下,为映像模板资源创建的标识不会自动添加到生成 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 存储中的脚本,其中访问需要身份验证。
  • 脚本位置需可公开访问,除非使用的是 MSI

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 脚本必须可公开访问,或者必须配置 MSI 才能让映像生成器访问它们。

"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 存储。

超级用户权限

为命令添加 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 脚本和内联命令,这些脚本必须可公开访问,这样,IB 才能访问这些脚本。

"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 存储下载文件。 该定制器支持 Linux 和 Windows。 如果你的某个映像生成管道依赖于生成工件,则可将 File 定制器设置为从生成共享进行下载,并将工件移到映像中。

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

File 定制器属性:

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

    注意

    如果 sourceUri 是 Azure 存储帐户,无论 blob 是否被标记为公共,你都将需要授予托管用户标识权限以读取 blob 上的访问权限。 请参阅此示例以设置存储权限。

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

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

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

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

注意

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

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

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

Windows 更新定制器

WindowsUpdate 定制器是基于适用于 Packer 的社区 Windows 更新预配程序(由 Packer 社区维护的一个开源项目)生成的。 Microsoft 使用映像生成器服务来测试和验证该预配程序,支持使用该服务来调查问题,并会努力解决问题,但该开源项目不受 Microsoft 官方支持。 如需获取关于 Windows Update Provisioner 的详细文档和帮助,请参阅项目存储库。

"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 更新定制器可能会失败,通常你可能会在 customization.log System.Runtime.InteropServices.COMException (0x80240016): Exception from HRESULT: 0x80240016 中看到此错误。 强烈建议考虑添加 Windows 重启和/或允许应用程序有足够的时间来使用内联命令或脚本中的睡眠或等待命令完成安装,然后再运行 Windows 更新。

通用化

默认情况下,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 Compute Gallery。
  • VHD - 存储帐户中的 VHD。

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

注意

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

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

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=2021-10-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 Compute Gallery 是一个新的映像管理服务,可用于管理映像区域复制,以及对自定义映像进行版本控制和共享。 Azure 映像生成器支持使用此服务进行分发,因此你可以将映像分发到 Azure Compute Gallery 支持的区域。

Azure Compute Gallery 包含:

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

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

注意

映像版本 ID 需要不同于现有 Azure Compute Gallery 中的任何映像版本。

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

以下 JSON 示例展示了如何使用 replicationRegions 字段分发到 Azure Compute Gallery。

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

注意

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

分发:targetRegions

以下 JSON 示例展示了如何使用 targetRegions 字段分发到 Azure Compute Gallery。

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

分发库的属性:

  • type - sharedImage

  • galleryImageId - Azure Compute Gallery 的 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 支持为要创建的映像版本指定这些类型的存储:

    • “Standard_LRS”
    • "Standard_ZRS","

注意

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

版本控制

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

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

默认版本号架构为 latest。 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 市场,或者将它与 Azure Stack 配合使用。

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

OS 支持:Windows 和 Linux

Distribute VHD 参数:

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

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

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

注意

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

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

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

VHD 分发属性:

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

属性:optimize

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

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

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

属性:source

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

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

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

注意

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

PlatformImage 源

Azure 映像生成器支持 Windows Server 和客户端以及 Linux Azure 市场映像。有关完整列表,请参阅了解 Azure 映像生成器

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

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

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

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

支持市场计划信息

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

"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 Compute Gallery 中的现有映像版本。

注意

源共享映像版本必须是受支持的 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 image-version list 可以列出映像版本。

以下 JSON 将源映像设置为存储在直接共享库中的映像。

注意

直接共享库目前以预览版提供。

    source: {
      "type": "SharedImageVersion",
      "imageVersionId": "<replace with resourceId of the image stored in the Direct Shared Gallery>"
    },

以下 JSON 将源映像设置为 Azure Compute Gallery 中存储的映像的最新映像版本。

"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 映像生成器映像模板资源的标识。

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

模板创建方案

  • stagingResourceGroup 属性保留为空

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

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

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

重要

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

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

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

模板删除

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

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

属性:验证

无论是否使用 Azure 映像生成器创建平台映像和自定义映像,都可以使用该 validate 属性验证平台映像和任何自定义映像。

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,或者不希望映像生成器能够访问现有的 VNet 资源,例如配置服务器(DSC、Chef、Puppet 和 Ansible)和文件共享,则你可以指定 VNet。 有关详细信息,请查看网络文档

"vnetConfig": {
  "subnetId": "/subscriptions/<subscriptionID>/resourceGroups/<vnetRgName>/providers/Microsoft.Network/virtualNetworks/<vnetName>/subnets/<subnetName>"
}

映像模板操作

启动映像生成

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

Invoke-AzResourceAction -ResourceName $imageTemplateName -ResourceGroupName $imageResourceGroup -ResourceType Microsoft.VirtualMachineImages/imageTemplates -ApiVersion "2021-10-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 "2021-10-01" -Action Cancel -Force
az resource invoke-action \
  --resource-group $imageResourceGroup \
  --resource-type  Microsoft.VirtualMachineImages/imageTemplates \
  -n helloImageTemplateLinux01 \
  --action Cancel

后续步骤

Azure 映像生成器 GitHub 中提供了适用于不同方案的示例 .json 文件。