使用共享加密黄金AMI构建Packer镜像遇ResourceNotReady错误求助
问题背景
使用Packer构建镜像已有3个月,此前使用亚马逊官方AMI可正常构建。改用另一AWS账户共享的定制加密黄金AMI作为源时,出现以下错误:
==> example-packer.amazon-ebs.example: Error waiting for instance (i-xxxxxxxxxxf) to become ready: ResourceNotReady: failed waiting for successful resource state
==> example-packer.amazon-ebs.example: Instance state change details: Client.InternalError: Client.InternalError: Client error on launch
当前Packer核心配置:
source "amazon-ebs" "example" { ami_name = "${local.prefix}${var.image_name}-{{timestamp}}" access_key = "${var.access_key}" secret_key = "${var.secret_key}" token = "${var.session_token}" instance_type = "m5d.8xlarge" region = "us-east-1" vpc_id = "${local.VPC_ID}" subnet_id = "${local.PUBLIC_SUBNET}" security_group_id = "${local.SECURITY_GROUP}" ssh_timeout = "10m" ssh_interface = "private_ip" communicator = "ssh" ssh_bastion_host = "ip" ssh_bastion_username = "user_name" ssh_bastion_private_key_file = "~/.ssh/id_rsa" }
共享黄金AMI包含3个加密块设备:/dev/xvda=snap-xxxxxxx:10:true:gp2:encrypted、/dev/xvdb=snap-xxxxxxx:20:true:gp2:encrypted、/dev/xvdh=snap-xxxxxxxx:10:true:gp2:encrypted,根设备为/dev/xvda,对应共享CMK ARN为arn:aws:kms:us-east-1:account_id:key/bbxxxx-xxxx-xxxx-xxx-xxxxxxxx5。
疑问解答
Q1:通过GitLab pipeline使用role_arn执行Packer构建,是否需要在角色策略中添加权限以访问该KMS密钥?
是,必须添加对应权限。
启动基于加密AMI的实例时,AWS需要解密AMI关联的快照,这要求执行ec2:RunInstances的IAM角色拥有对共享CMK的以下权限:
kms:Decrypt:用于解密快照数据kms:GenerateDataKey:用于实例启动时生成临时磁盘的加密密钥
同时需要确保共享CMK的密钥策略已明确允许你的账户或该IAM角色进行上述操作。示例密钥策略片段:
{ "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::你的账户ID:role/你的GitLab执行角色名" }, "Action": [ "kms:Decrypt", "kms:GenerateDataKey" ], "Resource": "*" }
Q2:添加launch_block_device_mappings配置后错误依旧,问题出在哪?
你误用了launch_block_device_mappings配置:
launch_block_device_mappings是控制临时构建实例的块设备映射,而非最终生成的AMI的磁盘配置。- 源AMI已处于加密状态,重复指定加密配置可能引发冲突;且该配置不会继承源AMI的快照信息,反而可能破坏原有磁盘映射逻辑。
正确做法是使用ami_block_device_mappings配置最终生成的AMI的加密规则,确保新AMI的磁盘使用指定CMK加密。示例配置:
source "amazon-ebs" "example" { // 保留原有其他配置... ami_block_device_mappings { device_name = "/dev/xvda" encrypted = true kms_key_id = "bbxxxx-xxxx-xxxx-xxx-xxxxxxxx5" } ami_block_device_mappings { device_name = "/dev/xvdb" encrypted = true kms_key_id = "bbxxxx-xxxx-xxxx-xxx-xxxxxxxx5" } ami_block_device_mappings { device_name = "/dev/xvdh" encrypted = true kms_key_id = "bbxxxx-xxxx-xxxx-xxx-xxxxxxxx5" } }
额外排查要点
- 验证共享AMI权限:确认源AMI所在账户已将AMI共享给你的AWS账户,且IAM角色拥有
ec2:RunInstances权限使用该AMI。 - 检查安全组出站规则:确保构建实例所在安全组允许HTTPS(443端口)出站流量到KMS服务,否则实例无法访问KMS完成解密。
- 确认实例类型兼容性:验证
m5d.8xlarge实例类型支持源AMI的虚拟化类型(如HVM)。 - 检查子网资源:确保指定的公有子网有足够的IP地址和资源启动实例,避免因资源不足导致启动失败。
内容的提问来源于stack exchange,提问作者Murali Salapu

