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

Terraform配置Shell脚本钩子实现EBS卷DeleteOnTermination及报错排查

问题解决:EBS卷DeleteOnTermination配置与S3桶弃用警告

一、修复local-exec的"bash: ... No such file or directory"错误(退出码127)

退出码127本质是脚本中调用的命令不存在,或脚本路径/写法有误。提供两种解决方案:

方案1:修正local-exec脚本写法

如果坚持使用local-exec,需满足以下要求并调整配置:

  • 执行Terraform的环境已安装AWS CLI,且配置了修改EBS卷属性的权限
  • 脚本变量引用正确,命令路径完整

示例配置:

resource "aws_instance" "example" {
  ami           = "ami-xxxxxx"
  instance_type = "t2.micro"

  # 附加EBS卷
  ebs_block_device {
    device_name = "/dev/sdh"
    volume_size = 10
  }

  provisioner "local-exec" {
    command = <<EOT
      # 等待实例进入运行状态
      aws ec2 wait instance-running --instance-ids ${self.id}
      # 获取目标EBS卷ID
      VOLUME_ID=$(aws ec2 describe-instances --instance-ids ${self.id} --query 'Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==`/dev/sdh`].Ebs.VolumeId' --output text)
      # 修改DeleteOnTermination属性
      aws ec2 modify-instance-attribute --instance-id ${self.id} --block-device-mappings "[{\"DeviceName\": \"/dev/sdh\", \"Ebs\": {\"DeleteOnTermination\": true}}]"
    EOT
    interpreter = ["/bin/bash", "-c"]
  }
}

注意事项:

  • 显式指定interpreter避免shell环境差异
  • 确保aws命令在PATH中,或直接写绝对路径(如/usr/local/bin/aws)
  • 用${self.id}正确引用实例ID,避免语法错误

方案2:用Terraform原生资源替代local-exec(推荐)

local-exec依赖外部工具易出环境问题,更可靠的方式是用aws_ebs_volume_attachment直接配置:

# 创建独立EBS卷
resource "aws_ebs_volume" "example" {
  availability_zone = aws_instance.example.availability_zone
  size              = 10
}

# 附加卷到实例并启用DeleteOnTermination
resource "aws_ebs_volume_attachment" "example" {
  device_name = "/dev/sdh"
  instance_id = aws_instance.example.id
  volume_id   = aws_ebs_volume.example.id

  delete_on_termination = true # 直接启用目标属性
}

resource "aws_instance" "example" {
  ami           = "ami-xxxxxx"
  instance_type = "t2.micro"
}

这种方式完全由Terraform管理,无需依赖外部脚本,从根源避免环境类错误。

二、修复S3桶属性弃用警告

Terraform AWS Provider现在推荐将S3桶配置拆分为独立资源,而非在aws_s3_bucket中嵌套属性:

旧的弃用写法(触发警告)

resource "aws_s3_bucket" "example" {
  bucket = "my-example-bucket"

  # 以下属性已被弃用
  acl           = "private"
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        kms_master_key_id = "arn:aws:kms:us-east-1:xxxxxx:key/xxxxxx"
        sse_algorithm     = "aws:kms"
      }
    }
  }
}

新的合规写法

resource "aws_s3_bucket" "example" {
  bucket = "my-example-bucket"
}

# 单独配置ACL
resource "aws_s3_bucket_acl" "example" {
  bucket = aws_s3_bucket.example.id
  acl    = "private"
}

# 单独配置服务器端加密
resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
  bucket = aws_s3_bucket.example.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = "arn:aws:kms:us-east-1:xxxxxx:key/xxxxxx"
      sse_algorithm     = "aws:kms"
    }
  }
}

其他如版本控制、日志配置等,也需拆分为aws_s3_bucket_versioning、aws_s3_bucket_logging等独立资源,遵循最新Provider规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:55:13