AMI 构建器 (基于 EBS)

原文


类型:amazon-ebs Artifact BuilderId:mitchellh.amazonebs

Packer 的 amazon-ebs 构建器能够创建由 EBS 卷支持的 Amazon AMI,以便在 EC2 中使用。有关基于 EBS 启动的实例和基于实例存储启动的实例二者之间差异的更多信息,请参阅 EC2 文档中的"根设备的存储"部分。

该构建器通过从指定的源 AMI 启动 EC2 实例、在运行的机器上运行配置器,然后从该机器创建 AMI。这一切都在您自己的 AWS 账户中完成。构建器将创建临时密钥对、安全组规则等,在创建镜像时为其提供对实例的临时访问权限。这大大简化了配置。

构建器不负责管理 AMI。一旦它创建了一个 AMI 并将其存储在您的账户中,您就可以对 AMI 进行使用、删除等操作。

注意:默认情况下,临时资源的名字都以 packer 为前缀。如果您想限制 Packer 能够操作的安全组和密钥对,这将很有用。

属于 EBS 的配置参数

构建器有许多可用的配置选项。除了此处列出的项目之外,您还需要查看 AMIBlockDevicesAccessRunCommunicator 的配置参数,这些配置是本构建器成功运行所必需的,可以在页面下方找到。

可选:

  • skip_create_ami (bool) - 如果为 true,Packer 将不会创建 AMI。在测试构建阶段时设置为 true 很有用。默认为 false
  • ami_block_device_mappings (awscommon.BlockDevices) - 将一个或多个块设备映射添加到 AMI。当从您的 AMI 启动新实例时,这些将被附加。要在 Packer 构建期间添加块设备,请参阅下面的 launch_block_device_mappings。根据您使用的不同的 VM 类型,您在此处的选项可能会有所不同。有关字段,请参阅 BlockDevices 文档。
  • run_volume_tags (map[string]string) - 应用于为创建 AMI 而启动的卷的标签。这些标签不会应用于生成的 AMI,除非它们在 tags 中重复。这是一个模板引擎,有关更多信息,请参阅构建模板数据。
  • run_volume_tag ([]{name string, value string}) - 与 run_volume_tags 相同,但定义为包含 namevalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • no_ephemeral (bool) - 仅与 Windows 虚拟机相关:如果您设置此标志,我们将向 launch_block_device_mappings 添加子句,以确保临时驱动器不会显示在 EC2 控制台中。从 EC2 控制台启动虚拟机时该行为是默认行为,但通过 SDK 启动时则不是。有关详细信息,请参阅 https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/InstanceStorage.html。因为我们不会验证您的虚拟机的操作系统类型,所以请确保您不为 *nix 虚拟机设置此设置,否则可能导致不可预测的行为。
  • deprecate_at(string)- AMI 过期的日期和时间,采用 UTC 格式,格式如下:YYYY-MM-DDTHH:MM:SSZ。如果设置了秒数,Amazon EC2 会将秒舍入到最接近的分钟。您不能指定过去的日期。 过期时间的上限是从现在起 10 年。

AMI 配置项

必须

  • ami_name(string)- 在 AWS 控制台中或通过 API 管理 AMI 时将显示的结果 AMI 的名称。这必须是唯一的。为了确保使其独一无二,请使用像 timestamp 这样的函数。

可选

  • ami_description(string)- 为生成的 AMI 设置的描述。默认情况下,此描述为空。
  • ami_virtualization_type(string)- 您正在构建的 AMI 的虚拟化类型。此选项是注册 HVM 镜像所必需的。可以是 paravirtual(默认)或 hvm
  • ami_users ([]string) - 有权使用构建的 AMI 启动虚拟机的帐户 ID 列表。默认情况下,除创建 AMI 的用户外,其他用户均无权使用它。
  • ami_groups ([]string) - 有权使用构建的 AMI 启动虚拟机的组列表。默认情况下,任何组都无权使用构建的 AMI。设置为 all 将使 AMI 可公开访问。 AWS 目前不接受除 all 以外的任何值。
  • ami_org_arns ([]string) - 有权使用构建的 AMI 启动虚拟机的 AWS 组织的 Amazon 资源名称 (ARN) 列表。默认情况下,任何组织都无权使用构建的 AMI。
  • ami_ou_arns ([]string) - 有权使用构建的 AMI 启动虚拟机的 AWS Organizations 组织单位 (OU) 的 Amazon 资源名称 (ARN) 列表。默认情况下,任何组织单位都无权使用构建的 AMI。
  • ami_product_codes ([]string) - 与 AMI 关联的产品代码列表。默认情况下,不会有产品代码与 AMI 关联。
  • ami_regions ([]string) - AMI 将被复制到的区域列表。tags 和属性将随 AMI 一起复制。 AMI 复制需要时间,具体时间取决于 AMI 的大小,但通常需要很多分钟。
  • skip_region_validation (bool) - 如果您想跳过 ami_regions 配置选项的验证,则设置为 true。默认为 false
  • tags (map[string]string) - 应用于 AMI 的键/值对标签。构建器不再向 tags 添加"name":"Packer Builder"条目。
  • tag ([]{name string, value string}) - 与 tags 相同,但定义为包含 namevalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • ena_support(bool)- 在与 HVM 兼容的 AMI 上启用增强网络(ENA 而不是 SriovNetSupport)。如果设置为 true,请将 ec2:ModifyInstanceAttribute 添加到您的 AWS IAM 策略。注意:您必须确保在您的实例上启用了网络增强。请参阅 Amazon 关于启用网络增强的文档
  • sriov_support (bool) - 在 HVM 兼容的 AMI 上启用网络增强(SriovNetSupport 而不是 ENA)。如果为 true,请将 ec2:ModifyInstanceAttribute 添加到您的 AWS IAM 策略。注意:您必须确保在您的实例上启用了网络增强。请参阅 Amazon 关于启用网络增强的文档
  • force_deregister (bool) - 如果同名的 AMI 已经存在,则 Packer 首先强制注销现有的 AMI。默认为 false
  • force_delete_snapshot (bool) - Packer 强制删除已被 force_deregister 注销的镜像所关联的快照。默认为 false
  • encrypt_boot (boolean) - 在将完成配置的实例复制到 AMI 时是否加密生成的 AMI。默认情况下,Packer 会使用源镜像中的加密设置。设置 false 将生成非加密镜像,而 true 将生成加密镜像。 如果您已经使用 launch_block_device_mappings 设置了一个加密密钥,并且该密钥与您希望在最后加密镜像的密钥相同,那么您不需要设置该字段;将其留空将避免不必要的额外复制步骤并为您节省一些时间。 请注意,如果您使用的帐户的全局"Always encrypt new EBS volumes"选项设置为 true,则 Packer 将无法覆盖此设置,并且无论您是否设置此值,最终镜像都将被加密。
  • kms_key_id(string)- 用来加密 AMI 的 KMS 密钥的 ID、别名或 ARN。这仅适用于主region —— AMI 复制到的任何目标区域都将由该区域的默认 EBS KMS 密钥加密,除非您在 AMIRegionKMSKeyIDs 中为特定区域设置了对应的密钥。 如果您选择 encrypt_boot,但不想使用该区域的默认 KMS 密钥,请设置此值。 如果您有一个自定义的 kms 密钥,您希望将其应用于启动卷,并且只在一个区域中构建,不设置本配置项以及 encrypt_boot ,改为在 launch_block_device_mappings 中设置密钥 ID 会更有效(您可以找到下面的例子)。通过防止 Packer 在构建结束时复制和重新加密镜像,这可能会在构建结束时节省很多时间。 有关有效格式,请参阅 AWS API 文档 - CopyImage 中的 KmsKeyId。此字段由 Packer 验证,当使用别名时,您必须在 kms_key_id 前加上 alias/ 前缀。
  • region_kms_key_ids (map[string]string) - 将 ami 复制到的区域,以及用于该区域加密的自定义 kms 密钥 ID(别名或 arn)。密钥必须与 ami_regions 中提供的区域相匹配。如果您只想使用默认 ID 进行加密,则可以只使用 kms_key_idami_regions。如果您希望某个区域使用该区域的默认密钥进行加密,您可以在此映射中使用空字符串 "" 而不是密钥 ID。 (例如"us-east-1":"")但是,如果您将其与 snapshot_users 结合使用,则不能使用默认密钥 ID —— 在这种情况下,您必须使用自定义密钥。有关有效格式,请参阅 AWS API 文档 - CopyImage 中的 KmsKeyId。 此选项优先级高于 kms_key_id 选项 —— 如果您同时设置了两者,并且它们不同,Packer 将使用构建区域的 region_kms_key_ids 中的值,并静默忽略 kms_key_id 中提供的值。
  • skip_save_build_region (bool) - 如果为 true,Packer 将不会检查其正在构建的区域中是否存在具有 ami_name 的 AMI。它将使用临时 AMI 名称,Packer 不会在构建区域中将其转换为 AMI。它会将临时 AMI 复制到 ami_regions 中设置的所有区域,然后删除临时 AMI。默认为 false
  • snapshot_tags (map[string]string) - 应用于快照的键/值对标签。如果快照上已经有 AMI 的标签,它们将覆盖 AMI 标签。
  • snapshot_tag ([]{key string, value string}) - 与 snapshot_tags 相同,但定义为包含 keyvalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • snapshot_users ([]string) - 有权使用快照创建磁盘卷的帐户 ID 列表。默认情况下,除创建 AMI 的用户外,其他用户均无权从快照创建磁盘卷。
  • snapshot_groups ([]string) - 有权从快照创建磁盘卷的组列表。默认情况下,任何组都无权从快照创建卷。 all 将使快照可公开访问。

