<p>So far I have 2 directories:</p>

<p><code>aws/</code>
  <code>k8s/</code></p>

<p>Inside <code>aws/</code> are <code>.tf</code> files describing a VPC, networking, security groups, IAM roles, EKS cluster, EKS node group, and a few EFS mounts. These are all using the AWS provider, the state in stored in S3.</p>

<p>Then in <code>k8s/</code> I'm then using the Kubernetes provider and creating Kubernetes resources inside the EKS cluster I created. This state is stored in the same S3 bucket in a different state file.</p>

<p>I'm having trouble figuring out how to mount the EFS mounts as Persistent Volumes to my pods.</p>

<p>I've found docs describing using an efs-provisioner pod to do this. See <a href="https://aws.amazon.com/premiumsupport/knowledge-center/eks-pods-efs/" rel="noreferrer">How do I use EFS with EKS?</a>. </p>

<p>In more recent EKS docs they now say to use <a href="https://docs.aws.amazon.com/eks/latest/userguide/efs-csi.html" rel="noreferrer">Amazon EFS CSI Driver</a>. The first step is to do a <code>kubectl apply</code> of the following file.</p>

<pre><code>apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
images:
- name: amazon/aws-efs-csi-driver
  newName: 602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/aws-efs-csi-driver
  newTag: v0.2.0
- name: quay.io/k8scsi/livenessprobe
  newName: 602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/csi-liveness-probe
  newTag: v1.1.0
- name: quay.io/k8scsi/csi-node-driver-registrar
  newName: 602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/csi-node-driver-registrar
  newTag: v1.1.0
</code></pre>

<p>Does anyone know how I would do this in Terraform? Or how in general to mount EFS file shares as PVs to an EKS cluster?</p>

<p>@BMW had it right, I was able to get this all into Terraform.</p>

<p>In the <code>aws/</code> directory I created all my AWS resources, VPC, EKS, workers, etc. and EFS mounts.</p>

<pre><code>resource "aws_efs_file_system" "example" {
  creation_token = "${var.cluster-name}-example"

  tags = {
    Name = "${var.cluster-name}-example"
  }
}

resource "aws_efs_mount_target" "example" {
  count = 2
  file_system_id = aws_efs_file_system.example.id
  subnet_id = aws_subnet.this.*.id[count.index]
  security_groups = [aws_security_group.eks-cluster.id]
}
</code></pre>

<p>I also export the EFS file system IDs from the AWS provider plan.</p>

<pre><code>output "efs_example_fsid" {
  value = aws_efs_file_system.example.id
}
</code></pre>

<p><strong>After the EKS cluster is created I had to manually install the EFS CSI driver into the cluster before continuing.</strong></p>

<p>Then in the <code>k8s/</code> directory I reference the <code>aws/</code> state file so I can use the EFS file system IDs in the PV creation.</p>

<pre><code>data "terraform_remote_state" "remote" {
  backend = "s3"
  config = {
    bucket = "example-s3-terraform"
    key    = "aws-provider.tfstate"
    region = "us-east-1"
  }
}
</code></pre>

<p>Then created the Persistent Volumes using the Kubernetes provider.</p>

<pre><code>resource "kubernetes_persistent_volume" "example" {
  metadata {
    name = "example-efs-pv"
  }
  spec {
    storage_class_name = "efs-sc"
    persistent_volume_reclaim_policy = "Retain"
    capacity = {
      storage = "2Gi"
    }
    access_modes = ["ReadWriteMany"]
    persistent_volume_source {
      nfs {
        path = "/"
        server = data.terraform_remote_state.remote.outputs.efs_example_fsid
      }
    }
  }
}
</code></pre>
