dockerterraformdockerfileamazon-ecsamazon-efs

Cannot mount EFS to ECS fargate with WooCommerce Dockerfile


I have spent a lot of time trying to do this, but I have to give up. I am not able to mount AWS-EFS from AWS-ECS WooCommerce Dockerfile. It is something related to permissions, such as UID or GID. I know that using UID and GID 0 is dangerous that's why I am looking for a safe solution.

My example error is:

tar: ./wp-includes: Cannot mkdir: Permission denied

My Dockerfile from official repo: https://github.com/docker-library/wordpress/tree/940a0d35951a0917622c35acc92b38b1db3c730f/latest/php8.2/apache

My ECR task definition in terraform:

# ECS Task Definition
resource "aws_ecs_task_definition" "woocommerce_task" {
  depends_on = [ aws_efs_access_point.wp_content ]
  family                   = var.task_family
  network_mode             = var.network_mode
  requires_compatibilities = var.task_compatibilities
  cpu                      = var.task_cpu
  memory                   = var.task_memory
  execution_role_arn       = aws_iam_role.ecs_execution_role.arn
  task_role_arn           = aws_iam_role.ecs_task_role.arn
  container_definitions = jsonencode([
    {
      name      = var.container_name,
      image     = "${var.ecr_repository_url}:${var.container_image_tag}",
      # user = "33:33",
      # user = "0:0",
      essential = true,
      mountPoints: [{
        "sourceVolume": "wp-content",
        "containerPath": "/var/www/html/"
        # "containerPath": "/var/www/html/wp-content/"
      }],
      environment = [
        {
          name  = "WORDPRESS_DB_NAME",
          value = var.db_name
        },
        {
          name  = "WORDPRESS_DB_HOST",
          value = "${var.db_host}:3306"
        },
        {
          name  = "WORDPRESS_DB_USER",
          value = "XXXX"
        },
        {
          name  = "WORDPRESS_DB_PASSWORD",
          value = "XXXX"
        },
        {
          name  = "TAR_OPTIONS",
          value = "--no-same-owner"
        },
      ],
      portMappings = [{
        containerPort = var.container_port,
        hostPort      = var.container_port,
        protocol      = "tcp"
      }],
      logConfiguration = {
        logDriver = "awslogs",
        options = {
          "awslogs-group"         = aws_cloudwatch_log_group.ecs_logs.name,
          "awslogs-region"        = var.aws_region,
          "awslogs-stream-prefix" = "ecs"
        }
      }
    }
  ])

My EFS resource:

resource "aws_efs_access_point" "wp_content" {
  file_system_id = aws_efs_file_system.wp_content.id

  posix_user {
    gid = "33"
    uid = "33"
    # gid = "1000"
    # uid = "1000"
    # gid = "0"
    # uid = "0"
  }

  root_directory {
    # path = "/wp-content"
    path = "/"
    creation_info {
    #   owner_gid   = "0"
    #   owner_uid   = "0"
      owner_gid   = "33"
      owner_uid   = "33"
    #   owner_gid   = "1000"
    #   owner_uid   = "1000"
    #   permissions = "755"
      permissions = "777"
    }
  }
}

Can you help me :) ?


Solution

  • Your aws_ecs_task_definition resource appears to be completely missing the volume mapping attribute, documented here. It would look something like:

    resource "aws_ecs_task_definition" "woocommerce_task" {
      # All the other stuff in your question
    
      volume {
        name = "wp-content"
        efs_volume_configuration {
          file_system_id     = aws_efs_file_system.wp_content.id
    
          authorization_config {
            access_point_id = aws_efs_access_point.wp_content.id
          }
        }
      }
    }