身份验证配置项

必须

  • access_key (string) - 用于与 AWS 通信的访问密钥。阅读配置教程。在 EBS 上,如果您使用 use_vault_aws_engine 进行身份验证,则无需配置。
  • region(string)- 区域的名称,例如 us-east-1,在该区域启动 EC2 实例以创建 AMI。当 chroot 构建时,这个值是根据环境来推测的。
  • secret_key(string)- 用于与 AWS 通信的机密密钥。阅读配置教程。如果您使用 use_vault_aws_engine 进行身份验证,则无需设置。

可选

  • assume_role (AssumeRoleConfig) - 如果设置了角色 ARN,Packer 将尝试使用提供的凭据代入此角色。有关所有可用选项的更多详细信息以及用法示例,请参阅下面的 AssumeRoleConfig
  • custom_endpoint_ec2(string)- 如果您使用的云平台提供的 API 与 aws EC2 兼容,则可以使用该配置项指定另一个端点,例如 https://ec2.custom.endpoint.com
  • shared_credentials_file (string) - 用以​​加载凭证的凭证文件的路径
  • decode_authorization_messages (bool) - 启动自动使用 sts:DecodeAuthorizationMessage API 对所有经编码的授权(错误)消息进行自动解码。注意:要求有效用户/角色对资源 * 拥有 sts:DecodeAuthorizationMessage 权限。默认为 false
  • insecure_skip_tls_verify (bool) - 这允许略过 AWS EC2 端点的 TLS 验证。默认为 false
  • max_retries (int) - API 调用重试的最大次数,在请求被限制或遇到暂时性故障的情况下。后续 API 调用之间的延迟呈指数增长。
  • mfa_code(string)- MFA TOTP 代码。这应该是一个由用户输入的变量,因为它一直在变化。
  • profile(string)- 使用的 AWS 的共享凭证文件。有关详细信息,请参阅亚马逊关于设置配置文件的文档。
  • skip_metadata_api_check (bool) - 不进行元数据 API 检查
  • skip_credential_validation (bool) - 如果想在运行前跳过验证 AWS 凭证,则设置为 true
  • token (string) - 要使用的访问令牌。这不同于访问密钥和机密密钥。如果您不确定这是什么,那么您可能不需要它。也可以通过 AWS_SESSION_TOKEN 环境变量来设置。
  • vault_aws_engine (VaultAWSEngineOptions) - 从 HashiCorp Vault 的 aws 机密引擎获取凭证。您必须拥有一个 Vault 角色才能使用。有关通过 Vault 引擎生成凭据的更多信息,请参阅 Vault 文档。如果设置此配置,则还必须设置以下选项:
    • name(string)- 必需。指定要生成凭据所使用的角色的名称。这是请求 URL 的一部分。
    • engine_name (string) - aws 机密引擎的名称。在 Vault 文档中,这通常称为 aws,如果未设置 engine_name,Packer 将默认为 aws
    • role_arn(string)- 如果 Vault 角色上的 credential_typeassumed_role,则代入的角色的 ARN。必须匹配 Vault 角色所配置的允许使用的 Aws 角色之一的 ARN。如果 Vault 角色只配置了一个 AWS 角色 ARN,则可选;否则必填。
    • ttl(string)- 指定使用 STS 令牌的 TTL。格式是带有时间单位后缀的字符串。仅当 credential_typeassumed_rolefederation_token 时有效。如果未指定,将使用为角色设置的 default_sts_ttl。如果 default_sts_ttl 也未设置,则将使用默认值 3600s。 AWS 对允许的最大 TTL 进行了限制。有关更多详细信息,请参阅有关 AssumeRole(对应于 assumed_role 凭证类型)和 GetFederationToken(对应于 federation_token 凭证类型)的 DurationSeconds 参数的 AWS 文档。

HCL2 样例:

vault_aws_engine {
    name = "myrole"
    role_arn = "myarn"
    ttl = "3600s"
}

JSON 样例:

{
    "vault_aws_engine": {
        "name": "myrole",
        "role_arn": "myarn",
        "ttl": "3600s"
    }
}
  • aws_polling (*AWSPollingConfig) - AWS 轮询等待的配置,设置检查资源状态的长轮询配置。

