Azure Resource Manager 构建器

原文


类型:azure-arm Artifact BuilderId:Azure.ResourceManagement.VMImage

Packer 支持在 Azure 资源管理器中构建虚拟硬盘 (VHD) 和托管镜像。 Azure 在前 30 天为新用户提供 200 美元的信用额度;之后,您将承担使用 Packer 构建和存储虚拟机的费用。

Azure 结合使用 OAuth 和 Active Directory 来授权对 ARM API 的请求。了解如何配置访问 ARM 的授权

下面的文档引用了 Azure CLI 的命令输出。

配置参考

构建器有许多可用的配置选项。我们将从身份验证参数开始介绍,然后是 Azure ARM 构建器特有的选项。除了此处列出的选项之外,还可以为此构建器配置通信器

身份认证选项

在配置中允许通过多种方式对 Azure 客户端进行身份验证。当指定 client_idsubscription_id 以及以下一项且仅一项时:client_secretclient_jwtclient_cert_path —— Packer 将使用指定的 Azure Active Directory (AAD) 服务主体 (SP)。如果仅指定了 use_interactive_auth,Packer 将尝试以交互方式登录当前用户(令牌将被缓存)。如果上述选项均未设置,Packer 将尝试使用运行 Packer 的虚拟机上附加的托管身份和订阅。这仅在 Packer 在具有 System Assigned 或 User Assigned 的托管身份的 Azure 虚拟机上运行时才有效。

托管身份

如果在具有托管身份的 Azure 虚拟机上运行 Packer,则无需指定任何其他配置选项。因为 Packer 将尝试使用运行 Packer 的虚拟机的托管身份和订阅。

可以通过设置 subscription_id 使用不同的订阅。如果您的虚拟机有多个用户分配的托管身份,您也需要设置 client_id

交互式用户登录

要使用交互式用户身份验证,您应该仅设置 use_interactive_auth。 Packer 将使用缓存的凭据或将您重定向到网站进行登录。

服务主体

要使用服务主体,您应该指定 subscription_idclient_id 以及 client_secretclient_cert_pathclient_jwt 之一。

  • subscription_id (string) - 执行构建所使用的订阅 Id。 client_id 中指定的服务主体必须具有对此订阅的完全访问权限,除非指定了 build_resource_group_name 选项,在这种情况下,它需要拥有对 build_resource_group_name 参数中指定的已经存在的资源组的所有者访问权限。
  • client_id(string)- 与您的构建器关联的 Active Directory 服务主体。
  • client_secret(string)- 您的服务主体的密码或机密。
  • client_cert_path(string)- 包含服务主体的证书和私钥的 PEM 文件的位置。
  • client_cert_token_timeout (duration string | ex: "1h30m12s") - 在使用 client_cert_path 时创建的令牌上设置过期时间的时间。
  • client_jwt(string)- 使用与您的服务主体主体关联的证书签署的 JWT。有关详细信息,请参阅 Azure Active Directory 文档

Azure ARM 构建器特定选项

Azure 构建器可以创建 VHD、托管镜像或创建共享镜像库。如果要创建 VHD,则必须使用一个现存的 VHD。同样,如果要创建托管镜像,则必须使用一个现存的托管镜像。托管镜像也可以发布到共享镜像库,但发布到库不需要托管镜像的定义。

必须

  • image_publisher(string)- 用于基础镜像的发布者的名称(仅限 Azure 市场镜像)。有关详细信息,请参阅文档。 使用 CLI 获取该参数的示例 az vm image list-publishers --location westus
  • image_offer(string)- 用于基础镜像的发布者 offer 的名称(仅限 Azure 市场镜像)。有关详细信息,请参阅文档。 使用 CLI 获取该参数的示例 az vm image list-offers --location westus --publisher Canonical
  • image_sku(string)- 适用于基础镜像 offer 的 SKU(仅限 Azure 市场镜像)。有关详细信息,请参阅文档。 使用 CLI 获取该参数的示例 az vm image list-skus --location westus --publisher Canonical --offer UbuntuServer
  • image_url(string)- 作为基础镜像的自定义 VHD 的 URL。如果设置了此值,则不应设置 image_publisherimage_offerimage_skuimage_version
  • custom_managed_image_name(string)- 用作基础镜像的自定义托管镜像的名称。如果设置了该值,则不要设置 image_publisherimage_offerimage_skuimage_version。如果设置了此值,则还必须设置选项 custom_managed_image_resource_group_name。请参阅文档以了解有关托管镜像的更多信息。
  • custom_managed_image_resource_group_name(string)- 用作于基础镜像的自定义托管镜像所在的资源组的名称。如果设置了此值,则不要设置 image_publisherimage_offerimage_skuimage_version。如果设置了此值,则还必须设置选项 custom_managed_image_name。请参阅文档以了解有关托管镜像的更多信息。

创建 VHD 时,需要以下附加选项:

  • capture_container_name (string) - 目标容器名称。本质上是您的 VHD 在 Azure 中所保存的“目录”。创建的 VHD 的 URL 将为 https://<storage_account>.blob.core.windows.net/system/Microsoft.Compute/Images/<capture_container_name>/<capture_name_prefix>.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.vhd
  • capture_name_prefix(string)- VHD 前缀。最终的制品将被命名为 PREFIX-osDisk.UUIDPREFIX-vmTemplate.UUID
  • resource_group_name (string) - 将存储最终制品的资源组。
  • storage_account (string) - 存储最终制品的存储帐户。

