【问题标题】:How do I force terraform to recreate a resource?如何强制 Terraform 重新创建资源?
【发布时间】:2022-12-29 04:58:03
【问题描述】:

我有两个资源:

resource "aws_lightsail_instance" "myserver-sig" {
  name              = "myserver-Sig"
  availability_zone = "eu-west-2a"
  blueprint_id      = "ubuntu_20_04"
  bundle_id         = "nano_2_0"
  key_pair_name     = "LightsailDefaultKeyPair"
}

resource "aws_lightsail_instance_public_ports" "myserver-sig-public-ports" {
  instance_name = aws_lightsail_instance.myserver-sig.name
  port_info {
    protocol  = "tcp"
    from_port = 443
    to_port   = 443
  }
  port_info {
    protocol  = "tcp"
    from_port = 80
    to_port   = 80
  }
  depends_on = [
    aws_lightsail_instance.myserver-sig,
  ]
}

当我第一次运行terraform apply时,两个资源都被创建了。

如果我想用新版本替换 aws_lightsail_instance,那么 aws_lightsail_instance 将重新部署,但 aws_lightsail_instance_public_ports 不会,因为端口没有改变。

然而,作为aws_lightsail_instance 部署的一部分,它将公共端口更改为关闭 443 并打开 22。这意味着重新部署 aws_lightsail_instance 的最终状态是端口 443 已关闭。

如果我再次运行terraform apply,它将正确替换aws_lightsail_instance_public_ports打开端口 443

我如何强制重新创建aws_lightsail_instance_public_ports 资源以便我只需要运行terraform apply 一次?

【问题讨论】:

  • 您是唯一运行此代码的人吗?是否实施了状态文件锁定?
  • 我是唯一运行此代码的人。是 lightsail 实例本身以打开的默认端口启动。每当您重新创建 lightsail 实例时,您总是需要重新配置端口。这意味着您无法通过锁定状态来阻止实例打开和关闭它自己的端口。
  • 这似乎是您应该提交给他们的 AWS Terraform 提供商中的错误。同时运行apply 两次可能是最好的选择。

标签: amazon-web-services terraform amazon-lightsail


【解决方案1】:

您可以通过将 -replace=ADDRESS 参数与 terraform planterraform apply 一起使用来强制重新创建(删除/创建或 -/+):

terraform apply -replace=aws_lightsail_instance_public_ports.myserver-sig-public-ports

这取代了之前 terraform taint <resource_address> 后跟 planapply 的工作流。如果您使用的是旧版本的 Terraform,则需要改用 taint

terraform taint aws_lightsail_instance_public_ports.myserver-sig-public-ports

【讨论】:

  • 有没有办法在 main.tf 中做到这一点?我只想跑terraform apply
  • @UEFI 如何添加新资源“aws_lightsail_instance_public_ports”“myserver-sig-public-ports-新的“然后评论旧的?
  • @UEFI 我的回答同时满足这两个条件。您已经在包含资源的配置中执行此操作,并且正在执行 terraform apply
  • 我想在没有任何异常参数的情况下执行 terraform apply。我想要一个“一键式”部署,工程师不必考虑奇怪的边缘情况。如果我使该 terraform 命令成为新的正常部署方式,那么逐渐会有更多的东西被添加到 terraform 命令中,并且在一两年内,了解部署我们的基础设施所需的所有边缘情况将成为某人的工作。
  • @UEFI 我认为您可以注释掉 main.tf 中的资源,应用它来销毁资源,然后取消注释并再次应用以重新创建它。
【解决方案2】:

您可以使用生命周期replace_triggered_by 属性来执行此操作。这是在 Terraform 1.2.0(2022 年 5 月发布)中引入的。

如果要在替换 aws_lightsail_instance.myserver-sig 时触发 aws_lightsail_instance_public_ports.myserver-sig-public-ports 的替换,请将以下代码添加到 aws_lightsail_instance_public_ports.myserver-sig-public-ports 配置中:

resource "aws_lightsail_instance_public_ports" "myserver-sig-public-ports" {
  # ...

  lifecycle {
    replace_triggered_by = [
      aws_lightsail_instance.myserver-sig.id
    ]
  }
}

因此,每当替换 Lightsail 实例时,将自动触发公共端口进行替换。

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 2022-01-12
    • 2019-02-27
    • 2021-08-28
    • 2018-10-23
    • 2021-12-16
    • 2018-09-24
    • 2021-03-16
    • 2020-04-06
    相关资源
    最近更新 更多