代入角色的配置

AssumeRoleConfig 允许用户设置配置选项以在执行 Packer 时代入指定角色。

HCL 配置样例:

source "amazon-ebs" "example" {
    assume_role {
        role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
        session_name = "SESSION_NAME"
        external_id  = "EXTERNAL_ID"
    }
}

JSON 配置样例:

builder{
    "type": "amazon-ebs",
    "assume_role": {
        "role_arn"    :  "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME",
        "session_name":  "SESSION_NAME",
        "external_id" :  "EXTERNAL_ID"
    }
}
  • role_arn(string)- 要代入的 IAM 角色的 Amazon 资源名称 (ARN)。
  • duration_seconds (int) - 限制代入角色会话持续时间的秒数。
  • external_id (string) - 代入角色时使用的外部 ID。如果省略,则不会将外部 ID 传递给 AssumeRole 调用。
  • policy (string) - IAM 策略 JSON,进一步限制所代入的 IAM 角色的权限。
  • policy_arns ([]string) - IAM 策略的 Amazon 资源名称 (ARN) 集,描述进一步限制 IAM 角色的权限
  • session_name (string) - 代入角色时使用的会话名称。
  • tags (map[string]string) - 代入角色时使用的会话的标签。
  • transitive_tag_keys ([]string) - 一组代入角色时使用的会话标签键,这些键会被传递给所有后续会话。

长轮询配置

AWS 长轮询配置。为创建资源\附加卷或导入镜像等操作配置长轮询参数。

HCL 样例:

aws_polling {
     delay_seconds = 30
     max_attempts = 50
}

JSON 样例:

"aws_polling" : {
     "delay_seconds": 30,
     "max_attempts": 50
}
  • max_attempts (int) - 指定长轮询检查资源状态的最大尝试次数。该值也可以通过环境变量 AWS_MAX_ATTEMPTS 设置。如果同时设置了配置项和环境变量,则将优先使用 max_attempts 而不是 AWS_MAX_ATTEMPTS。如果未设置,则使用 AWS 长轮询默认值,即 40 作为 max_attempts
  • delay_seconds (int) - 指定尝试检查资源状态之间的延迟秒数。该值也可以通过环境变量 AWS_POLL_DELAY_SECONDS 设置。如果同时设置了配置项和环境变量,则优先使用 delay_seconds 而不是环境变量。如果未设置,则使用 AWS 长轮询默认值,即 15 秒。

运行时配置

必须

  • instance_type(string)- 构建 AMI 时要使用的 EC2 实例类型,例如 t2.small
  • source_ami(string)- 将在当前运行的实例上复制和配置其根卷的源 AMI。必须是一个您有权访问的基于 Ebs 的根卷 AMI。

可选

  • associate_public_ip_address (confighelper.Trilean) - 如果使用非默认 VPC,默认情况下不分配公共 IP 地址。如果配置该选项,您的新实例将获得一个公共 IP。默认值:unset
  • availability_zone (string) - 启动实例的目标可用区。不设置该配置项则会交由亚马逊自动分配。
  • block_duration_minutes (int64) - 需要同时设置 spot_price。 Spot 实例所需的持续时间(也称为 Spot 块)。该值必须是 60 的倍数(60、120、180、240、300 或 360)。如果设置了本配置项,则无法指定可用区或启动组(launch group)。注意:此参数自 2021 年 7 月 1 日起不再对新客户可用。请参阅亚马逊的文档
  • capacity_reservation_preference(string)- 设置是否优先使用容量预留的配置(如果存在)。可配置的值有:opennone。默认为 none
  • capacity_reservation_id(string)- 设置将由 Packer 使用的指定 EC2 容量预留 ID。
  • capacity_reservation_group_arn(string)- 设置将由 Packer 使用的 EC2 容量预留组的 ARN。
  • disable_stop_instance (bool) - Packer 通常会在所有配置程序运行后停止构建实例。对于 Windows 实例,有时需要运行 Sysprep 来为您停止实例。如果将其设置为 true,Packer 将不会停止实例,但会假设您将通过最后一个配置器发送停止信号。你可以使用 windows-shell provisioner 来实现这一点。请注意,Packer 仍将等待实例停止,如果您将此标志设置为 true,则配置器运行失败导致没能发送停止信号将导致超时。 一个 windows-shell provisioner 中有效的 windows 关机命令的示例是:
ec2config.exe -sysprep

或者是:

"%programfiles%\amazon\ec2configservice\"ec2config.exe -sysprep""

注意:如果您的 CMD shell 当前路径已经在 C:\Program Files\Amazon\EC2ConfigService\ 目录中,则命令中不需要双引号。

  • ebs_optimized (bool) - 将实例配置为启用 EBS 优化。默认为 false
  • enable_nitro_enclave (bool) - 在实例上启用对 Nitro Enclaves 的支持。请注意,实例类型必须能够支持 N​​itro Enclaves。 Spot 实例不支持此选项。
  • enable_t2_unlimited (bool) - 已废弃的参数 - 请使用 enable_unlimited_credits。启用 T2 Unlimited 允许源实例在必要时,在其可用 CPU 积分之外突发使用额外的 CPU。这与仅允许实例消耗其可用 CPU 积分的标准配置形成对比。有关更多信息,请参阅 T2 Unlimited 的 AWS 文档和 Amazon EC2 按需实例定价文档T2 Unlimited 定价部分。默认情况下,此选项处于禁用状态,Packer 将使用 T2 标准实例。 要使用 T2 Unlimited,您必须使用 T2 实例类型,例如 t2.micro。此外,T2 Unlimited 不能与 Spot 实例结合使用,例如当配置了 spot_price 选项时。尝试这样做会导致错误。 警告!启用 T2 Unlimited 可能会产生额外费用 - 即使对于通常符合 AWS 免费套餐资格的实例也是如此。
  • enable_unlimited_credits (bool) - 启用无限积分,允许源实例在必要时突发使用超出其可用 CPU 积分的额外 CPU。这与仅允许实例消耗其可用 CPU 积分的标准配置形成对比。有关更多信息,请参阅 T2 Unlimited 的 AWS 文档和 Amazon EC2 按需定价文档的 Unlimited 定价部分。默认情况下,此选项是禁用的,Packer 使用标准实例。 要使用 Unlimited,您必须使用 T2/T3/T3a/T4g 实例类型,例如(t2.microt3.micro)。此外,Unlimited 不能与 T2 类型实例的 Spot 实例结合使用,例如当配置了 spot_price 选项时。如果基础实例类型是 T2 类型实例,尝试这样做将导致错误。默认情况下,受支持的可突增实例类型(包括 t3/t3a/t4g)将配置为标准的 CPU 积分,只有当 enable_unlimited_creditstrue 时,才会为实例提供无限的 CPU 积分。
  • iam_instance_profile(string)- 用于启动 EC2 实例的 IAM 实例配置文件的名称。
  • fleet_tags (map[string]string) - 将应用于发布的 fleet 的键/值对标签。
  • fleet_tag ([]{key string, value string}) - 与 fleet_tags 相同,但定义为包含 keyvalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • skip_profile_validation (bool) - 是否检查 IAM 实例配置文件是否存在。默认为 false
  • temporary_iam_instance_profile_policy_document (*PolicyDocument) - 临时 IAM 实例配置文件策略文档。如果设置了 IamInstanceProfile,则不会使用该配置。 HCL 样例:
temporary_iam_instance_profile_policy_document {
    Statement {
        Action   = ["logs:*"]
        Effect   = "Allow"
        Resource = ["*"]
    }
    Version = "2012-10-17"
}

JSON 样例:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
            "logs:*"
            ],
            "Effect": "Allow",
            "Resource": ["*"]
        }
    ]
}
  • shutdown_behavior (string) - 在 Packer 发生异常退出时自动终止实例。可能的值是 stopterminate。默认是 stop
  • security_group_filter (SecurityGroupFilterOptions) - 用来生成 security_group_ids 字段的过滤器。 HCL 样例:
  security_group_filter {
    filters = {
      "tag:Class": "packer"
    }
  }

JSON 样例:

{
  "security_group_filter": {
    "filters": {
      "tag:Class": "packer"
    }
  }
}

该样例过滤出 tag 中 Classpacker 的安全组以供使用。

  • filters(map[string,string] 或是用逗号分隔的多个过滤器)- 用于过滤 security_group_ids 的过滤器。 DescribeSecurityGroups 文档中描述的所有过滤器均有效。

security_group_ids 的优先级更高。

  • run_tags (map[string]string) - 应用于生成的密钥对、安全组、快照和为创建 EBS 卷而启动的实例的键/值对标签。生成的 AMI 也将继承这些标签。
  • run_tag ([]{key string, value string}) - 与 run_tags 相同,但定义为包含 keyvalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • security_group_id (string) - 要分配给实例的安全组的 ID(不是名称)。默认不设置,Packer 将自动创建一个新的临时安全组以允许 SSH 访问。请注意,如果配置,则必须确保安全组允许访问 ssh_port 配置指定的端口。
  • security_group_ids ([]string) - 如上所述的安全组列表。请注意,如果设置本参数,则不能设置 security_group_id
  • source_ami_filter (AmiFilterOptions) - 用于生成 source_ami 字段的过滤器。 HCL 样例:
source "amazon-ebs" "basic-example" {
  source_ami_filter {
    filters = {
       virtualization-type = "hvm"
       name = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
       root-device-type = "ebs"
    }
    owners = ["099720109477"]
    most_recent = true
  }
}

JSON 样例:

"builders" [
  {
    "type": "amazon-ebs",
    "source_ami_filter": {
       "filters": {
       "virtualization-type": "hvm",
       "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
       "root-device-type": "ebs"
       },
       "owners": ["099720109477"],
       "most_recent": true
    }
  }
]

该配置将从 Canonical 选出最新的 Ubuntu 16.04 HVM EBS AMI。注意:除非恰好返回一个 AMI,否则 Packer 会失败。在上面的示例中,most_recent 将通过只选择最新的镜像使运行成功。

  • filters(map[string,string] 或是用逗号分隔的多个过滤器)- 用于选择 source_ami 的过滤器。注意:除非恰好返回一个 AMI,否则将触发失败。 DescribeImages 文档中描述的所有过滤器均有效。
  • owners([]string)- 按所有者过滤镜像。您可以指定一个或多个 AWS 账户 ID、"self"(它将使用您用来运行 Packer 的凭据的账户)或 AWS 所有者别名:例如,amazonaws-marketplacemicrosoft。出于安全原因,此选项是必需的。
  • most_recent (boolean) - 为 true 时只选择最新创建的镜像。这对于选择每日发行版本最常用的。 您可以设置该参数来代替 source_ami 或与之结合使用。如果将它与 source_ami 一起设置,则 source_ami 将被添加到过滤器中。提供的 source_ami 必须满足 source_ami_filter 中设置的所有过滤条件;这会锁定过滤器返回的 AMI,但如果 source_ami 不存在,则会导致 Packer 失败。
  • spot_instance_types ([]string) - 用于运行构建的可接受实例类型列表。我们将使用 spot_price 的最高价格和分配策略的"最低价格"来请求 spot 实例。您的实例将以您列表中可用价格最低的实例类型启动。该参数将代替 instance_type。您只能设置 spot_instance_typesinstance_type,不能同时设置。此功能的存在是为了帮助防止 Packer 构建失败的情况,因为指定的可用区可能没有 instance_type 中请求的特定实例类型的资源。
  • spot_price(string)- 对于 Spot 实例,您需要支付在您的实例运行期间有效的 Spot 价格。 Spot 实例价格由 Amazon EC2 设定,并根据 Spot 实例容量供需的长期趋势逐步调整。 设置此字段时,它表示您愿意为 Spot 实例支付的最高小时价格。如果您不设置此值,它默认为等于实例的按需价格的最高价格。在当前亚马逊设置的 Spot 价格超过该字段设置值的情况下,Packer 不会启动实例,构建会报错。在亚马逊 Spot 价格低于该字段设定值的情况下,Packer 将启动,您将支付亚马逊 Spot 价格,而不是该参数配置的最大值。有关详细信息,请参阅有关 Spot 定价的 Amazon 文档。
  • spot_tags (map[string]string) - 需要设置 spot_price 参数才能设置本参数。键/值对标签,代表将应用于发出的 Spot 请求上附加的标签。
  • spot_tag ([]{key string, value string}) - 与 spot_tags 相同,但定义为包含 keyvalue 字段的单一块。在 HCL2 模式下,dynamic_block 将允许您动态地生成这些内容。
  • subnet_filter (SubnetFilterOptions) - 用于生成 subnet_id 字段的过滤器。

HCL 样例:

source "amazon-ebs" "basic-example" {
  subnet_filter {
    filters = {
          "tag:Class": "build"
    }
    most_free = true
    random = false
  }
}

JSON 样例:

"builders" [
  {
    "type": "amazon-ebs",
    "subnet_filter": {
      "filters": {
        "tag:Class": "build"
      },
      "most_free": true,
      "random": false
    }
  }
]

该配置选择带有标签 Class 和值 build 的子网,该子网拥有最多的空闲 IP 地址。注意:除非恰好返回一个子网,否则这段代码将会失败。通过使用 most_freerandom 将从匹配过滤器的那些中选择一个。

  • filters(map[string,string] 或是用逗号分隔的多个过滤器)- 用于选择 subnet_id 的过滤器。注意:除非恰好返回一个子网,否则这段代码将会报错。 DescribeSubnets 文档中描述的所有过滤器均有效。
  • most_free (boolean) - 如果过滤器匹配多个子网,将使用具有最多空闲 IPv4 地址的子网。
  • random (boolean) - 如果过滤器匹配多个子网,将使用随机子网。 most_free 的优先级更高。 subnet_id 的优先更高。
    • subnet_id(string)- 如果使用 VPC,该参数指定使用的子网的 ID,例如 subnet-12345def,Packer 将在该子网中启动 EC2 实例。如果您使用的是非默认 VPC,则此字段是必需的。
    • license_specifications ([]LicenseSpecification) - 许可证配置。