创建托管镜像时,需要以下附加选项:

  • managed_image_name (string) - 设置将保存的 Packer 构建的托管镜像的名称。不能存在用该名称命名的托管镜像,Packer 不会覆盖同名文件。如果设置了此值,则还必须设置值 managed_image_resource_group_name。请参阅文档以了解有关托管镜像的更多信息。
  • managed_image_resource_group_name(string)- 设置将保存 Packer 构建的托管镜像的资源组名称。资源组必须已经存在。如果设置了此值,则还必须设置值 managed_image_name。请参阅文档以了解有关托管镜像的更多信息。

可以通过指定 shared_image_gallery 配置选项来创建使用共享库镜像作为源的托管镜像。

Resource Group 用例

Azure 构建器可以在它控制的新资源组(默认)或现有资源组中创建资源。使用 Packer 创建的资源组的优点是失败时清理资源更容易,因为您可以简单地删除整个资源组,但这意味着提供的凭据必须具有创建和删除资源组的权限。通过使用现有资源组,您可以将提供的凭据范围限定到该组,但是构建失败后更有可能留下未使用的制品。

要让 Packer 创建资源组,您必须提供:

  • location(string)您的虚拟机将在该区域运行。

使用 CLI 获取该参数的示例: az account list-locations

并可配置可选参数:

  • temp_resource_group_name(string)分配给构建期间创建的临时资源组的名称。如果没有设置此参数,将分配一个随机值。该资源组在构建结束时被删除。

要使用现有资源组,您必须提供:

  • build_resource_group_name(string)- 指定一个现有的资源组来运行构建。 设置了 temp_resource_group_namelocation 时就不能设置 build_resource_group_name

可选

  • user_assigned_managed_identities ([]string) - 要在虚拟机上配置的用户分配托管身份的一个或多个 ID 的列表。有关如何在虚拟机中获取令牌的信息,请参阅文档。若要将用户分配的托管身份分配给虚拟机,提供的帐户或服务主体必须具有 Managed Identity OperatorVirtual Machine Contributor的角色。
  • capture_name_prefix(string)- VHD 前缀。
  • capture_container_name (string) - 目标容器名称。
  • shared_image_gallery (SharedImageGallery) - 使用共享镜像库的镜像作为本次构建的源镜像。 VHD 目标与此构建类型不兼容 - 目标必须是托管镜像。当使用 shared_image_gallery 作为源时,不应设置 image_publisherimage_offerimage_skuimage_versioncustom_managed_image_name

JSON 样例:

"shared_image_gallery": {
    "subscription": "00000000-0000-0000-0000-00000000000",
    "resource_group": "ResourceGroup",
    "gallery_name": "GalleryName",
    "image_name": "ImageName",
    "image_version": "1.0.0",
}
"managed_image_name": "TargetImageName",
"managed_image_resource_group_name": "TargetResourceGroup"

HCL 样例:

shared_image_gallery {
    subscription = "00000000-0000-0000-0000-00000000000"
    resource_group = "ResourceGroup"
    gallery_name = "GalleryName"
    image_name = "ImageName"
    image_version = "1.0.0"
}
managed_image_name = "TargetImageName"
managed_image_resource_group_name = "TargetResourceGroup"
  • shared_image_gallery_destination (SharedImageGalleryDestination) - 共享镜像库的名称,托管镜像将发布为该共享镜像库内的镜像版本。

JSON 样例:

"shared_image_gallery_destination": {
    "subscription": "00000000-0000-0000-0000-00000000000",
    "resource_group": "ResourceGroup",
    "gallery_name": "GalleryName",
    "image_name": "ImageName",
    "image_version": "1.0.0",
    "replication_regions": ["regionA", "regionB", "regionC"],
    "storage_account_type": "Standard_LRS"
}
"managed_image_name": "TargetImageName",
"managed_image_resource_group_name": "TargetResourceGroup"

HCL 样例:

