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

Terraform更新Shell脚本时避免重建EC2实例问题求助

问题根源

  1. EC2实例强制重建的核心原因:执行计划明确显示associate_public_ip_address = true -> false # forces replacement,该属性属于EC2实例创建时不可修改的参数,一旦变更必然触发实例销毁重建。
  2. EIP关联资源重建的连锁反应:EIP关联依赖EC2实例ID,当EC2实例被标记为重建时,关联资源也会被强制替换。
  3. EIP关联配置笔误:aws_eip_association中的allocation_id = aws_eip.server_eip_eip.id是错误引用,正确应为aws_eip.server_eip.id,该错误会加剧配置异常。

解决步骤

1. 终止EC2实例的不必要重建

  • 若不需要关闭自动分配公网IP:将aws_instance.my-ec2中的associate_public_ip_address改回与现有实例一致的true,即可阻止EC2重建。
  • 若确实需要关闭自动分配公网IP:本次terraform apply会强制重建一次EC2,但后续不要再修改该属性,脚本更新就不会再触发EC2重建。

2. 修复EIP关联的配置错误

修正aws_eip_association的allocation_id引用:

resource "aws_eip_association" "eip-association" {
  instance_id   = aws_instance.my-ec2.id
  allocation_id = aws_eip.server_eip.id # 移除多余的_eip后缀
}

3. 确保null_resource仅在脚本更新时触发

当前null_resource的触发器逻辑正确,但需添加依赖保证EIP绑定完成后再执行文件复制,避免连接失败:

resource "null_resource" "shell_script" {
  triggers = {
    script_sha = sha256(file("${path.module}/script.sh"))
  }

  provisioner "file" {
    source      = "./script.sh"
    destination = "/home/ubuntu/script.sh"
  }

  connection {
    type        = "ssh"
    user        = "ubuntu"
    private_key = tls_private_key.server_instance.private_key_openssh
    host        = aws_eip.server_eip.public_ip
  }

  depends_on = [aws_eip_association.eip-association] # 等待EIP绑定完成再执行
}

验证

修改完成后执行terraform plan,仅当脚本SHA值变化时,会显示null_resource.shell_script的替换操作,EC2和EIP相关资源不会出现变更。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:34:52