EFS 卷绑定在 ECS 任务定义的每个“terraform apply”上自动分离/重新附加
Posted
技术标签:
【中文标题】EFS 卷绑定在 ECS 任务定义的每个“terraform apply”上自动分离/重新附加【英文标题】:EFS volume bind auto detaching/reattaching on every `terraform apply` for ECS task definition 【发布时间】:2021-11-05 06:02:26 【问题描述】:我目前正在使用 AWS ECS 进行服务部署。对于共享卷,我正在绑定一些 EFS 卷。
这是我的任务定义:
resource "aws_ecs_task_definition" "ecs-fargate"
family = var.ecs_task_definition_name
container_definitions = var.container_definitions
requires_compatibilities = ["FARGATE"]
network_mode = "awsvpc"
cpu = var.ecs_task_cpu
memory = var.ecs_task_memory
execution_role_arn = var.ecs_task_execution_role_arn
task_role_arn = var.ecs_task_role_arn
dynamic "volume"
for_each = var.volumes
content
name = volume.value["name"]
efs_volume_configuration
file_system_id = volume.value["file_system_id"]
var "volumes"
default = [
name = "vol1"
file_system_id = "fs-xxxxxxxx"
,
name = "vol2"
file_system_id = "fs-xxxxxxxx"
]
上面的 Terraform 代码也可以正常工作。
但是当我每次都执行terraform apply
时,任务定义会先分离 EFS 卷,然后再次重新附加相同的卷。这是问题的截图:
- volume
- name = "vol1" -> null
- efs_volume_configuration
- file_system_id = "fs-xxxxxxx" -> null
- root_directory = "/" -> null
+ volume
+ name = "vol1"
+ efs_volume_configuration
+ file_system_id = "fs-xxxxxx"
+ root_directory = "/"
对于上述问题,我是否在此处遗漏了一些额外的 Terraform 配置?
【问题讨论】:
每次运行的文件系统 ID 是否完全相同?您不需要对此进行审查,但这样做会给您的问题增加一些歧义。 嗨@ydaetskcoR,我已经检查并确认它们在每次申请时都是相同的。 【参考方案1】:如果您apply
TF 配置,您应该会看到实际上没有执行任何更改。如果您检查 TF 文档中的 efs_volume_configuration,您会看到它具有许多属性。其中一些将是默认,例如您未指定的root_directory
。在您最初的apply
之后,TF 可能需要获取这些默认值。因此,稍后您可能会在随后的terraform plan
中看到它们。
【讨论】:
【参考方案2】:建议: 首先,您应该遵循他们尽可能避免使用动态块的标准做法,如果项目很少,请不要使用它。最后一段供参考https://www.terraform.io/docs/language/expressions/dynamic-blocks.html。
解决方案1:
从@marcin 的回答中获取部分想法,文档中的默认挂载点似乎是/
,因此将2 个不同EFS 卷的挂载点更改为/vol_a
和/vol_b
,因为有比赛/
的挂载点条件。
解决方案 2:
在不使用dynamic
语言表达式的情况下重写 Terraform 配置。
扩展上面的建议,两者都使用fs-xxxxxxxx
是非常模棱两可的,或者您可以提到fs-yyyyyyyy
作为第二个EFS 卷ID。它们不是要审查的 IP 地址,并且无法在您的 VPC 之外访问。所以放松吧。
【讨论】:
以上是关于EFS 卷绑定在 ECS 任务定义的每个“terraform apply”上自动分离/重新附加的主要内容,如果未能解决你的问题,请参考以下文章
在 AWS ECS 中将带有卷参数的 docker 容器作为任务定义或服务运行