shared_image_gallery_destination {
    subscription = "00000000-0000-0000-0000-00000000000"
    resource_group = "ResourceGroup"
    gallery_name = "GalleryName"
    image_name = "ImageName"
    image_version = "1.0.0"
    replication_regions = ["regionA", "regionB", "regionC"]
    storage_account_type = "Standard_LRS"
}
managed_image_name = "TargetImageName"
managed_image_resource_group_name = "TargetResourceGroup"
  • shared_image_gallery_timeout(持续时间string | 例如:"1h5m2s") - 在超时之前等待镜像发布到共享镜像库的时间。如果您的 Packer 构建在发布到共享镜像库步骤中失败并出现 Original Error: context deadline exceeded,但是当您从 Azure 网页控制台检查时镜像存在,那么您可能需要将此超时从其默认值 "60m" 增加(有效的时间单位包括 s 代表秒,m 代表分钟,h 代表小时。)
  • shared_gallery_image_version_end_of_life_date(string)- 共享镜像库镜像版本的生命周期结束日期 (2006-01-02T15:04:05.99Z)。此属性可用于退役目的。
  • shared_image_gallery_replica_count (int32) - 要创建的镜像版本在每个区域的副本数。当未指定 regionalReplicaCount 时,此属性将对单个区域生效。副本数必须在 1100 之间,但对于大多数用例而言,50 个副本应该足够了。
  • shared_gallery_image_version_exclude_from_latest (bool) - 如果设置为 true,设置为从最新版本的镜像定义部署的虚拟机将不会使用此镜像版本。
  • image_version(string)- 指定要使用的镜像版本。默认为 latest。由于镜像同步延迟,不同地区可用的版本可能存在差异。为确保跨区域的版本一致,请将此值设置为在您部署的所有区域都可用的值。 使用 CLI 获取该参数的示例 az vm image list --location westus --publisher Canonical --offer UbuntuServer --sku 16.04.0-LTS --all
  • location(string)- 将要运行构建的虚拟机所在的 Azure 数据中心。
  • vm_size (string) - 用于构建的虚拟机的大小。当您从 VHD 部署虚拟机时,可以更改此设置。查看定价信息。默认为 Standard_A1。 使用 CLI 获取该参数的示例 az vm list-sizes --location westus
  • spot (Spot) - 是否在构建期间使用 spot 实例; spot 配置设置仅适用于 Packer 启动的虚拟机,不会保留在生成的镜像制品上。
  • managed_image_resource_group_name(string)- 指定将用于保存 Packer 构建结果的托管镜像的资源组名称。资源组必须已经存在。如果设置了此值,则还必须设置值 managed_image_name。请参阅文档以了解有关托管镜像的更多信息。
  • managed_image_name (string) - 指定将保存 Packer 构建结果的托管镜像名称。不能提前存在同名镜像,Packer 不会尝试覆盖同名镜像。如果设置了此值,则还必须设置 managed_image_resource_group_name。请参阅文档以了解有关托管镜像的更多信息。
  • managed_image_storage_account_type(string)- 指定托管镜像的存储帐户类型。有效值为 Standard_LRSPremium_LRS。默认值为 Standard_LRS
  • managed_image_os_disk_snapshot_name(string)- 如果设置了 managed_image_os_disk_snapshot_name,则会在保存虚拟机之前使用与此值相同的名称创建操作系统磁盘的快照。
  • managed_image_data_disk_snapshot_prefix(string)- 如果设置了 managed_image_data_disk_snapshot_prefix,则在保存虚拟机之前使用与此值相同的前缀创建数据磁盘的快照。
  • keep_os_disk (bool) - 如果设置了 keep_os_disk,则不会删除操作系统磁盘。默认为 false
  • managed_image_zone_resilient (bool) - 将镜像存储在区域弹性存储中。您需要在支持可用区的区域中创建它。
  • azure_tags (map[string]string) - 创建的所有例如资源组、VM、NIC、VNET、公网 IP、KeyVault 等资源所附带的 Name/Value 标签对。用户最多可以定义 15 个标签。标记名称不能超过 512 个字符,标记值不能超过 256 个字符。
  • azure_tag ([]{name string, value string}) - 与 azure_tags 相同,但定义为包含名称和值字段的单一可重复块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • resource_group_name (string) - 将存储最终制品的资源组。
  • storage_account (string) - 存储最终制品的 Storage Account。
  • temp_compute_name(string)- 分配给虚拟机的临时名称。如果未设置此值,将分配一个随机值。知晓资源组和虚拟机名称是的 Packer 在构建期间可以执行命令来更新虚拟机,例如将资源磁盘附加到虚拟机。
  • temp_nic_name (string) - 分配给 Nic 的临时名称。如果未设置此值,将分配一个随机值。如果能够分配遵循命名约定规范的自定义 nic 名称可以简化部署。
  • temp_resource_group_name (string) - 分配给构建期间创建的临时资源组的名称。如果未设置此值,将分配一个随机值。该资源组在构建结束时被删除。
  • build_resource_group_name(string)- 指定一个现有的资源组来运行构建。
  • build_key_vault_name(string)- 指定一个现有的 Key Vault,用于将证书上传到要连接的实例。
  • build_key_vault_sku(string)- 指定要在构建期间创建的 Key Vault 的 SKU。有效值为 standardpremium。默认值为 standard
  • disk_encryption_set_id(string)- 指定磁盘加密集(Disk Encryption Set) ID,用于加密在构建期间使用虚拟机创建的操作系统和数据磁盘,仅在发布到共享镜像库时可用,托管镜像不可用。磁盘加密集 ID 可以在Azure 门户上设置的磁盘加密的属性选项卡中查看 https://learn.microsoft.com/en-us/azure/virtual-machines/image-version-encryption
  • private_virtual_network_with_public_ip (bool) - 此值允许您设置 virtual_network_name 并获取公网 IP。如果未设置该值且 virtual_network_name 已定义,则仅允许从同一子网/虚拟网络上的主机执行 Packer。
  • virtual_network_name(string)- 为虚拟机使用预先存在的虚拟网络。此选项启用与虚拟机的私有通信,不使用或配置公网 IP 地址(除非您设置 private_virtual_network_with_public_ip)。
  • virtual_network_subnet_name (string) - 如果设置了 virtual_network_name,则也可以设置该值。如果设置了 virtual_network_name 而未设置此值,则构建器会尝试确定要与虚拟网络一起使用的子网。如果找不到子网,或者无法在多个子网中决定使用哪个,则应设置此值。
  • virtual_network_resource_group_name(string)- 如果设置了 virtual_network_name,则也可以设置该值。如果设置了 virtual_network_name 而未设置此值,构建器将尝试确定包含虚拟网络的资源组。如果找不到资源组,或者无法消除歧义,则应设置此值。
  • custom_data_file (string) - 指定包含 custom data 的文件以注入到 cloud-init 进程中。文件的内容被读取并注入到 ARM 模板中。custom data 将在配置时传递给 cloud-init 进行处理。请参阅文档以了解有关自定义数据的更多信息,以及如何使用它来影响供应过程。
  • custom_data (string) - 指定启动实例时要应用的 Base64 编码 custom data。请注意,由于模板是 JSON,因此您需要注意转义字符。custom data 将在配置时传递给 cloud-init 进行处理。请参阅文档以了解有关 custom data 的更多信息,以及如何使用它来影响配置过程。
  • user_data_file (string) - 指定包含 user data 的文件以注入到 cloud-init 进程中。文件的内容被读取并注入到 ARM 模板中。从虚拟机被配置到被删除之间,user data 都可以被读取。虚拟机上的任何应用程序都可以在配置后从 Azure 实例元数据服务 (IMDS) 访问 user data。请参阅文档以了解有关用户数据的更多信息。
  • user_data (string) - 指定要应用的 Base64 编码 user data。请注意,由于模板是 JSON,因此您需要注意转义字符。从虚拟机被配置到被删除之间,user data 都可以被读取。虚拟机上的任何应用程序都可以在配置后从 Azure 实例元数据服务 (IMDS) 访问 user data。请参阅文档以了解有关用户数据的更多信息。
  • custom_script(string)- 用于在镜像构建期间运行有关虚拟机配置的脚本。

