提供从 ECS 任务对 EFS 的访问
我正在努力获取 ECS 任务来查看 EFS 卷。 terraform 配置为:
EFS DEFINITION
resource "aws_efs_file_system" "persistent" {
encrypted = true
}
resource "aws_efs_access_point" "access" {
file_system_id = aws_efs_file_system.persistent.id
}
resource "aws_efs_mount_target" "mount" {
for_each = {for net in aws_subnet.private : net.id => {id = net.id}}
file_system_id = aws_efs_file_system.persistent.id
subnet_id = each.value.id
security_groups = [aws_security_group.efs.id]
}
任务定义
resource "aws_ecs_task_definition" "app" {
family = "backend-app-task"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.ecs_task_role.arn
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.fargate_cpu
memory = var.fargate_memory
container_definitions = data.template_file.backendapp.rendered
volume {
name = "persistent"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/opt/data"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
authorization_config {
access_point_id = aws_efs_access_point.access.id
iam = "ENABLED"
}
}
}
}
安全组
resource "aws_security_group" "efs" {
name = "efs-security-group"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = 2999
to_port = 2999
security_groups = [aws_security_group.ecs_tasks.id]
cidr_blocks = [for net in aws_subnet.private : net.cidr_block]
}
}
任务角色
resource "aws_iam_role" "ecs_task_role" {
name = "ecsTaskRole"
assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role_base.json
managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess","arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", aws_iam_policy.ecs_exec_policy.arn]
}
据我了解 AWS 文档,IAM角色应该具有访问权限,并且安全组应该传递流量,但错误表明该任务无法解析 EFS 实例。
错误信息是:
ResourceInitializationError: failed to invoke EFS utils commands to set up EFS volumes: stderr: Failed to resolve "fs-0000000000000.efs.eu-west-2.amazonaws.com" - check that your file system ID is correct.
我已经在控制台中手动确认了EFS id是正确的,所以我只能得出结论,由于网络/权限问题而无法解决。
- 编辑 - ECS 服务定义
resource "aws_ecs_service" "main" {
name = "backendservice"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = var.app_count
launch_type = "FARGATE"
enable_execute_command = true
network_configuration {
security_groups = [aws_security_group.ecs_tasks.id]
subnets = aws_subnet.private.*.id
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_alb_target_group.app.id
container_name = "server"
container_port = var.app_port
}
depends_on = [aws_alb_listener.backend]
}
ECS 任务安全组
resource "aws_security_group" "ecs_tasks" {
name = "backend-ecs-tasks-security-group"
description = "allow inbound access from the ALB only"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = var.app_port
to_port = var.app_port
security_groups = [aws_security_group.lb.id]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
VPC 定义(减去互联网网关)
data "aws_availability_zones" "available" {
}
resource "aws_vpc" "main" {
cidr_block = "172.17.0.0/16"
}
# Create var.az_count private subnets, each in a different AZ
resource "aws_subnet" "private" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.main.id
}
resource "aws_subnet" "public" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, var.az_count + count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.main.id
map_public_ip_on_launch = true
}
编辑
原来容器模板中缺少 mountPoints 块。我现在已经添加了,但结果是一样的。
I am struggling to get an ECS task to be able to see an EFS volume.
The terraform config is:
EFS DEFINITION
resource "aws_efs_file_system" "persistent" {
encrypted = true
}
resource "aws_efs_access_point" "access" {
file_system_id = aws_efs_file_system.persistent.id
}
resource "aws_efs_mount_target" "mount" {
for_each = {for net in aws_subnet.private : net.id => {id = net.id}}
file_system_id = aws_efs_file_system.persistent.id
subnet_id = each.value.id
security_groups = [aws_security_group.efs.id]
}
TASK DEFINITION
resource "aws_ecs_task_definition" "app" {
family = "backend-app-task"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
task_role_arn = aws_iam_role.ecs_task_role.arn
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = var.fargate_cpu
memory = var.fargate_memory
container_definitions = data.template_file.backendapp.rendered
volume {
name = "persistent"
efs_volume_configuration {
file_system_id = aws_efs_file_system.persistent.id
root_directory = "/opt/data"
transit_encryption = "ENABLED"
transit_encryption_port = 2999
authorization_config {
access_point_id = aws_efs_access_point.access.id
iam = "ENABLED"
}
}
}
}
SECURITY GROUP
resource "aws_security_group" "efs" {
name = "efs-security-group"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = 2999
to_port = 2999
security_groups = [aws_security_group.ecs_tasks.id]
cidr_blocks = [for net in aws_subnet.private : net.cidr_block]
}
}
TASK ROLE
resource "aws_iam_role" "ecs_task_role" {
name = "ecsTaskRole"
assume_role_policy = data.aws_iam_policy_document.ecs_task_execution_role_base.json
managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonElasticFileSystemFullAccess","arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy", aws_iam_policy.ecs_exec_policy.arn]
}
As I understand the AWS docs, the IAM role should have access, and the security group should be passing traffic, but the error suggests that the task cannot resolve the EFS instance.
The error message is:
ResourceInitializationError: failed to invoke EFS utils commands to set up EFS volumes: stderr: Failed to resolve "fs-0000000000000.efs.eu-west-2.amazonaws.com" - check that your file system ID is correct.
I've manually confirmed in the console that the EFS id is correct, so I can only conclude that it cannot resolve due to a network/permissions issue.
-- EDIT --
ECS SERVICE DEFINITION
resource "aws_ecs_service" "main" {
name = "backendservice"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = var.app_count
launch_type = "FARGATE"
enable_execute_command = true
network_configuration {
security_groups = [aws_security_group.ecs_tasks.id]
subnets = aws_subnet.private.*.id
assign_public_ip = true
}
load_balancer {
target_group_arn = aws_alb_target_group.app.id
container_name = "server"
container_port = var.app_port
}
depends_on = [aws_alb_listener.backend]
}
ECS TASK SECURITY GROUP
resource "aws_security_group" "ecs_tasks" {
name = "backend-ecs-tasks-security-group"
description = "allow inbound access from the ALB only"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = var.app_port
to_port = var.app_port
security_groups = [aws_security_group.lb.id]
}
egress {
protocol = "-1"
from_port = 0
to_port = 0
cidr_blocks = ["0.0.0.0/0"]
}
}
VPC DEFINITION (minus internet gateway)
data "aws_availability_zones" "available" {
}
resource "aws_vpc" "main" {
cidr_block = "172.17.0.0/16"
}
# Create var.az_count private subnets, each in a different AZ
resource "aws_subnet" "private" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.main.id
}
resource "aws_subnet" "public" {
count = var.az_count
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, var.az_count + count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
vpc_id = aws_vpc.main.id
map_public_ip_on_launch = true
}
EDIT
It turned out the mountPoints block was missing from the container template. I have now added it, but the outcome is the same.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
遇到这个问题,这就是我解决的方法:
aws_ecs_service
上的platform_version = "1.4.0"
,它可能不再相关,但在这篇博文中我用作起点https://medium.com /@ilia.lazebnik/attaching-an-efs-file-system-to-an-ecs-task-7bd15b76a6efaws_efs_mount_target
将subnet_id
和security_groups
设置为服务使用的相同值。由于我对多个可用区域使用多个子网,因此我为每个可用区域创建了挂载目标。ingress
,否则挂载操作会因超时错误而失败。Run into this problem, this is what I did to resolve:
platform_version = "1.4.0"
on theaws_ecs_service
, its possible its no longer relevant but was in this blog post I used as a starting point https://medium.com/@ilia.lazebnik/attaching-an-efs-file-system-to-an-ecs-task-7bd15b76a6efaws_efs_mount_target
hassubnet_id
andsecurity_groups
set to same ones used by the service. Since I use multiple subnets for multiple availability zones I created mount target for each of them.ingress
as without that mount operation was failing with timeout error.