HCL 样例:

source "amazon-ebs" "basic-example" {
  license_specifications {
    license_configuration_request = {
      license_configuration_arn = "${var.license_configuration_arn}"
    }
  }
}

JSON 样例:

"builders" [
  {
    "type": "amazon-ebs",
    "license_specifications": [
      {
        "license_configuration_request": {
          "license_configuration_arn": "{{user `license_configuration_arn`}}"
        }
      }
    ]
  }
]

每个 license_configuration_request 描述了一个许可配置,其属性是:

  • license_configuration_arn(string)- 许可证配置的 Amazon 资源名称 (ARN)。
  • placement(Placement)——描述实例的置放信息。

HCL 样例:

source "amazon-ebs" "basic-example" {
  placement = {
    host_resource_group_arn = "${var.host_resource_group_arn}"
    tenancy                 = "${var.placement_tenancy}"
  }
}

JSON 样例:

"builders" [
  {
    "type": "amazon-ebs",
    "placement": {
      "host_resource_group_arn": "{{user `host_resource_group_arn`}}",
      "tenancy": "{{user `placement_tenancy`}}"
    }
  }
]
  • host_resource_group_arn(string)- 将要启动实例的主机资源组的 ARN。如果指定主机资源组 ARN,请省略 Tenancy 参数或将其设置为 host
  • tenancy (string) - 实例的租赁(tenancy)(如果实例在 VPC 中运行)。设置为 dedicated 租赁的实例在单租户硬件上运行。默认是 default,意思是共享租赁。允许的值为 defaultdedicatedhost
    • tenancy (string) - 已弃用:改为使用 Placement Tenancy。
    • temporary_security_group_source_cidrs ([]string) - 当 Packer 程序创建临时安全组时,授权访问实例的 IPv4 CIDR 块列表。默认值为 [0.0.0.0/0](即允许任何 IPv4 源)。如果设置了 temporary_security_group_source_public_ip 则只允许当前运行 Packer 的主机的公共 IP,阻止其他所有 IPv4 源。该配置仅在未指定 security_group_idsecurity_group_ids 时有效。
    • temporary_security_group_source_public_ip (bool) - 设置该参数后,当 Packer 程序创建临时安全组时,使用当前运行 Packer 的主机的公共 IP(从 https://checkip.amazonaws.com 获得)作为 CIDR 块以授权访问实例。默认为 false。该参数仅在未指定 security_group_idsecurity_group_idstemporary_security_group_source_cidrs 时有效。
    • user_data (string) - 启动实例时要应用的 User Data。请注意,由于模板是 JSON,因此您需要注意转义字符。相反,使用 user_data_file 通常更方便。 Packer 不会等待 User Data 脚本完成才关闭实例,这必须在配置器中处理。
    • user_data_file (string) - 启动实例时将用于 User Data 的文件的路径。
    • vpc_filter (VpcFilterOptions) - 用于生成 vpc_id 字段的过滤器。

HCL 样例:

source "amazon-ebs" "basic-example" {
  vpc_filter {
    filters = {
      "tag:Class": "build",
      "isDefault": "false",
      "cidr": "/24"
    }
  }
}

JSON 样例:

"builders" [
  {
    "type": "amazon-ebs",
    "vpc_filter": {
      "filters": {
        "tag:Class": "build",
        "isDefault": "false",
        "cidr": "/24"
      }
    }
  }
]

上述配置将选择带有标签 Class 和值 build 的 VPC,它不是默认 VPC,并且具有 /24 的 IPv4 CIDR 块。注意:除非恰好返回一个 VPC,否则这段代码将会失败。

  • filters (map[string,string] 或是 用逗号分隔的多个过滤器) - 用于选择 vpc_id 的过滤器。注意:除非恰好返回一个 VPC,否则这段代码将会失败。 DescribeVpcs 文档中描述的所有过滤器都是有效的。 vpc_id 参数的优先级更高。
    • vpc_id(string)- 如果要在指定 VPC 子网中启动,Packer 需要 VPC ID 才能在 VPC 内创建临时安全组。需要设置 subnet_id。如果此字段留空,Packer 将尝试从 subnet_id 中获取 VPC ID。
    • windows_password_timeout(duration string,例如:"1h5m2s")- 等待 Windows 实例的 Windows 密码的超时时间。默认为 20 分钟。示例值:10m
    • metadata_options (MetadataOptions) - 元数据配置

元数据配置

下列参数可以用来配置元数据选项。相关详细信息,请参阅配置 IMDS

  • http_endpoint (string) - 用于启用或禁用实例的 IMDS 端点的字符串。默认为 "enabled"。可设置为 "enabled""disabled"
  • http_tokens(string)- 用于将实例对 IMDSv2 的使用设置为 "optional""required"。默认为 "optional"
  • http_put_response_hop_limit (int64) - 用于设置与 IMDS 端点通信时允许的跳数上限。默认为 1
  • instance_metadata_tags(string)- 用于启用或禁用从实例元数据访问实例标签。默认为 "disabled"。商业区域可以访问实例元数据标签。对于非商业区域,请在启用前检查可用性。可选项为 "enabled""disabled"

HCL 样例:

source "amazon-ebs" "basic-example" {
  region        =  "us-east-1"
  source_ami    =  "ami-fce3c696"
  instance_type =  "t2.micro"
  ssh_username  =  "ubuntu"
  ami_name      =  "packer_AWS_example_"
  metadata_options {
    http_endpoint = "enabled"
    http_tokens = "required"
    http_put_response_hop_limit = 1
  }
}

JSON 样例:

{
  "variables": {
    "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
    "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
  },
  "builders": [
    {
      "type": "amazon-ebs",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "us-east-1",
      "source_ami": "ami-fce3c696",
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "packer_AWS {{timestamp}}",
      "metadata_options": {
        "http_endpoint": "enabled",
        "http_tokens": "required",
        "http_put_response_hop_limit": 1
      }
    }
  ]
}

会话管理器(Session Manager)连接

对 AWS Systems Manager 会话管理器的支持使用户无需打开入站端口或维护堡垒主机即可管理 EC2 实例。会话管理器连接依赖于使用会话管理器插件来打开本地机器和远程实例之间的安全隧道。创建隧道后,所有 SSH 通信都将通过 SSM 隧道转接到远程实例。

注意:会话管理器连接目前仅针对 SSH 通信器实现,WinRM 通信器无法使用。

要将会话管理器用作 SSH 通信器的连接接口,您需要将以下配置选项添加到 Amazon 构建器选项中:

  • ssh_interface:ssh 接口必须设置为 "session_manager"。使用此选项时,构建器将创建到远程主机上配置的 ssh_port(默认为 22)的 SSM 隧道。
  • iam_instance_profile:aws ssm-agent 需要一个有效的实例配置文件来授予 Systems Manager 管理远程实例的权限来启动和停止会话连接。有关 Systems Manager 的 IAM 实例配置文件的更多详细信息,请参阅下文。

可选参数

  • session_manager_port:运行 Packer 的主机上的本地端口,用来连接到远程主机的会话隧道。如果未指定,Packer 将寻找一个可用的端口来使用。
  • temporary_iam_instance_profile_policy_document:创建临时实例配置策略文档以授予 Systems Manager 对 Ec2 实例的权限。这是配置 iam_instance_profile 参数的替代方法。

HCL 样例:

# file: example.pkr.hcl

# In order to get these variables to read from the environment,
# set the environment variables to have the same name as the declared
# variables, with the prefix PKR_VAR_.
# You could also hardcode them into the file, but we do not recommend that.

data "amazon-ami" "example" {
  filters = {
    virtualization-type = "hvm"
    name                = "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*"
    root-device-type    = "ebs"
  }
  owners      = ["099720109477"]
  most_recent = true
  region      = "us-east-1"
}

source "amazon-ebs" "ssm-example" {
  ami_name             = "packer_AWS "
  instance_type        = "t2.micro"
  region               = "us-east-1"
  source_ami           = data.amazon-ami.example.id
  ssh_username         = "ubuntu"
  ssh_interface        = "session_manager"
  communicator         = "ssh"
  iam_instance_profile = "myinstanceprofile"
}

build {
  sources = ["source.amazon-ebs.ssm-example"]

  provisioner "shell" {
    inline = ["echo Connected via SSM at '${build.User}@${build.Host}:${build.Port}'"]
  }
}

JSON 样例:

{
  "builders": [
    {
      "type": "amazon-ebs",
      "ami_name": "packer-ami-{{timestamp}}",
      "instance_type": "t2.micro",
      "source_ami_filter": {
        "filters": {
          "virtualization-type": "hvm",
          "name": "ubuntu/images/*ubuntu-xenial-16.04-amd64-server-*",
          "root-device-type": "ebs"
        },
        "owners": ["099720109477"],
        "most_recent": true
      },
      "ssh_username": "ubuntu",
      "ssh_interface": "session_manager",
      "communicator": "ssh",
      "iam_instance_profile": "{{user `iam_instance_profile`}}"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "inline": [
        "echo Connected via SSM at '{{build `User`}}@{{build `Host`}}:{{build `Port`}}'"
      ]
    }
  ]
}

会话管理器插件

通过会话管理器的连接需要使用会话管理器插件(需要与 Packer 一起安装)和能够运行 AWS ssm-agent 的实例 AMI - 有关支持的 AMI 的详细信息,请参阅关于 SSM 代理

为了让 Packer 启动和关闭将您连接到托管实例的会话,您必须首先在本地计算机上安装会话管理器插件。该插件可以安装在受支持的 Microsoft Windows、macOS、Linux 和 Ubuntu Server 版本上。这里是会话管理器插件的安装说明

Systems Manager 的 IAM 实例配置文件

默认情况下,Systems Manager 无权对创建的实例执行操作,因此必须通过使用 AmazonSSMManagedInstanceCore 策略创建实例配置(instance profile)来授予 SSM 访问权限。然后可以将实例配置附加到您希望通过会话管理器插件管理的任何实例。有关创建所需实例配置文件的详细信息,请参阅添加 System Manager 实例配置

块存储设备配置

块存储设备可以嵌套在 ami_block_device_mappingslaunch_block_device_mappings 数组中。

这些磁盘将在您的实例启动时连接。决于您使用的 VM 类型,您在此处的选项可能会有所不同。

示例用例:

以下配置将告诉 Packer 在启动时使用特定的非默认 kms 密钥加密构建实例的根卷:

HCL 样例:

launch_block_device_mappings {
    device_name = "/dev/sda1"
    encrypted = true
    kms_key_id = "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
}

JSON 样例:

"launch_block_device_mappings": [
  {
     "device_name": "/dev/sda1",
     "encrypted": true,
     "kms_key_id": "1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d"
  }
]

请注意,此示例中的 kms_key_id 选项存在于 launch_block_device_mappings 而不是 ami_block_device_mappings 当中。

可在此处找到块设备映射的文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html

可选参数:

  • delete_on_termination (bool) - 配置是否在实例终止时删除 EBS 卷。默认为 false。注意:如果此值未明确设置为 true 并且未通过替代方法清理卷,则每次构建后都会累积额外的卷。
  • device_name(string)- 向实例注册的设备名称(例如,/dev/sdhxvdh)。块设备映射中的每个设备都需要配置。
  • encrypted (boolean) - 配置是否加密卷。默认情况下,Packer 会沿用源镜像中的加密设置。设置 false 将创建未加密的设备,而 true 将创建加密的设备。
  • iops (*int64) - 卷支持的每秒 I/O 操作数 (IOPS)。有关详细信息,请参阅有关 IOPS 的文档
  • no_device (bool) - 禁止包含在 AMI 的块设备映射中的指定设备。
  • snapshot_id (string) - 快照的 ID。
  • throughput (*int64) - gp3 卷的吞吐量,仅对 gp3 类型有效,请参阅有关吞吐量的文档以获取更多信息
  • virtual_name (string) - 虚拟设备名称。有关详细信息,请参阅有关块设备映射的文档。
  • volume_type(string)- 卷类型。 设置为 gp2gp3 使用通用 (SSD) 卷,io1io2 使用预置 IOPS (SSD) 卷,st1 用于吞吐量优化 HDD,sc1 用于冷 HDD,以及标准磁性卷。
  • volume_size (int64) - 卷的大小,以 GiB 为单位。如果未指定 snapshot_id,则为必需。
  • kms_key_id(string)- 用于引导卷加密的 KMS 密钥的 ID、别名或 ARN。此选项存在于 launch_block_device_mappings 而不是 ami_block_device_mappings。此处定义的 kms key id 仅适用于执行构建的区域;如果 AMI 被复制到其他区域,这些区域中的卷将由默认的 EBS KMS 密钥加密。有关有效格式,请参阅 AWS API 文档中的 KmsKeyId - CopyImage 此字段由 Packer 验证。使用别名时,您必须在 kms_key_id 前加上 alias/

通信器配置

可选

  • 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 默认支持的算法。默认值为 [ "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 作为传输文件、安全复制(默认)或 SSH 文件传输的协议。
  • 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) -
  • temporary_key_pair_type(string)- dsa | ECDS | ed25519 | rsa(默认) 指定要创建的密钥类型。可配置的值为"dsa"、"ecdsa"、"ed25519"或"rsa"。
  • temporary_key_pair_bits (int) - 指定要创建的密钥中的位数。对于 RSA 密钥,最小大小为 1024 位,默认为 4096 位。通常,3072 位被认为足够了。 DSA 密钥必须恰好是 FIPS 186-2 指定的 1024 位。对于 ECDSA 密钥,位通过从三种椭圆曲线大小中选择一种来确定密钥长度:256、384 或 521 位。尝试使用 ECDSA 密钥的这三个值以外的位长度将失败。 Ed25519 密钥具有固定长度,位将被忽略。
  • ssh_keypair_name(string)- 如果配置该参数,那么它将是在 SSH 到机器时使用的密钥对。该密钥必须与加载到服务器中的密钥对名称相匹配。默认情况下不配置,除非使用 ssh_password,否则 Packer 将生成一个临时密钥对。使用 ssh_keypair_name 时必须指定 ssh_private_key_filessh_agent_auth
  • ssh_private_key_file(string)- 用于通过 SSH 进行身份验证的 PEM 编码私钥文件的路径。 ~ 可以在路径中使用,将扩展到当前用户的主目录。
  • ssh_agent_auth (bool) - 如果为 true,则本地 SSH 代理将用于验证与源实例的连接。不会创建临时密钥对,ssh_passwordssh_private_key_file 的值将被忽略。必须设置环境变量 SSH_AUTH_SOCK 才能使此选项正常工作。

基础样例

这是一个基础示例。您将需要提供访问密钥,并且可能需要根据运行该模板时所能查到的镜像更改 AMI ID:

HCL:

// To make Packer read these variables from the environment into the var object,
// set the environment variables to have the same name as the declared
// variables, with the prefix PKR_VAR_.

// There are other ways to [set variables](/packer/docs/templates/hcl_templates/variables#assigning-values-to-build-variables)
// including from a var file or as a command argument.

// export PKR_VAR_aws_access_key=$YOURKEY
variable "aws_access_key" {
  type = string
  // default = "hardcoded_key"
}

// export PKR_VAR_aws_secret_key=$YOURSECRETKEY
variable "aws_secret_key" {
  type = string
  // default = "hardcoded_secret_key"
}

source "amazon-ebs" "basic-example" {
  access_key = var.aws_access_key
  secret_key =  var.aws_secret_key
  region =  "us-east-1"
  source_ami =  "ami-fce3c696"
  instance_type =  "t2.micro"
  ssh_username =  "ubuntu"
  ami_name =  "packer_AWS "
}

build {
  sources = [
    "source.amazon-ebs.basic-example"
  ]
}

JSON:

{
  "variables": {
  "aws_access_key": "{{env `AWS_ACCESS_KEY_ID`}}",
  "aws_secret_key": "{{env `AWS_SECRET_ACCESS_KEY`}}"
},
  "builders": [
    {
      "type": "amazon-ebs",
      "access_key": "{{user `aws_access_key`}}",
      "secret_key": "{{user `aws_secret_key`}}",
      "region": "us-east-1",
      "source_ami": "ami-fce3c696",
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "packer_AWS {{timestamp}}"
    }
  ]
}

注意:Packer 也可以不用设置用户变量,直接从环境变量中读取访问密钥和秘密访问密钥。有关 Packer 将查找哪些环境变量的更多信息,请参阅上一节中的配置参考。

有关查找 AMI ID 及其与实例类型和区域的关系的更多信息,请参阅适用于 LinuxWindows 的 AWS EC2 文档。

访问主机实例来调试

如果出于某种原因需要访问实例进行调试,请使用 -debug 标志运行构建器。在调试模式下,Amazon 构建器会将私钥保存在当前目录中,并输出 DNS 或 IP 信息。您可以使用此信息来访问正在运行的实例。

AMI 块存储设备映射示例

下面是一个使用可选 AMI 块设备映射的示例。我们的 launch_block_device_mappings 配置将在构建期间将根卷 (/dev/sda) 扩大到 40gb(高于默认的 8gb)。使用 ami_block_device_mappings,当我们启动 AMI 的新实例时,AWS 将附加额外的卷 /dev/sdb/dev/sdc

HCL 样例:

source "amazon-ebs" "basic-example" {
  region        =  "us-east-1"
  source_ami    =  "ami-fce3c696"
  instance_type =  "t2.micro"
  ssh_username  =  "ubuntu"
  ami_name      =  "packer_AWS_example_"
  launch_block_device_mappings {
    device_name = "/dev/sda1"
    volume_size = 40
    volume_type = "gp2"
    delete_on_termination = true
  }
  // Notice that instead of providing a list of mappings, you are just providing
  // multiple mappings in a row. This diverges from the JSON template format.
  ami_block_device_mappings {
    device_name  = "/dev/sdb"
    virtual_name = "ephemeral0"
  }
  ami_block_device_mappings {
    device_name  = "/dev/sdc"
    virtual_name = "ephemeral1"
  }
}

build {
  sources = [
    "source.amazon-ebs.basic-example"
  ]
}

JSON 样例:

{
  "builders": [
    {
      "type": "amazon-ebs",
      "region": "us-east-1",
      "source_ami": "ami-fce3c696",
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "packer-quick-start ",
      "launch_block_device_mappings": [
        {
          "device_name": "/dev/sda1",
          "volume_size": 40,
          "volume_type": "gp2",
          "delete_on_termination": true
        }
      ],
      "ami_block_device_mappings": [
        {
          "device_name": "/dev/sdb",
          "virtual_name": "ephemeral0"
        },
        {
          "device_name": "/dev/sdc",
          "virtual_name": "ephemeral1"
        }
      ]
    }
  ]
}

假设您已设置环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY,上述构建模板就可以正常工作。

注意:Packer 使用预构建的 AMI 作为构建镜像的来源。这些源 AMI 可能包含未标记为在构建新映像的实例终止时销毁的卷。 Packer 将尝试清除用户未指定在终止后保留的所有剩余卷。如果您需要保留这些源卷,您可以通过在设备的 launch_block_device_mappings 块中将 delete_on_termination 设置为 false 来改写终止设置。

构建时模板中可用的变量

在编写构建模板代码时,可以在代码中使用以下变量:

  • BuildRegion - Packer 正在构建 AMI 的区域(例如 eu-central-1)。
  • SourceAMI - 用于构建 AMI 的源 AMI ID(例如 ami-a2412fcd)。
  • SourceAMICreationDate - 源 AMI 创建日期(例如"2020-05-14T19:26:34.000Z")。
  • SourceAMIName - 用于构建 AMI 的源 AMI 名称(例如 ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306)。
  • SourceAMIOwner - 源 AMI 所有者 ID。
  • SourceAMIOwnerName - 源 AMI 所有者别名/名称(例如 amazon)。
  • SourceAMITags - 源 AMI 标签,类型为 map[string]string

构建时共享的信息变量

本构建器在运行时会生成一些数据,这些数据通过旧的 JSON 模板引擎的构建功能和 HCL2 的上下文变量共享给配置器和后处理器。

  • BuildRegion - Packer 正在构建 AMI 的区域(例如 eu-central-1)。
  • SourceAMI - 用于构建 AMI 的源 AMI ID(例如 ami-a2412fcd)。
  • SourceAMICreationDate - 源 AMI 创建日期(例如 "2020-05-14T19:26:34.000Z")。
  • SourceAMIName - 用于构建 AMI 的源 AMI 名称(例如 ubuntu/images/ebs-ssd/ubuntu-xenial-16.04-amd64-server-20180306)。
  • SourceAMIOwner - 源 AMI 所有者 ID。
  • SourceAMIOwnerName - 源 AMI 所有者别名/名称(例如 amazon)。

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:
build {
  source "amazon-ebs" "basic-example" {
    tags = {
    OS_Version = "Ubuntu"
    Release = "Latest"
    Base_AMI_ID = "{{ .SourceAMI }}"
    Base_AMI_Name = "{{ .SourceAMIName }}"
    }
  }

  // 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_ami_name = "${build.SourceAMIName}"
  }
}