以下示例执行 user_data_file 指定的文件的内容:

custom_script   = "powershell -ExecutionPolicy Unrestricted -NoProfile -NonInteractive -Command \"$userData = (Invoke-RestMethod -Headers @{Metadata=$true} -Method GET -Uri http://169.254.169.254/metadata/instance/compute/userData?api-version=2021-01-01$([char]38)format=text); $contents = [System.Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($userData)); set-content -path c:\\Windows\\Temp\\userdata.ps1 -value $contents; . c:\\Windows\\Temp\\userdata.ps1;\""
user_data_file  = "./scripts/userdata.ps1"

指定一个命令注入 CustomScriptExtension,在 Windows 构建启动后,通信器尝试连接之前运行,请参阅文档了解更多信息。

  • plan_info (PlanInformation) - 用于从 Marketplace 镜像创建镜像。有关更多详细信息,请参阅使用 Marketplace 条款部署镜像。并非所有 Marketplace 镜像都支持程序化部署,并且镜像的支持是由镜像发布者控制的。

下面定义了一个示例 plan_info 对象。

{
  "plan_info": {
      "plan_name": "rabbitmq",
      "plan_product": "rabbitmq",
      "plan_publisher": "bitnami"
  }
}
  • plan_name (string) - 计划名称,必需。
  • plan_product (string) - 计划产品,必需。
  • plan_publisher (string) - 计划发布者,必需。
  • plan_promotion_code (string) - 一些镜像可以配置促销代码,可选。

使用 plan_info 从 Marketplace 创建的映像必须在部署镜像时指定 plan_info。构建器会自动将以下标签添加到镜像以确保此信息不会丢失:

1.  PlanName
2.  PlanProduct
3.  PlanPublisher
4.  PlanPromotionCode
  • polling_duration_timeout (duration string | ex: "1h5m2s") - azure 的默认 PollingDuration 为 15 分钟,本参数将覆盖该值。请参阅 Azure DefaultPollingDuration。如果您的 Packer 构建在 ARM 部署时失败并出现错误 Original Error: context deadline exceeded,那么您可能需要将此超时从其默认值 15m 增加(有效时间单位包括 s 表示秒,m 表示分钟,h 代表小时。)
  • os_type (string) - 如果指定了 Linux 或 Windows,Packer 将自动为要配置的机器配置身份验证凭据。对于 Linux,会配置 SSH 授权密钥。对于 Windows,会配置一个 WinRM 证书。
  • temp_os_disk_name (string) - 分配给 OSDisk 的临时名称。如果未设置此值,将分配一个随机值。如果能够分配遵循命名约定规范的自定义 osDiskName 名称可以简化部署。
  • os_disk_size_gb (int32) - 以 GB(千兆字节)为单位指定操作系统磁盘的大小。设置位小于等于零的值会被忽略。
  • disk_additional_size ([]int32) - 虚拟机的额外附加硬盘的大小(以 GB 为单位)。如果未指定,则虚拟机将仅包含一个 OS 磁盘。额外磁盘的数量和磁盘的最大大小取决于虚拟机的配置。有关详细信息,请参阅 WindowsLinux

对于 VHD 构建,最终制品将被命名为 PREFIX-dataDisk-<n>.UUID.vhd 并与操作系统磁盘一起存储在指定的存储容器中。额外的磁盘包含名为 PREFIX-vmTemplate.UUID 的部署模板中。

