通过 Terraform 安装 EFS 时,ECS Fargate 任务卡在挂起状态

ECS Fargate Tasks stuck in pending when mounting EFS via Terraform

在 Terraform 中安装 EFS 时,我的 ECS Fargate 任务卡在挂起状态。我在我的集​​群所在的两个子网中都有挂载点,并且我在 2049 上有一个用于挂载点的 sec 组,它允许应用程序的 sec 组进入。我想这可能是角色或 IAM 问题,但我不确定最好的配置并且对 AWS 和 Terraform 很陌生。非常感谢您审阅我的问题并提供帮助。

EFS 文件

# Creating Amazon EFS File system
resource "aws_efs_file_system" "myfilesystem" {
  lifecycle_policy {
    transition_to_ia = "AFTER_30_DAYS"
  }
}

# Creating the EFS access point for AWS EFS File system
resource "aws_efs_access_point" "test" {
  file_system_id = aws_efs_file_system.myfilesystem.id
}
# Creating the AWS EFS System policy to transition files into and out of the file system.
resource "aws_efs_file_system_policy" "policy" {
  file_system_id = aws_efs_file_system.myfilesystem.id
  policy = <<POLICY
{
    "Version": "2012-10-17",
    "Id": "Policy01",
    "Statement": [
        {
            "Sid": "Statement",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Resource": "${aws_efs_file_system.myfilesystem.arn}",
            "Action": [
                "elasticfilesystem:ClientMount",
                "elasticfilesystem:ClientRootAccess",
                "elasticfilesystem:ClientWrite"
            ],
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}
POLICY
}

# AWS EFS Mount point uses File system ID to launch.
resource "aws_efs_mount_target" "alpha" {
  file_system_id = aws_efs_file_system.myfilesystem.id
  subnet_id      = "subnet-09469abaeaf483de5"
  security_groups = [aws_security_group.efs.id]

  depends_on = [
    aws_security_group.efs
  ]
}

resource "aws_efs_mount_target" "beta" {
  file_system_id = aws_efs_file_system.myfilesystem.id
  subnet_id      = "subnet-04903e6b225a67aeb"
  security_groups = [aws_security_group.efs.id]

  depends_on = [
    aws_security_group.efs
  ]
}

安全组和任务定义

//Grafana Application Security Group
resource "aws_security_group" "grafana" {
  name        = "grafana"
  description = "Grafana Application Security Group"
  vpc_id      = var.vpc_id

  ingress {
    description = "Allows the load balancer to access Grafana"
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    security_groups = [aws_security_group.grafana-lb-sec.id]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "grafana"
  }

//EFS Mount Point Security Group that Allows Traffic from ECS to EFS
resource "aws_security_group" "efs" {
  name        = "efs-sec-group"
  description = "EFS Security Group"
  vpc_id      = var.vpc_id

  ingress {
    description = "Allows ECS to access EFS"
    from_port   = 2049
    to_port     = 2049
    protocol    = "tcp"
    security_groups = [aws_security_group.grafana.id]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "fargate-grafana"
  }

  depends_on = [
    aws_security_group.grafana
  ]
}

//ECS Cluster
resource "aws_ecs_cluster" "grafana" {
  name = "grafana"
}

//Task Definition
resource "aws_ecs_task_definition" "grafana" {
  family                   = "grafana"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = "512"
  memory                   = "1024"
  task_role_arn = "arn:aws:iam::692869463706:role/ecsTaskExecutionRole"

  container_definitions = <<DEFINITION
[
  {
      "memory": 128,
      "cpu": 10,
      "portMappings": [
          {
              "hostPort": 3000,
              "containerPort": 3000,
              "protocol": "tcp"
          }
      ],
      "essential": true,
      "mountPoints": [
          {
              "containerPath": "/var/lib/grafana",
              "sourceVolume": "efs-html",
              "readOnly": null
          }
      ],
      "name": "grafana",
      "image": "grafana/grafana:latest"
  }
]
DEFINITION

  volume {
    name = "efs-html"
    efs_volume_configuration {
      file_system_id = aws_efs_file_system.myfilesystem.id
      root_directory = "/"
      transit_encryption      = "ENABLED"
      transit_encryption_port = 2999
    }
  }
}

//ECS Service
resource "aws_ecs_service" "grafana" {
  name                              = "grafana"
  cluster                           = aws_ecs_cluster.grafana.id
  task_definition                   = aws_ecs_task_definition.grafana.arn
  desired_count                     = 1
  health_check_grace_period_seconds = 300
  network_configuration {
    subnets          = var.subnets
    security_groups  = [aws_security_group.grafana.id]
    assign_public_ip = true
  }
  load_balancer {
    target_group_arn = aws_lb_target_group.grafana-test-tg.arn
    container_name   = "grafana"
    container_port   = 3000
  }
  launch_type = "FARGATE"
  platform_version = "1.4.0"
}

您目前没有使用您正在创建的接入点。您在 ECS 任务的卷配置中缺少访问点信息。将任务定义中的卷配置更改为以下内容:

  volume {
    name = "efs-html"
    efs_volume_configuration {
      file_system_id = aws_efs_file_system.myfilesystem.id
      root_directory = "/"
      transit_encryption      = "ENABLED"
      transit_encryption_port = 2999

      authorization_config {
        access_point_id = aws_efs_access_point.test.id
        iam             = "ENABLED"
      }
    }
  }

此外,您的 EFS 策略将不起作用。如果 aws:secureTransportfalse,您目前只允许访问您的 EFS 系统。这意味着如果请求是安全的,您将拒绝所有访问文件系统的请求。这几乎肯定与您想要的相反。在该条件下,EFS 策略的 Effect 应该是 Deny,而不是 Allow

最后,您分配给 ECS 任务的 IAM 角色:arn:aws:iam::692869463706:role/ecsTaskExecutionRole 需要添加适当的 EFS 权限(elasticfilesystem:ClientMountelasticfilesystem:ClientWrite、 and/or elasticfilesystem:ClientRootAccess),如果还没有。