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.