JSON 样例:

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

Tags 样例

这里给出一个使用可选 AMI 标签的示例。这会将 OS_VersionRelease 标签添加到完成的 AMI。和以前一样,您需要提供访问密钥,并且可能需要根据运行此模板时存在的镜像更改源 AMI ID:

HCL 样例:

source "amazon-ebs" "basic-example" {
  region =  "us-east-1"
  source_ami =  "ami-fce3c696"
  instance_type =  "t2.micro"
  ssh_username =  "ubuntu"
  ami_name =  "packer_tag_example {{timestamp}}"
  tags = {
      OS_Version = "Ubuntu"
      Release = "Latest"
      Base_AMI_Name = "{{ .SourceAMIName }}"
      Extra = "{{ .SourceAMITags.TagName }}"
  }
}

build {
  sources = [
    "source.amazon-ebs.basic-example"
  ]
}

JSON 样例:

{
  "builders": [
      {
      "type": "amazon-ebs",
      "region": "us-east-1",
      "source_ami": "ami-fce3c696",
      "instance_type": "t2.micro",
      "ssh_username": "ubuntu",
      "ami_name": "packer-tag-example {{timestamp}}",
      "tags": {
        "OS_Version": "Ubuntu",
        "Release": "Latest",
        "Base_AMI_Name": "{{ .SourceAMIName }}",
        "Extra": "{{ .SourceAMITags.TagName }}"
      }
    }
  ]
}

