title: Mount local directory to AWS ECS Fargate Container
body: <p><strong>Goal</strong></p>
  <p>The goal is to mount a local version of a Github repository to an ECS Fargate container.</p>
  <p><strong>Background</strong></p>
  <p>Local Machine: MacOs Catalina v10.15.7</p>
  <p>The container is configured to use the <a href="https://aws.amazon.com/blogs/containers/new-using-amazon-ecs-exec-access-your-containers-fargate-ec2/" rel="nofollow noreferrer">ECS Exec</a> functionality so that IAM users can interactively run integration tests via the ECS Fargate container. The ECS service isn't constraint to using Fargate and can use EC2 if needed to solve this problem.</p>
  <p>Here's the associated VPC configurations:</p>
  <pre><code>module &quot;vpc&quot; {
    source = &quot;terraform-aws-modules/vpc/aws&quot;
  
    name = local.mut_id
    cidr = &quot;10.0.0.0/16&quot;
    azs  = [&quot;us-west-2a&quot;, &quot;us-west-2b&quot;, &quot;us-west-2c&quot;, &quot;us-west-2d&quot;]
    enable_dns_hostnames = true
  
    public_subnets = local.public_subnets
    database_subnets           = local.database_subnets
  }
  </code></pre>
  <p><strong>Attempts</strong></p>
  <ol>
  <li>Mount an AWS EFS to the local machine directory then mount EFS onto the ECS container. As a prerequisite to mounting to the EFS, I created a client VPN endpoint associated within the VPC subnet that the ECS and EFS resources are hosted in.</li>
  </ol>
  <p>EFS configurations:</p>
  <pre><code>resource &quot;aws_efs_file_system&quot; &quot;testing&quot; {
    creation_token = local.mut_id
  }
  
  resource &quot;aws_efs_mount_target&quot; &quot;testing&quot; {
    file_system_id = aws_efs_file_system.testing.id
    subnet_id      = module.vpc.public_subnets[0]
    security_groups = [aws_security_group.testing_efs.id]
  }
  
  data &quot;aws_iam_policy_document&quot; &quot;testing_efs&quot; {
    statement {
      effect = &quot;Allow&quot;
      actions = [
        &quot;elasticfilesystem:ClientMount&quot;,
        &quot;elasticfilesystem:ClientWrite&quot;,
        &quot;elasticfilesystem:ClientRootAccess&quot;
      ]
      principals {
        type        = &quot;AWS&quot;
        identifiers = [data.aws_caller_identity.current.arn]
      }
    }
  }
  
  resource &quot;aws_security_group&quot; &quot;testing_efs&quot; {
    name        = &quot;${local.mut_id}-integration-testing-efs&quot;
    description = &quot;Allows inbound access from testing container&quot;
    vpc_id      = module.vpc.vpc_id
  
    ingress {
      description = &quot;Allows EFS mount point access from testing container&quot;
      from_port   = 2049
      to_port     = 2049
      protocol    = &quot;tcp&quot;
      cidr_blocks = [&quot;${chomp(data.http.my_ip.body)}/32&quot;]
    }
  }
  
  data &quot;http&quot; &quot;my_ip&quot; {
    url = &quot;http://ipv4.icanhazip.com&quot;
  }
  
  </code></pre>
  <p>VPN config:</p>
  <pre><code>module &quot;testing_vpn&quot; {
    source  = &quot;DNXLabs/client-vpn/aws&quot;
    version = &quot;0.3.0&quot;
    cidr = &quot;172.31.0.0/16&quot;
    name = local.mut_id
    vpc_id                        = module.vpc.vpc_id
    subnet_ids = module.vpc.public_subnets
    security_group_id = aws_security_group.testing_vpn.id
    split_tunnel = true
  }
  
  resource &quot;aws_security_group&quot; &quot;testing_vpn&quot; {
    name        = &quot;${local.mut_id}-integration-testing-vpn&quot;
    description = &quot;Allows inbound VPN connection&quot;
    vpc_id      = module.vpc.vpc_id
  
    ingress {
      description = &quot;Inbound VPN connection&quot;
      from_port = 443
      protocol = &quot;UDP&quot;
      to_port = 443
      cidr_blocks = [&quot;0.0.0.0/0&quot;]
    }
  
    egress {
      from_port = 0
      protocol = &quot;-1&quot;
      to_port = 0
      cidr_blocks = [&quot;0.0.0.0/0&quot;]
    }
  }
  </code></pre>
  <p>Here's the related commands used to start the VPN and mount the EFS to the local directory:</p>
  <pre><code>    client_cfg=$(aws ec2 export-client-vpn-client-configuration --client-vpn-endpoint-id &quot;$vpn_endpoint&quot; --output text)
  
      client_cfg=$(cat &lt;&lt;EOT &gt;&gt; $PWD/client.ovpn
  $client_cfg
  &lt;cert&gt;
  $vpn_cert
  &lt;/cert&gt;
  
  &lt;key&gt;
  $vpn_private_key
  &lt;/key&gt;
  EOT
  )
      echo &quot;Running OpenVPN&quot;
      sudo openvpn --config &quot;$PWD/client.ovpn&quot; --daemon
  
      echo &quot;Mounting to EFS: $local_mount&quot;
      mount -t nfs -o nfsvers=4,rsize=8192,wsize=8192,hard,timeo=600,retrans=2,noresvport &quot;$efs_dns&quot;:/ &quot;$local_mount&quot;
  </code></pre>
  <p>The command: <code>mount -t nfs -o nfsvers=4,rsize=8192,wsize=8192,hard,timeo=600,retrans=2,noresvport &quot;$efs_dns&quot;:/ &quot;$local_mount&quot;</code> results in the error even though the directory exists:</p>
  <pre><code>mount: realpath &lt;$local_mount&gt;: No such file or directory
  </code></pre>
  <p>I've also tried running <code>sudo nfsd restart</code> and using the IP address of the EFS mount target like so: <code>mount -t nfs -o nfsvers=4,rsize=8192,wsize=8192,hard,timeo=600,retrans=2,noresvport x.x.x.x:/ &quot;$local_mount&quot;</code> which results in a timeout error.</p>
  <p>OpenVPN version: 2.5.5</p>
  <p><code>rpcinfo -p</code>:</p>
  <pre><code>    100000    2   udp    111  rpcbind
      100000    3   udp    111  rpcbind
      100000    4   udp    111  rpcbind
      100000    2   tcp    111  rpcbind
      100000    3   tcp    111  rpcbind
      100000    4   tcp    111  rpcbind
      100024    1   udp   1011  status
      100024    1   tcp   1021  status
      100021    0   udp    946  nlockmgr
      100021    1   udp    946  nlockmgr
      100021    3   udp    946  nlockmgr
      100021    4   udp    946  nlockmgr
      100021    0   tcp   1017  nlockmgr
      100021    1   tcp   1017  nlockmgr
      100021    3   tcp   1017  nlockmgr
      100021    4   tcp   1017  nlockmgr
      100011    1   udp    648  rquotad
      100011    2   udp    648  rquotad
      100011    1   tcp    937  rquotad
      100011    2   tcp    937  rquotad
      100003    2   udp   2049  nfs
      100003    3   udp   2049  nfs
      100003    2   tcp   2049  nfs
      100003    3   tcp   2049  nfs
      100005    1   udp    928  mountd
      100005    3   udp    928  mountd
      100005    1   tcp    929  mountd
      100005    3   tcp    929  mountd
  </code></pre>