EFS volume bind auto detaching/reattaching 在每个“terraform apply”上用于 ECS 任务定义
EFS volume bind auto detaching/reattaching on every `terraform apply` for ECS task definition
我目前正在使用 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 配置?
如果您 apply
您的 TF 配置,您应该会看到 实际上没有执行任何更改。如果您查看 TF 文档中的 efs_volume_configuration,您会看到它有很多属性。其中一些将是 default,例如您未指定的 root_directory
。 TF 可能需要在您初始 apply
之后获取这些默认值。因此,稍后您可能会在随后的 terraform plan
.
中看到它们
建议:
首先,您应该遵循他们的标准做法,尽可能避免动态块,如果有少量项目,请不要使用它。最后一段供参考 https://www.terraform.io/docs/language/expressions/dynamic-blocks.html .
解决方案1:
从@marcin 的回答中获取部分想法,在文档中似乎默认挂载点是 /
,因此将 2 个不同 EFS 卷的挂载点更改为 /vol_a
和 [=12] =],因为在 /
.
处存在挂载点竞争条件
解决方案2:
不使用 dynamic
语言表达式重写 Terraform 配置。
扩展上面的建议,对两者都使用 fs-xxxxxxxx
是非常模棱两可的,或者你可以为第二个 EFS 卷 ID 提到 fs-yyyyyyyy
。它们不是要审查的 IP 地址,无法在您的 VPC 之外访问。放松一下。
我目前正在使用 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 配置?
如果您 apply
您的 TF 配置,您应该会看到 实际上没有执行任何更改。如果您查看 TF 文档中的 efs_volume_configuration,您会看到它有很多属性。其中一些将是 default,例如您未指定的 root_directory
。 TF 可能需要在您初始 apply
之后获取这些默认值。因此,稍后您可能会在随后的 terraform plan
.
建议: 首先,您应该遵循他们的标准做法,尽可能避免动态块,如果有少量项目,请不要使用它。最后一段供参考 https://www.terraform.io/docs/language/expressions/dynamic-blocks.html .
解决方案1:
从@marcin 的回答中获取部分想法,在文档中似乎默认挂载点是 /
,因此将 2 个不同 EFS 卷的挂载点更改为 /vol_a
和 [=12] =],因为在 /
.
解决方案2:
不使用 dynamic
语言表达式重写 Terraform 配置。
扩展上面的建议,对两者都使用 fs-xxxxxxxx
是非常模棱两可的,或者你可以为第二个 EFS 卷 ID 提到 fs-yyyyyyyy
。它们不是要审查的 IP 地址,无法在您的 VPC 之外访问。放松一下。