我正在尝试通过 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.
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 的第一次运行可能会重新创建服务,但后续运行不会。