【问题标题】:Terraform template re-creating all resources after manually changing EBS volTerraform 模板在手动更改 EBS vol 后重新创建所有资源
【发布时间】:2020-06-13 08:16:03
【问题描述】:

我有一个 terraform 模板,可以为我们的 6 个后端应用程序创建一个 EC2 实例,并相应地添加安全组规则,以便它可以连接到所需的资源。它还创建了 6 个负载均衡器 (ALB),用于将我们的后端暴露给外部。

上周,由于连续错误日志导致磁盘空间达到 100%,我们的生产实例经历了状态检查失败。在此事件中,我们必须使用恢复 EC2 实例来恢复生产实例,并且我们必须手动增加生产实例 EBS 卷的容量。

然后我们尝试更新当前的 terraform 模板以匹配新的 EBS 卷大小,但它会破坏我们所有的生产资源并在此过程中重新创建它们。

我正在尝试找出一种方法来避免模板重新创建所有资源并让模板保持最新以匹配新的 EBS 卷容量。

以下是创建 EC2 实例的代码。

resource "aws_instance" "ec2" {
  ami = "${var.ami_id}"
  instance_type = "${var.instance_type}"
  key_name = "${var.key_pair_name}"
  subnet_id = "${var.private_subnet_id}"
  iam_instance_profile = "${aws_iam_instance_profile.iam_instance_profile.name}"

  /*
   * CAUTION: changing value of below fields will cause the EC2 instance to be terminated and
   * re-created. Think before running the "apply" command.
   */
  associate_public_ip_address = false

  tags = {
    Environment = "${var.env}"
    Project = "${var.project}"
    Provisioner="different-box"
    Name = "${local.name}"
  }

  root_block_device {
    volume_type = "standard"
    volume_size = 50
  }
}

即使我更新 volume_size 以匹配新的大小 100,它仍然会重新创建所有资源。

计划输出

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_instance.ec2 must be replaced
-/+ resource "aws_instance" "ec2" {
        ami                          = "ami-09d1383e2a5ae8a93"
      ~ arn                          = "arn:aws:ec2:us-west-2:289914521333:instance/i-0ffa0d29b8fc91930" -> (known after apply)
        associate_public_ip_address  = false
      ~ availability_zone            = "us-west-2a" -> (known after apply)
      ~ cpu_core_count               = 1 -> (known after apply)
      ~ cpu_threads_per_core         = 2 -> (known after apply)
      - disable_api_termination      = false -> null
      - ebs_optimized                = false -> null
        get_password_data            = false
      - hibernation                  = false -> null
      + host_id                      = (known after apply)
        iam_instance_profile         = "iam_instance_profile_prod"
      ~ id                           = "i-0ffa0d29b8fc91930" -> (known after apply)
      ~ instance_state               = "running" -> (known after apply)
        instance_type                = "t3.large"
      ~ ipv6_address_count           = 0 -> (known after apply)
      ~ ipv6_addresses               = [] -> (known after apply)
        key_name                     = "dev_different"
      - monitoring                   = false -> null
      + network_interface_id         = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      ~ primary_network_interface_id = "eni-061cb6a5ca9240438" -> (known after apply)
      ~ private_dns                  = "ip-172-31-72-30.us-west-2.compute.internal" -> (known after apply)
      ~ private_ip                   = "172.31.72.30" -> (known after apply)
      + public_dns                   = (known after apply)
      + public_ip                    = (known after apply)
      ~ security_groups              = [
          - "default",
          - "different-box.prod-sg",
        ] -> (known after apply)
        source_dest_check            = true
        subnet_id                    = "subnet-00beb1529c4ff05af"
        tags                         = {
            "Environment" = "prod"
            "Name"        = "different-box.prod"
            "Project"     = "different-box"
            "Provisioner" = "different-box"
        }
      ~ tenancy                      = "default" -> (known after apply)
      ~ volume_tags                  = {} -> (known after apply)
      ~ vpc_security_group_ids       = [
          - "sg-0844f9cd4fb14d5d9",
          - "sg-97ef74ef",
        ] -> (known after apply)

      - credit_specification {
          - cpu_credits = "unlimited" -> null
        }

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      ~ root_block_device {
          ~ delete_on_termination = false -> true # forces replacement
          ~ encrypted             = false -> (known after apply)
          ~ iops                  = 0 -> (known after apply)
          + kms_key_id            = (known after apply)
          ~ volume_id             = "vol-01d0d03d564cf44d6" -> (known after apply)
            volume_size           = 100
            volume_type           = "standard"
        }
    }

  # aws_network_interface_sg_attachment.sg_attachment must be replaced