通过 WinRM 连接 Windows 实例

如果要启动 Windows 实例并使用 WinRM 进行连接,则需要在该实例上配置 WinRM。以下是可以使用 AWS 的 "user_data_file" 选项配置的 powershell 脚本。它通过端口 5986 上的 HTTPS 启用 WinRM,并创建用于连接的自签名证书。如果您使用的是来自 CA 的证书,而不是创建自签名证书,则可以省略下面提到的 "winrm_insecure" 选项。

autogenerated_pa​​ssword_https_bootstrap.txt

<powershell>

# MAKE SURE IN YOUR PACKER CONFIG TO SET:
#
#
#    "winrm_username": "Administrator",
#    "winrm_insecure": true,
#    "winrm_use_ssl": true,
#
#


write-output "Running User Data Script"
write-host "(host) Running User Data Script"

Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore

# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"

# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse

# Create a self-signed certificate to let ssl work
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force

# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"

cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config" '@{MaxTimeoutms="1800000"}'
cmd.exe /c winrm set "winrm/config/winrs" '@{MaxMemoryPerShellMB="1024"}'
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm

</powershell>

您会注意到此配置没有定义用户或密码;相反,Packer 会要求 AWS 提供它自动生成的随机密码。

以下配置将与上述模板一起使用:

HCL 样例:

# This example uses a amazon-ami data source rather than a specific AMI.
# this allows us to use the same filter regardless of what region we're in,
# among other benefits.
data "amazon-ami" "example" {
  filters = {
    virtualization-type = "hvm"
    name                = "*Windows_Server-2012*English-64Bit-Base*"
    root-device-type    = "ebs"
  }
  owners      = ["amazon"]
  most_recent = true
  # Access Region Configuration
  region      = "us-east-1"
}

source "amazon-ebs" "winrm-example" {
  region =  "us-east-1"
  source_ami = data.amazon-ami.example.id
  instance_type =  "t2.micro"
  ami_name =  "packer_winrm_example "
  # This user data file sets up winrm and configures it so that the connection
  # from Packer is allowed. Without this file being set, Packer will not
  # connect to the instance.
  user_data_file = "../boot_config/winrm_bootstrap.txt"
  communicator = "winrm"
  force_deregister = true
  winrm_insecure = true
  winrm_username = "Administrator"
  winrm_use_ssl = true
}

build {
  sources = [
    "source.amazon-ebs.winrm-example"
  ]
}

JSON 样例:

{
  "builders": [
    {
      "type": "amazon-ebs",
      "region": "us-east-1",
      "instance_type": "t2.micro",
      "source_ami_filter": {
        "filters": {
          "virtualization-type": "hvm",
          "name": "*Windows_Server-2012*English-64Bit-Base*",
          "root-device-type": "ebs"
        },
        "most_recent": true,
        "owners": "amazon"
      },
      "ami_name": "default-packer",
      "user_data_file": "./boot_config/winrm_bootstrap.txt",
      "communicator": "winrm",
      "force_deregister": true,
      "winrm_insecure": true,
      "winrm_username": "Administrator",
      "winrm_use_ssl": true
    }
  ]
}

Windows 2016 Sysprep 命令 - 仅适用于 Amazon Windows AMI

对于 Amazon Windows 2016 AMI,必须要运行 Sysprep 命令,这些命令可以轻松添加到配置器当中。

HCL 样例:

provisioner "powershell" {
  inline = [
    "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/InitializeInstance.ps1 -Schedule",
    "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/SysprepInstance.ps1 -NoShutdown"
  ]
}

JSON 样例:

{
  "type": "powershell",
  "inline": [
    "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/InitializeInstance.ps1 -Schedule",
    "C:/ProgramData/Amazon/EC2-Windows/Launch/Scripts/SysprepInstance.ps1 -NoShutdown"
  ]
}

该使用哪种 SSH 参数选项?

如果您设置以下 SSH 选项,下面的图表分解描述了 Packer 会执行的操作:

ssh_password ssh_private_key_file ssh_keypair_name temporary_key_pair_name Packer will...
X - - - 使用给定的用户名和密码进行 ssh 认证
- X - - 使用给定的私钥文件进行 ssh 认证
- X X - 使用给定的私钥文件进行 ssh 验证,并将配置的 keipair 附加到实例上
- - - X 使用特定名称创建一个临时的 ssh keypair,使用后清除
- - - - 使用默认名称创建一个临时的 ssh keypair,使用后清除

results matching ""

    No results matching ""