对于托管镜像的构建,最终制品包含在托管镜像中。附加的磁盘将具有与 OS 磁盘相同的存储帐户类型,由 managed_image_storage_account_type 参数所指定。

  • disk_caching_type (string) - 指定磁盘缓存类型。有效值为 NoneReadOnlyReadWrite。默认值为 ReadWrite
  • allowed_inbound_ip_addresses ([]string) - 指定应允许访问虚拟机的 IP 地址和 CIDR 块的列表。如果设置,将使用相应的规则创建 Azure 网络安全组并绑定到虚拟机的子网。不允许同时设置 allowed_inbound_ip_addressesvirtual_network_name
  • boot_diag_storage_account(string)- 指定用于存储启动诊断的存储账户 —— 设置该参数将在指定的存储帐户中创建 2 个文件(串行控制台日志和屏幕截图文件)。构建完成后,必须手动将其删除。在这里查看更多信息
  • custom_resource_build_prefix(string)- 在构建期间指定自定义 Azure 资源名称,限制为最多 10 个字符,这将为资源名称设置前缀。实际资源名称将是 custom_resource_build_prefix + resourcetype + 5 个字符的随机字母数字字符串
  • license_type(string)- 为构建虚拟机指定许可证类型以启用 Azure 混合权益。如果未设置,将使用现收现付(Pay-As-You-Go)许可模式(默认)。有效值为: 对于 Windows:

  • secure_boot_enabled (bool) - 指定是否为虚拟机启用安全引导和可信启动。

  • vtpm_enabled (bool) - 指定是否为虚拟机启用 vTPM(虚拟可信平台模块)和可信启动。
  • async_resourcegroup_delete (bool) - 如果你想让 Packer 异步删除临时资源组时设置这个参数。它是一个布尔值,默认为 false。将此设置为 true 意味着您的构建速度更快,但是删除资源组失败时不会报错。
  • cloud_environment_name(string)- PublicChinaGermanyUSGovernment 之一。默认为 Public。还支持 USGovernmentCloudAzureUSGovernmentCloud 等长格式。
  • metadata_host(string)- Azure 元数据服务的主机名(例如 management.azure.com),用于在使用自定义 Azure 环境时获取云环境。这也可以通过 ARM_METADATA_HOST 环境变量设置该参数。注意:cloud_environment_name 必须设置为 metadata_host 中可用环境列表中请求的环境名称。
  • client_id(string)- AAD 服务主体的 Application ID。还需要设置 client_secretclient_cert_pathclient_jwt
  • client_secret(string)- 为 AAD 服务主体注册的密码/机密。
  • client_cert_path(string)- 将用于作为指定 AAD 服务主体进行身份验证的 pem 编码证书的路径。
  • client_cert_token_timeout (duration string | ex: "1h5m2s") - 使用客户端证书时 JWT 令牌的超时时间。默认为 1 小时。
  • client_jwt(string)- 用于客户端身份验证(RFC 7523,第 2.2 节)的 JWT 承载令牌,将用于对 AAD 服务主体进行身份验证。与使用 client_cert_path 相比,在使用证书身份验证时拥有对令牌过期的更细致控制能力。
  • object_id(string)- AAD 服务主体的 Object ID。可选,如果留空,将从 oAuth 令牌派生。
  • tenant_id(string)- 与您的 client_idsubscription_id 关联的 Active Directory 租户标识符。如果未指定,将使用 subscription_id 查找 tenant_id
  • subscription_id (string) - 要使用的订阅 ID。
  • use_azure_cli_auth (bool) - 使用 Azure CLI 身份验证的参数。默认为 false。 CLI 身份验证将使用来自活动 az login 会话的信息连接到 Azure,并设置与登录帐户关联的订阅 ID 和租户 ID。如果启用,它将使用 az CLI 提供的身份验证。 Azure CLI 身份验证将使用标记为 isDefault 的凭据,并且可以使用 az account show 进行验证。可以搭配普通身份验证 (az login) 和服务主体 (az login --service-principal --username APP_ID --password PASSWORD --tenant TENANT_ID)验证。如果启用则忽略所有其他配置。
  • use_interactive_auth (bool) - 使用交互式登录(使用设备代码)身份验证的标志。默认为 false。如果启用,它将使用交互式身份验证。
  • skip_create_image (bool) - 跳过创建镜像。在构建测试阶段设置为 true 很有帮助。默认为 false

共享镜像库

shared_image_gallery_destination 块可用于将新镜像版本发布到现有共享镜像库。

  • subscription(string)- 使用的订阅
  • resource_group (string) - 使用的资源组
  • gallery_name(string)- 使用的镜像库名称
  • image_name (string) - 镜像名称
  • image_version(string)- 镜像版本
  • replication_regions ([]string) - 要复制到的区域
  • storage_account_type(string)- 为共享镜像库镜像版本指定存储帐户类型。默认为 Standard_LRS。可接受的值为 Standard_LRS``、Standard_ZRSPremium_LRS

构建期共享信息变量

本构建器会生成一些可以通过 JSON 模板引擎的构建功能和 HCL2 的上下文变量与配置器和后处理器共享的数据。

构建器可用的生成变量是:

  • SourceImageName - 部署中使用的源镜像的全名。使用共享镜像时,生成的名称将指向用于创建所述版本的实际源镜像。

HCL 样例:

// When accessing one of these variables from inside the builder, you need to
// use the golang templating syntax. This is due to an architectural quirk that
// won't be easily resolvable until legacy json templates are deprecated:

source "azure-arm" "basic-example" {
  os_type = "Linux"
  image_publisher = "Canonical"
  image_offer = "UbuntuServer"
  image_sku = "14.04.4-LTS"
}

// when accessing one of the variables from a provisioner or post-processor, use
// hcl-syntax
post-processor "manifest" {
    output = "manifest.json"
    strip_path = true
    custom_data = {
        source_image_name = "${build.SourceImageName}"
    }
}

JSON 样例:

"post-processors": [
  {
    "type": "manifest",
    "output": "manifest.json",
    "strip_path": true,
    "custom_data": {
      "source_image_name": "{{ build `SourceImageName` }}"
    }
  }
]

通信器配置

