Home > Blockchain >  ECS Fargate Tasks stuck in pending when mounting EFS via Terraform
ECS Fargate Tasks stuck in pending when mounting EFS via Terraform

Time:06-03

My ECS Fargate Tasks get stuck in pending when mounting EFS in Terraform. I have mount points in both of the subnets my cluster is in and I have a sec group for the mount point on 2049 that allows the app’s sec group in. I guess it could be a role or IAM issue but I am unsure of the best configuration and am quite new to AWS and Terraform. I thank you immensely for reviewing my question and offering assistance.

EFS File

# 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
  ]
}

Sec Groups and Task Def

//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"
}

CodePudding user response:

You aren't currently using the access points you are creating. You are missing the access point info in the ECS task's volume configuration. Change the volume configuration in the task definition to the following:

  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"
      }
    }
  }

Also, your EFS policy is not going to work. You are currently only allowing access to your EFS system if aws:secureTransport is false. That means you are denying all requests to access your file system, if the request is secure. That's almost certainly the opposite of what you want. The EFS policy should have an Effect of Deny with that condition, not Allow.

Finally, the IAM role you are assigning to your ECS task: arn:aws:iam::692869463706:role/ecsTaskExecutionRole needs to have the appropriate EFS permissions added to it (elasticfilesystem:ClientMount, elasticfilesystem:ClientWrite, and/or elasticfilesystem:ClientRootAccess), if it doesn't have them already.

  • Related