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

如何通过Terraform为AWS EC2实例保留固定公网IP

问题与解决方案:保留EC2实例原有公网IP的Terraform配置调整

问题描述

我使用Terraform配置创建了4个EC2实例并为其分配静态公网IP,配置代码如下:

resource "aws_instance" "kit-prod-api" {
  subnet_id                   = element(module.vpc.public_subnets, count.index)
  ami                         = data.aws_ami.kit_prod_api_ami.id
  instance_type               = "c5.large"
  associate_public_ip_address = true
  vpc_security_group_ids      = [module.vpc.default_security_group_id, aws_security_group.prod_ssh_security_group.id, aws_security_group.prod_lb_instances_security_group.id]
  count                       = 4
  lifecycle {
    create_before_destroy = "true"
    ignore_changes = [
      ami,
      instance_type,
    ]
  }
  # there are tags and provisioner blocks here too
}

当我需要更新实例以使用新AMI时,会逐个终止实例并执行terraform apply来替换它们。此操作虽能成功,但实例会获取新的公网IP。我发现旧IP会出现在AWS控制台的EIP区域,但之前并未显示。请问是否可以修改该脚本/工作流,使新实例关联原有公网IP?

解决方案

要保留原有公网IP,核心是把自动分配的临时公网IP转为**弹性公网IP(EIP)**并独立管理,再绑定到新实例上。具体步骤如下:

1. 分离EIP资源,独立创建并绑定到实例

修改Terraform配置,新增aws_eip资源,为每个实例分配固定EIP,并通过实例ID绑定:

# 为每个EC2实例创建独立的弹性公网IP
resource "aws_eip" "kit-prod-api" {
  count = 4
  vpc   = true

  # 绑定到对应的EC2实例
  instance = aws_instance.kit-prod-api[count.index].id
  subnet   = element(module.vpc.public_subnets, count.index)

  # 保留EIP,避免实例销毁时自动释放
  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_instance" "kit-prod-api" {
  subnet_id                   = element(module.vpc.public_subnets, count.index)
  ami                         = data.aws_ami.kit_prod_api_ami.id
  instance_type               = "c5.large"
  # 关闭自动分配公网IP,改用手动绑定EIP
  associate_public_ip_address = false
  vpc_security_group_ids      = [module.vpc.default_security_group_id, aws_security_group.prod_ssh_security_group.id, aws_security_group.prod_lb_instances_security_group.id]
  count                       = 4
  lifecycle {
    create_before_destroy = true
    ignore_changes = [
      ami,
      instance_type,
    ]
  }
  # 保留原有的tags和provisioner配置
}

2. 执行配置迁移,保留现有IP

  • 先执行terraform import将现有实例的公网IP导入为aws_eip资源:
    对于每个实例(0到3索引),运行:
    terraform import aws_eip.kit-prod-api[0] <实例对应的公网IP>
    terraform import aws_eip.kit-prod-api[1] <实例对应的公网IP>
    terraform import aws_eip.kit-prod-api[2] <实例对应的公网IP>
    terraform import aws_eip.kit-prod-api[3] <实例对应的公网IP>
    
  • 然后执行terraform apply,此时Terraform会将现有临时IP转为EIP并绑定,不会改变现有IP。

3. 更新AMI时的工作流调整

后续更新AMI时,直接执行terraform apply即可:

  • 由于开启了create_before_destroy,Terraform会先创建新实例(无自动公网IP)
  • 然后将对应的EIP从旧实例解绑,绑定到新实例
  • 最后销毁旧实例,EIP会保留并继续绑定在新实例上,实现IP不变

关键说明

  • 关闭associate_public_ip_address:避免新实例自动分配临时IP,确保仅使用我们管理的EIP
  • prevent_destroy:防止Terraform在销毁实例时误删EIP,确保IP资源持久保留
  • 导入现有IP:将之前自动分配的临时IP转为EIP,无需重新分配新IP

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:03:37