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 的配置参数
构建器有许多可用的配置选项。除了此处列出的项目之外,您还需要查看 AMI、BlockDevices、Access、Run 和 Communicator 的配置参数,这些配置是本构建器成功运行所必需的,可以在页面下方找到。
可选:
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相同,但定义为包含name和value字段的单一块。在 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相同,但定义为包含name和value字段的单一块。在 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_id和ami_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相同,但定义为包含key和value字段的单一块。在 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:DecodeAuthorizationMessageAPI 对所有经编码的授权(错误)消息进行自动解码。注意:要求有效用户/角色对资源*拥有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_type为assumed_role,则代入的角色的 ARN。必须匹配 Vault 角色所配置的允许使用的 Aws 角色之一的 ARN。如果 Vault 角色只配置了一个 AWS 角色 ARN,则可选;否则必填。ttl(string)- 指定使用 STS 令牌的 TTL。格式是带有时间单位后缀的字符串。仅当credential_type为assumed_role或federation_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。默认值:unsetavailability_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)- 设置是否优先使用容量预留的配置(如果存在)。可配置的值有:open与none。默认为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 的支持。请注意,实例类型必须能够支持 Nitro 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.micro,t3.micro)。此外,Unlimited 不能与 T2 类型实例的 Spot 实例结合使用,例如当配置了spot_price选项时。如果基础实例类型是 T2 类型实例,尝试这样做将导致错误。默认情况下,受支持的可突增实例类型(包括 t3/t3a/t4g)将配置为标准的 CPU 积分,只有当enable_unlimited_credits为true时,才会为实例提供无限的 CPU 积分。iam_instance_profile(string)- 用于启动 EC2 实例的 IAM 实例配置文件的名称。fleet_tags(map[string]string) - 将应用于发布的 fleet 的键/值对标签。fleet_tag([]{key string, value string}) - 与fleet_tags相同,但定义为包含key和value字段的单一块。在 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 发生异常退出时自动终止实例。可能的值是stop和terminate。默认是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 中 Class 为 packer 的安全组以供使用。
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相同,但定义为包含key和value字段的单一块。在 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 所有者别名:例如,amazon、aws-marketplace或microsoft。出于安全原因,此选项是必需的。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_types或instance_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相同,但定义为包含key和value字段的单一块。在 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_free 或 random 将从匹配过滤器的那些中选择一个。
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,意思是共享租赁。允许的值为default、dedicated和host。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_id或security_group_ids时有效。temporary_security_group_source_public_ip(bool) - 设置该参数后,当 Packer 程序创建临时安全组时,使用当前运行 Packer 的主机的公共 IP(从 https://checkip.amazonaws.com 获得)作为 CIDR 块以授权访问实例。默认为false。该参数仅在未指定security_group_id、security_group_ids和temporary_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 分钟。示例值:10mmetadata_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_mappings 或 launch_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/sdh或xvdh)。块设备映射中的每个设备都需要配置。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)- 卷类型。 设置为gp2和gp3使用通用 (SSD) 卷,io1和io2使用预置 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 exec 和 docker 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) - 选择使用scp或sftp作为传输文件、安全复制(默认)或 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_file或ssh_agent_auth。ssh_private_key_file(string)- 用于通过 SSH 进行身份验证的 PEM 编码私钥文件的路径。~可以在路径中使用,将扩展到当前用户的主目录。ssh_agent_auth(bool) - 如果为true,则本地 SSH 代理将用于验证与源实例的连接。不会创建临时密钥对,ssh_password和ssh_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 及其与实例类型和区域的关系的更多信息,请参阅适用于 Linux 或 Windows 的 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_ID 和 AWS_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_Version 和 Release 标签添加到完成的 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_password_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,使用后清除 |