除了构建器选项之外,还可以定义一个通信器:

  • communicator (string) - Packer 目前支持三种通信器:
    • none - 不使用通信器。如果设置了此项,大多数配置器也无法使用。
    • ssh - 将建立到机器的 SSH 连接。通常这是默认值。
    • winrm - 将建立 WinRM 连接。 除了上述三种之外,一些构建器还可以使用自定义通信器。例如,Docker 构建器有一个 docker 通信器,它使用 docker execdocker cp 来执行脚本和复制文件。
  • pause_before_connecting (duration string | ex: "1h5m2s") - 我们建议您将 SSH 或 WinRM 作为访客引导程序脚本的最后一步,但有时您可能会遇到并行竞争场景,您需要 Packer 在尝试连接之前等待你的虚拟机系统就绪。 如果您遇到这种情况,您可以使用模板选项 pause_before_connecting。默认情况下,没有暂停。例如,如果您将 pause_before_connecting 设置为 10m,Packer 将检查它是否可以正常连接。但是一旦连接尝试成功,它将断开连接,然后等待 10 分钟,然后连接到虚拟机并开始配置。
  • ssh_host (string) - SSH 到的地址。这通常由构建器自动配置。
  • ssh_port (int) - 连接到 SSH 的端口。默认为 22
  • ssh_username (string) - 用于连接 SSH 的用户名。如果使用 SSH,则必填。
  • ssh_password(string)- 用于通过 SSH 进行身份验证的明文密码。
  • ssh_ciphers ([]string) - 这会覆盖 Golang 默认支持的 Cipher。默认值为 [ "aes128-gcm@openssh.com", "chacha20-poly1305@openssh.com", "aes128-ctr", "aes192-ctr", "aes256-ctr", ] 密码的有效选项包括:“aes128-ctr”、“aes192-ctr”、“aes256-ctr”、“aes128-gcm@openssh.com”、“chacha20-poly1305@openssh.com”、“arcfour256”、“arcfour128” ", "arcfour", "aes128-cbc", "3des-cbc",
  • ssh_clear_authorized_keys (bool) - 如果为 true,Packer 将尝试从 ~/.ssh/authorized_keys/root/.ssh/authorized_keys 中删除其临时密钥。这主要是一个装饰性的选项,因为无论是否设置为 true,Packer 都会从主机系统中删除临时私钥(除非用户设置了 -debug 标志)。默认为 false;目前仅适用于安装了 sed 的系统。
  • ssh_key_exchange_algorithms ([]string) - 如果设置,Packer 将覆盖 Golang 默认支持的密钥交换 (kex) 算法的值。可接受的值包括:"curve25519-sha256@libssh.org", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521", "diffie-hellman-group14-sha1", 以及 "diffie-hellman-group1-sha1"。
  • ssh_certificate_file(string)- 用于通过 SSH 进行身份验证的用户证书的路径。 ~ 可以在路径中使用,将扩展到当前用户的主目录。
  • ssh_pty (bool) - 如果为 true,将为 SSH 连接请求 PTY。这默认为 false
  • ssh_timeout (duration string | ex: "1h5m2s") - 等待 SSH 可用的时间。 Packer 使用它来确定机器何时启动,因此这通常很长。示例值:10m。默认为 5m,除非设置了 ssh_handshake_attempts
  • ssh_disable_agent_forwarding (bool) - 如果为 true,SSH 代理转发将被禁用。默认为 false
  • ssh_handshake_attempts (int) - 一旦可以连接,尝试使用 SSH 的握手次数。默认为 10,除非设置了 ssh_timeout
  • ssh_bastion_host(string)- 用于实际 SSH 连接的堡垒主机。
  • ssh_bastion_port (int) - 堡垒主机的端口。默认为 22
  • ssh_bastion_agent_auth (bool) - 如果为 true,则将使用本地 SSH 代理对堡垒主机进行身份验证。默认为 false
  • ssh_bastion_username(string)- 连接堡垒主机的用户名。
  • ssh_bastion_password(string)- 用于向堡垒主机进行身份验证的密码。
  • ssh_bastion_interactive (bool) - 如果为 true,则将使用键盘交互方式与堡垒主机进行身份验证。
  • ssh_bastion_private_key_file(string)- 用于与堡垒主机进行身份验证的 PEM 编码私钥文件的路径。 ~ 可以在路径中使用,将扩展到当前用户的主目录。
  • ssh_bastion_certificate_file(string)- 用于与堡垒主机进行身份验证的用户证书的路径。 ~ 可以在路径中使用,将扩展到当前用户的主目录。
  • ssh_file_transfer_method (string) - scpsftp - 如何传输文件、scp(默认)或 sftp。 注意:使用带有 Win32-OpenSSH v9.1.0.0p1-Beta 的 Windows 的用户,scp(用于复制数据的默认协议)返回非零错误代码,因为无法设置 MOTW,这会导致所有文件传输失败。作为解决方法,您可以使用 SFTP 替代传输协议: ssh_file_transfer_protocol = "sftp"
  • ssh_proxy_host (string) - 用于 SSH 连接的 SOCKS 代理主机
  • ssh_proxy_port (int) - SOCKS 代理的端口。默认为 1080
  • ssh_proxy_username(string)- 用于使用代理服务器进行身份验证的可选用户名。
  • ssh_proxy_password(string)- 用于向代理服务器进行身份验证的可选密码。
  • ssh_keep_alive_interval (duration string | ex: "1h5m2s") - 向服务器发送 "keep alive" 消息的频率。设置为负值 (-1s) 以禁用。示例值:10s。默认为 5s
  • ssh_read_write_timeout (duration string | ex: "1h5m2s") - 等待远程命令结束的时间。该参数在某些时候可能很有用,例如,如果 Packer 程序在服务器重启后挂起在连接上。示例:5m。默认情况下禁用。
  • ssh_remote_tunnels ([]string) -
  • ssh_local_tunnels ([]string) -
  • ssh_private_key_file(string)- 用于通过 SSH 进行身份验证的 PEM 编码私钥文件的路径。 ~ 可以在路径中使用,将扩展到当前用户的主目录。

