提供从 ECS 任务对 EFS 的访问

发布于 2025-01-11 07:33:41 字数 4722 浏览 0 评论 0原文

我正在努力获取 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦醒时光 2025-01-18 07:33:41

遇到这个问题,这就是我解决的方法:

  1. aws_ecs_service 上的 platform_version = "1.4.0",它可能不再相关,但在这篇博文中我用作起点https://medium.com /@ilia.lazebnik/attaching-an-efs-file-system-to-an-ecs-task-7bd15b76a6ef
  2. 确保aws_efs_mount_targetsubnet_idsecurity_groups 设置为服务使用的相同值。由于我对多个可用区域使用多个子网,因此我为每个可用区域创建了挂载目标。
  3. 添加了标准 EFS 端口 2049 到 ingress,否则挂载操作会因超时错误而失败。

Run into this problem, this is what I did to resolve:

  1. platform_version = "1.4.0" on the aws_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-7bd15b76a6ef
  2. Made sure aws_efs_mount_target has subnet_id and security_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.
  3. Added standard EFS port 2049 to ingress as without that mount operation was failing with timeout error.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文