You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HashiCorp Packer配置执行报错:SSH脚本权限拒绝问题排查

问题:Packer构建AMI时出现SSH脚本权限拒绝错误(退出码126)

我用HashiCorp Packer编写了app.pkr.hcl配置文件,目标是启动EC2实例、执行user-data.sh脚本并生成包含应用的AMI。执行packer validate通过后运行构建,出现SSH脚本权限拒绝错误(退出码126)。已将脚本上传至实例并赋予755权限,配置文件与脚本在同一目录,添加IAM实例配置文件后仍报错,需排查问题原因。


Packer配置代码

variable "ami_id" {
  type    = string
  default = "ami-xxxxxxxxxx"
}
variable "environment" {
  type    = string
  default = "DEMO"
}
variable "ec2_size" {
  type    = string
  default = "t2.micro"
}

variable "ssh-user" {
  type    = string
  default = "ec2-user"
}

variable "app_name" {
  type    = string
  default = "Test App"
}

locals {
  app_name = "Test App"
}
source "amazon-ebs" "rhel8" {
  ami_name      = "PACKER-POC-${local.app_name}"
  instance_type = "${var.ec2_size}"
  #region        = "${var.region}"
  source_ami   = "${var.ami_id}"
  ssh_username = "${var.ssh-user}"
  vpc_id       = "vpc-xxxxxxxxxx"
  subnet_id    = "subnet-xxxxxxxxxx"
  ssh_timeout          = "5m"
  iam_instance_profile = "ASMEC2InstanceProfile"
  tags = {
    Env  = "${var.environment}"
    Name = "PACKER-${var.environment}-${var.app_name}"
  }
}
build {
  sources = ["source.amazon-ebs.rhel8"]

  provisioner "shell" {
    inline = "mkdir -p /tmp/temp123/"
  }

  provisioner "file" {
    source      = "user-data.sh"
    destination = "/tmp/temp123/user-data.sh"
  }

  provisioner "shell" {
    inline = [
     "chmod 755 /tmp/temp123/user-data.sh"
    ]
  }
  provisioner "shell" {
    script = "user-data.sh"
  }

  post-processor "shell-local" {
    inline = ["echo Finished with the Test Application Installation"]
  }
}

报错信息

amazon-ebs.rhel8: output will be in this color.

==> amazon-ebs.rhel8: Prevalidating any provided VPC information
==> amazon-ebs.rhel8: Prevalidating AMI Name: PACKER-POC-TestApp
    amazon-ebs.rhel8: Found Image ID: ami-034197f3f8ec3a4c8
==> amazon-ebs.rhel8: Creating temporary keypair: packer_640f06fc-a274-aff8-f15e-cd1ac572ee40
==> amazon-ebs.rhel8: Creating temporary security group for this instance: packer_640f06ff-8d73-979b-69ba-b432d60bd675
==> amazon-ebs.rhel8: Authorizing access to port 22 from [0.0.0.0/0] in the temporary security groups...
==> amazon-ebs.rhel8: Launching a source AWS instance...
    amazon-ebs.rhel8: Instance ID: i-0bf8682dc88b27e3b
==> amazon-ebs.rhel8: Waiting for instance (i-0bf8682dc88b27e3b) to become ready...
==> amazon-ebs.rhel8: Using SSH communicator to connect: 10.10.164.253
==> amazon-ebs.rhel8: Waiting for SSH to become available...
==> amazon-ebs.rhel8: Connected to SSH!
==> amazon-ebs.rhel8: Provisioning with shell script: /var/folders/m4/mxxzm10d2d774n5j9yn2l54m0000gq/T/packer-shell3653121735
==> amazon-ebs.rhel8: bash: /tmp/script_1399.sh: Permission denied
==> amazon-ebs.rhel8: Provisioning step had errors: Running the cleanup provisioner, if present...
==> amazon-ebs.rhel8: Terminating the source AWS instance...
==> amazon-ebs.rhel8: Cleaning up any extra volumes...
==> amazon-ebs.rhel8: No volumes to clean up, skipping
==> amazon-ebs.rhel8: Deleting temporary security group...
==> amazon-ebs.rhel8: Deleting temporary keypair...
Build 'amazon-ebs.rhel8' errored after 4 minutes 9 seconds: Script exited with non-zero exit status: 126. Allowed exit codes are: [0]

==> Wait completed after 4 minutes 9 seconds

==> Some builds didn't complete successfully and had errors:
--> amazon-ebs.rhel8: Script exited with non-zero exit status: 126. Allowed exit codes are: [0]

==> Builds finished but no artifacts were created.

文件目录信息

ls -larth
total 24
-rwxr-xr-x@  1 testuser  staff   6.5K Mar 10 11:21 user-data.sh
drwxr-xr-x  10 testuser  staff   320B Mar 10 21:08 ..
drwxr-xr-x   4 testuser  staff   128B Mar 12 13:56 .
-rw-r--r--   1 testuser  staff   1.4K Mar 13 14:00 app.pkr.hcl

问题分析与解决

核心原因

配置存在逻辑矛盾:

  • 你先将user-data.sh上传到实例的/tmp/temp123/目录并赋予执行权限,但最后调用shell provisioner的script参数时,指定的是本地的user-data.sh。
  • Packer处理script参数时,会把本地脚本重新上传到实例的临时目录(如/tmp/script_xxxx.sh),但该临时脚本未被赋予执行权限,或实例/tmp目录带有noexec挂载属性,导致无法执行。

修复方案

方案一:执行已上传到实例的脚本

既然已经完成脚本上传和权限设置,直接执行实例上的脚本即可,替换最后一个shell provisioner:

provisioner "shell" {
  inline = [
    "/tmp/temp123/user-data.sh"
  ]
}

方案二:让Packer自动处理脚本权限

如果要直接使用script参数,添加execute_command配置,确保Packer在执行前给临时脚本加权限:

provisioner "shell" {
  script = "user-data.sh"
  execute_command = "chmod +x {{ .Path }} && {{ .Vars }} {{ .Path }}"
}

此方式可删除前面多余的file和chmod步骤,简化配置。

额外排查点

检查实例/tmp目录的挂载属性:执行mount | grep /tmp,如果输出包含noexec,说明该目录禁止执行脚本,需更换脚本存放目录(如/home/ec2-user/)或修改挂载选项。


内容的提问来源于stack exchange,提问作者learner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:17:55