基础样例

这里有一份基础样例,HCL 版本:

source "azure-arm" "basic-example" {
  client_id = "fe354398-d7sf-4dc9-87fd-c432cd8a7e09"
  client_secret = "keepitsecret&#*$"
  resource_group_name = "packerdemo"
  storage_account = "virtualmachines"
  subscription_id = "44cae533-4247-4093-42cf-897ded6e7823"
  tenant_id = "de39842a-caba-497e-a798-7896aea43218"

  capture_container_name = "images"
  capture_name_prefix = "packer"

  os_type = "Linux"
  image_publisher = "Canonical"
  image_offer = "UbuntuServer"
  image_sku = "14.04.4-LTS"

  azure_tags = {
    dept = "engineering"
  }

  location = "West US"
  vm_size = "Standard_A2"
}

build {
  sources = ["sources.azure-arm.basic-example"]
}

JSON 版本:

{
  "type": "azure-arm",

  "client_id": "fe354398-d7sf-4dc9-87fd-c432cd8a7e09",
  "client_secret": "keepitsecret&#*$",
  "resource_group_name": "packerdemo",
  "storage_account": "virtualmachines",
  "subscription_id": "44cae533-4247-4093-42cf-897ded6e7823",
  "tenant_id": "de39842a-caba-497e-a798-7896aea43218",

  "capture_container_name": "images",
  "capture_name_prefix": "packer",

  "os_type": "Linux",
  "image_publisher": "Canonical",
  "image_offer": "UbuntuServer",
  "image_sku": "14.04.4-LTS",

  "azure_tags": {
    "dept": "engineering"
  },

  "location": "West US",
  "vm_size": "Standard_A2"
}

清理配置(Deprovision)

Azure 虚拟机在每次构建结束时都应该执行清理配置。对于 Windows,这意味着执行 sysprep,而对于 Linux,这意味着执行 waagent 清理配置流程。 请参阅 Azure 示例文件夹以获取显示清理配置过程的完整示例。

Windows

以下代码片段显示了如何对 Windows 虚拟机运行 sysprep。清理配置应该是构建执行的最后一个操作。下面的代码将等待 sysprep 将镜像状态写入注册表,然后退出。如果你想等待不同的状态,这里记录了可用的状态。

HCL:

provisioner "powershell" {
   inline = [
        " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.",
        "  while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
        "  while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }",
        "  while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",

        "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm",
        "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10  } else { break } }"
   ]
}

JSON:

{
  "provisioners": [
    {
      "type": "powershell",
      "inline": [
        " # NOTE: the following *3* lines are only needed if the you have installed the Guest Agent.",
        "  while ((Get-Service RdAgent).Status -ne 'Running') { Start-Sleep -s 5 }",
        "  while ((Get-Service WindowsAzureTelemetryService).Status -ne 'Running') { Start-Sleep -s 5 }",
        "  while ((Get-Service WindowsAzureGuestAgent).Status -ne 'Running') { Start-Sleep -s 5 }",

        "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit /mode:vm",
        "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10  } else { break } }"
      ]
    }
  ]
}

Windows Guest Agent 参与 Sysprep 进程。代理必须先完成安装,然后才能对虚拟机运行 sysprep。为确保该前置条件,所有代理服务都必须在执行 sysprep.exe 之前运行。上面的 JSON 片段显示了一种在 PowerShell 配置器中执行此操作的方法。仅当 VM 配置为安装代理时才需要此代码段,这是默认设置。要了解有关禁用 Windows 来宾代理的更多信息,请参阅安装虚拟机代理

请注意,如果配置不正确,sysprep 可能会陷入无限循环 —— 例如,如果它正在等待您从未执行过的重启。

Linux

以下配置代码片段显示了如何清理配置 Linux VM。清理配置应该是构建执行的最后一个操作。

HCL:

provisioner "shell" {
   execute_command = "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'"
   inline = [
        "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
   ]
   inline_shebang = "/bin/sh -x"
}

JSON:

{
  "provisioners": [
    {
      "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
      "inline": [
        "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
      ],
      "inline_shebang": "/bin/sh -x",
      "type": "shell"
    }
  ]
}

要了解有关 Linux 清理配置过程的更多信息,请参阅 WALinuxAgent 的说明

skip_clean

有客户报告了导致构建器挂起的清理配置的问题,错误消息类似于以下内容:

Build 'azure-arm' errored: Retryable error: Error removing temporary script at /tmp/script_9899.sh: ssh: handshake failed: EOF

一种解决方案是在配置器中将 skip_clean 设置为 true。这可以防止 Packer 在构建期间清理上传到虚拟机的所有帮助脚本。

默认值

Azure 构建器尝试选择默认值以使构建刚好可以工作。用户可以将这些值更改为更合适的值。

  • 默认用户名是 Packer,而不是其他构建器中的 root。 Azure 上的大多数发行版不允许使用 root 通过 SSH 连接到虚拟机,因此需要非 root 默认用户。设置 ssh_username 参数以覆盖默认值。
  • 默认的虚拟机规格为 Standard_A1。设置 vm_size 参数以覆盖默认值。
  • 默认镜像版本是 latest。设置 image_version 参数以覆盖默认值。
  • 默认情况下,一个临时的资源组将作为构建的一部分被创建和销毁。如果您没有这样做的权限,请使用 build_resource_group_name 指定一个现有资源组来运行构建。

