每次我执行“terraform apply”时,Terraform 都想重新应用 aws_ecs_service

问题描述 投票:0回答:1

我正在尝试通过 Terraform 设置 AWS ECS 服务。

ECS 实例(FARGATE)运行 openldap docker 容器。

我现在一切正常,ECS 集群/服务/任务已正确创建。

我预计在做了之后

terraform apply 

一切都启动并运行后,下一个 terraform apply 调用将不执行任何操作,因为没有任何更改。

但是再次执行 terraform apply 时,Terraform 想要销毁服务(及其连接的任务),然后想要使用新任务创建新服务。

为什么要这么做?

这些是 Terraform 定义:

resource "aws_ecs_service" "openldap" {
  name            = "openldap"
  cluster         = aws_ecs_cluster.ecs_cluster_ldap.id
  task_definition = aws_ecs_task_definition.openldap.arn
  desired_count   = 1

  network_configuration {
    subnets = [aws_subnet.sn-public-access.id]
    security_groups = [aws_security_group.secgrp-public-access.id]
    assign_public_ip = true 
  }
}

resource "aws_ecs_task_definition" "openldap" {
  family = "openldap-task-definition"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu       = 512
  memory    = 1024
  execution_role_arn    = aws_iam_role.ecs_task_execution_role.arn

  container_definitions = jsonencode([
    {
      name      = "openldap"
      image     = "public.ecr.aws/bitnami/openldap:2.6.7"
      cpu       = 512
      memory    = 1024
      essential = true
      portMappings = [
        {
          containerPort = 1389
          hostPort      = 1389
        },
        {
          containerPort = 1636
          hostPort      = 1636
        }
      ]
      environment = [
        { name = "LDAP_PORT_NUMBER", value = "1389" },
        { name = "LDAP_ROOT", value = "dc=example,dc=com"},
        { name = "LDAP_ADMIN_USERNAME", value = "admin" },
        { name = "LDAP_ADMIN_PASSWORD_FILE", value = "/openldap/ldap_admin_password.txt" },
        { name = "LDAP_CUSTOM_LDIF_DIR", value = "/openldap/ldif" },
        { name = "BITNAMI_DEBUG", value = "yes" },
        { name = "LDAP_TLS_CERT_FILE", value = "/openldap/certs/ldapserver-cert.pem" },
        { name = "LDAP_TLS_KEY_FILE", value = "/openldap/certs/ldapserver-key.pem" },
        { name = "LDAP_TLS_CA_FILE" , value = "/openldap/certs/ldapserver-cacerts.pem" },
        { name = "LDAP_ENABLE_TLS", value = "yes" },
        { name = "LDAP_ENABLE_RQUIRE_TLS", value = "no" },
        { name = "LDAP_LDAPS_PORT_NUMBER", value = "1636" }
      ]      
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          awslogs-group = "cwlg-ecs-ldap"
          awslogs-stream-prefix = "openldap"
          awslogs-region = "${var.region}"
        }
      }
      mountPoints = [
        {
          "sourceVolume": "openldap",
          "containerPath": "/openldap"
        }
      ]
    }
  ])

 volume {
    name = "openldap"

    efs_volume_configuration {
      file_system_id          = aws_efs_file_system.sandbox-efs.id
      root_directory          = "ldap/"
      transit_encryption      = "ENABLED"
      transit_encryption_port = 2049
    }
  }

  runtime_platform {
    operating_system_family = "LINUX"
    cpu_architecture        = "X86_64"
  }
}

这是第二个 terraform apply 调用的输出:

Terraform will perform the following actions:

  # aws_ecs_service.openldap must be replaced
-/+ resource "aws_ecs_service" "openldap" {
      - health_check_grace_period_seconds  = 0 -> null
      ~ iam_role                           = "/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS" -> (known after apply)
      ~ id                                 = "arn:aws:ecs:eu-central-1:xxxxxxxxxxxx:service/ecs_cluster_ldap/openldap" -> (known after apply)
      + launch_type                        = (known after apply)
        name                               = "openldap"
      ~ platform_version                   = "LATEST" -> (known after apply)
      - propagate_tags                     = "NONE" -> null
      - tags                               = {} -> null
      ~ triggers                           = {} -> (known after apply)
        # (10 unchanged attributes hidden)

      - capacity_provider_strategy { # forces replacement
          - base              = 1 -> null
          - capacity_provider = "FARGATE" -> null
          - weight            = 100 -> null
        }

      - deployment_circuit_breaker {
          - enable   = false -> null
          - rollback = false -> null
        }

      - deployment_controller {
          - type = "ECS" -> null
        }

        # (1 unchanged block hidden)
    }

Plan: 1 to add, 0 to change, 1 to destroy.
amazon-web-services terraform amazon-ecs
1个回答
0
投票

Terraform Apply 输出对于调试重新创建资源的原因非常有用。留意任何带有注释

# forces replacement
的行。这是 Terraform 告诉您哪个属性不同步,需要重新创建资源才能使其同步。

就您而言,它是

capacity_provider_strategy
。虽然您没有在定义中指定它,但在幕后许多资源都采用默认值。

您的

aws_ecs_service
资源定义理想情况下应指定
launch_type
capacity_provider_strategy
参数。这会指示 AWS 以适当的方式为您的服务寻找容量。

您两者都没有指定,所以我怀疑 AWS 默认使用 Fargate,如第二个 Terraform 应用步骤中所报告的那样:

      - capacity_provider_strategy { # forces replacement
          - base              = 1 -> null
          - capacity_provider = "FARGATE" -> null
          - weight            = 100 -> null
        }

如果您想使用 Fargate,请选择以下两种方法之一:

launch_type
capacity_provider_strategy
。如果您不想混合使用部署目标,则前者更简单。

因此,请尝试将以下内容添加到您的 ECS 服务定义中:

launch_type = "FARGATE"

resource "aws_ecs_service" "openldap" {
  name            = "openldap"
  cluster         = aws_ecs_cluster.ecs_cluster_ldap.id
  task_definition = aws_ecs_task_definition.openldap.arn
  desired_count   = 1

  launch_type = "FARGATE"

  network_configuration {
    subnets = [aws_subnet.sn-public-access.id]
    security_groups = [aws_security_group.secgrp-public-access.id]
    assign_public_ip = true 
  }
}

Terraform Apply 的第一次运行可能会重新创建服务,但后续运行不会。

© www.soinside.com 2019 - 2024. All rights reserved.