-/+ resource "aws_network_interface_sg_attachment" "sg_attachment" {
      ~ id                   = "sg-0844f9cd4fb14d5d9_eni-061cb6a5ca9240438" -> (known after apply)
      ~ network_interface_id = "eni-061cb6a5ca9240438" -> (known after apply) # forces replacement
        security_group_id    = "sg-0844f9cd4fb14d5d9"
    }

  # module.alb_admin-mobile-api.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/admin-mobile-api-prod-alb-tg/b6940620ef9217f6-20190610084318298800000003" -> (known after apply)
        port             = 1982
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/admin-mobile-api-prod-alb-tg/b6940620ef9217f6"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_admin-portal-backend.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/admin-portal-backend-prod-alb-tg/09e967d1703d0c93-20190610084319310500000004" -> (known after apply)
        port             = 3001
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/admin-portal-backend-prod-alb-tg/09e967d1703d0c93"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_api.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/api-prod-alb-tg/4cb4a656a520c34d-20190610084318237800000001" -> (known after apply)
        port             = 1984
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/api-prod-alb-tg/4cb4a656a520c34d"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_digitalreign.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/digitalreign-prod-alb-tg/c8f0a479686bcaf0-20190610084318291300000002" -> (known after apply)
        port             = 2040
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/digitalreign-prod-alb-tg/c8f0a479686bcaf0"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_engine-ui.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/engine-ui-prod-alb-tg/a2aedefc0c88b5e4-20190701134129654000000001" -> (known after apply)
        port             = 2016
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/engine-ui-prod-alb-tg/a2aedefc0c88b5e4"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_example-backend.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/example-backend-prod-alb-tg/fa7eb3eb4ac1aa95-20190610084319317500000005" -> (known after apply)
        port             = 2010
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/example-backend-prod-alb-tg/fa7eb3eb4ac1aa95"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

  # module.alb_tenant-mobile-api.aws_alb_target_group_attachment.alb_target_group_attachment must be replaced
-/+ resource "aws_alb_target_group_attachment" "alb_target_group_attachment" {
      ~ id               = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/tenant-mobile-api-prod-alb-tg/76edfa9edba45f58-20190610084319318900000006" -> (known after apply)
        port             = 1983
        target_group_arn = "arn:aws:elasticloadbalancing:us-west-2:289914521333:targetgroup/tenant-mobile-api-prod-alb-tg/76edfa9edba45f58"
      ~ target_id        = "i-0ffa0d29b8fc91930" -> (known after apply) # forces replacement
    }

Plan: 9 to add, 0 to change, 9 to destroy.

------------------------------------------------------------------------

【问题讨论】:

  • 能分享一下计划输出吗?
  • @ydaetskcoR 我已将计划输出添加到问题中
  • 您能解释一下您是如何增加现有卷上的空间的吗?看起来delete_on_termination 自创建以来就发生了变化,并且想要强制娱乐。
  • 在这种情况下重新创建 EBS 附件资源也是期望的行为。你可能不希望他们成为孤儿。
  • @AndyShinn,因为在磁盘达到 100% 后我们无法 ssh 进入盒子。我们必须使用恢复实例来增加卷大小。 - 我们停止了生产实例 - 在同一 AZ 中启动了一个新的恢复实例 - 从 prod 实例中分离卷并重新附加到恢复实例 - 然后增加卷大小 - 也使用 diskpart 应用操作系统级别大小更改 - 然后重新附加到生产实例

标签: amazon-web-services amazon-ec2 terraform terraform-provider-aws


【解决方案1】:

根据计划输出,正在重新创建实例,因为卷的delete_on_termination 已更改。当它附加到恢复实例时,这可能会发生变化。

虽然aws_instance 可能不支持更新选项。不过according to the documentation应该是可以的。

有两种可能的解决方案:

  1. 如果您不关心在实例终止时删除卷,您可以简单地将delete_on_termination = false 添加到您的root_block_device。由于您尚未设置它,因此使用默认值(即trueaccording to the documentation)。
  2. 在 Terraform 外部将 DeleteOnTermination 参数更改为 true using the CLI documentation

【讨论】:

  • 太好了,我将尝试第二个选项,因为除生产之外的所有其他环境当前都具有 true 值。
猜你喜欢
  • 2020-05-23
  • 1970-01-01
  • 2021-05-15
  • 2018-09-24
  • 2018-10-23
  • 2021-03-13
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
相关资源
最近更新 更多