实现

警告!本节讨论的是一些有关实现细节的深度内容。如果只是使用 Azure 构建器是不需要阅读本节内容的。

Azure 构建器使用 ARM Template 来部署资源。ARM 模板允许您声明所需的资源,无需描述如何实现。

Azure 构建器的工作的前提假设是它创建了执行构建所需的一切。构建完成后,它会简单地删除资源组以清理所有运行时资源。资源组使用 packer-Resource-Group-<random> 的形式命名。值 <random> 是在每次调用 packer 时生成的随机值。 <random> 值在命名资源时尽可能重复使用,因此用户可以在他们的订阅中看到这些这些临时资源时更好地进行识别和分类。

VHD 是在保存用户指定的存储帐户内的,运行时不会随机创建存储账户。保存虚拟机时,生成的 VHD 将存储在与源 VHD 相同的存储帐户中。 Packer 创建的 VHD 必须在构建完成后保留,这就是由用户设置存储账户的原因。

构建的基本步骤是:

  1. 创建资源组。
  2. 验证并部署虚拟机模板。
  3. 运行用户定义的配置器;通常是 shell 命令。
  4. 关闭并保存虚拟机。
  5. 删除资源组。
  6. 删除临时虚拟机的操作系统磁盘。

用于构建的模板当前已在 Packer 代码中定义。对于 Linux、Windows 和 KeyVault 都有对应的模板。模板本身是用名称、密码、SSH 密钥、证书等的占位符模板化的。

什么是随机化

Azure 生成器在运行时创建以下随机值。

  • 管理员密码:使用密码字母表的随机 32 个字符值。
  • 证书:用于保护 WinRM 通信的 2,048 位证书。证书有效期为 24 小时,大致从调用时间开始。
  • 证书密码:一个由 32 个密码字母表中字符组成的随机值,使用用于保护证书私钥。
  • 计算名称:一个随机的 15 个字符的名称,以 pkrvm 为前缀;虚拟机的名称。
  • 部署名称:一个随机的 15 个字符的名称,以 pkfdp 为前缀;部署的名称。
  • KeyVault 名称:一个随机的 15 个字符的名称,前缀为 pkrkv
  • NIC 名称:一个随机的 15 个字符的名称,以 pkrni 为前缀。
  • 公共 IP 名称:一个随机的 15 个字符的名称,前缀为 pkrip
  • 操作系统磁盘名称:一个随机的 15 个字符的名称,以 pkros 为前缀。
  • 数据盘名称:一个随机的 15 个字符的名称,以 pkrdd 为前缀。
  • 资源组名称:一个随机的 33 个字符的名称,前缀为 packer-Resource-Group-
  • 子网名称:一个随机的 15 个字符的名称,以 pkrsn 为前缀。
  • SSH 密钥对:2,048 位非对称密钥对;可以被用户改写。
  • 虚拟网络名称:一个随机的 15 个字符的名称,以 pkrvn 为前缀。
  • 用于随机值的默认字母表是 0123456789bcdfghjklmnpqrstvwxyz。减少了字母表(没有元音字母)以防止与 Azure 规范控制发生冲突。

用于随机值的密码字母表是 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

弃用警告

当您运行 Azure 构建器时,您可能会看到一个看起来很可怕的弃用警告:

==> azure-arm: Warning: You are using Azure Packer Builder to create VHDs which
is being deprecated, consider using Managed Images. Learn more
http://aka.ms/packermanagedimage

不要慌。您的构建不会在短时间内停止工作。

从长远来看,Azure 希望每个人都转向使用托管镜像和托管磁盘,因为它们隐藏了存储帐户性能方面的复杂性。托管磁盘可以导出到 VHD。如果弃用该方法,将由帮助维护 Packer 的 Microsoft 团队以对用户透明的过程来完成。

将来,Packer 可能会移除 VHD 支持,但会添加一个可以自动导出到存储帐户的后处理器。

Windows

Windows 实现与 Linux 构建非常相似,不同之处在于它部署了一个模板来配置 KeyVault。 Packer 使用 WinRM 协议与 Windows VM 通信。 Azure 上的 Windows VM 默认为 WinRM 使用基于密码和证书的身份验证。密码很容易通过 VM ARM 模板设置,但证书需要一个存储介质。 Azure 的证书存储介质是 KeyVault。证书将上传到与虚拟机在同一资源组中预先配置好的的新 KeyVault 内。部署 Windows 虚拟机时,它会链接到 KeyVault 中的证书,Azure 将确保证书作为部署的一部分注入。 Windows 构建的基本步骤是:

  1. 创建资源组。
  2. 验证并部署 KeyVault 模板。
  3. 验证并部署 VM 模板。
  4. 执行规定 - 由用户定义;通常是 shell 命令。
  5. 关闭并捕获 VM。
  6. 删除资源组。
  7. 删除临时 VM 的操作系统磁盘。 Windows 构建需要两个模板和两个部署。不幸的是,KeyVault 和 VM 不能同时部署,因此需要两个模板和部署。部署 KeyVault 模板所需的时间极少,因此总体影响很小。

有关更多示例,请参阅 Packer 项目中的示例文件夹

results matching ""

    No results matching ""