Self-hosted service
kubernetes-sigs/aws-efs-csi-driver avatar
kubernetes-sigs/aws-efs-csi-driver

Amazon EFS CSI Driver: persistent volumes for EFS and S3 on Kubernetes

CSI Driver for Amazon EFS https://aws.amazon.com/efs/

805 stars614 forksGoApache-2.0

At a glance

What is it?
The Amazon EFS CSI driver lets Kubernetes clusters running on AWS mount Amazon EFS and Amazon S3 file systems as persistent volumes, starting with driver version 3.0.0 or above. It covers static and dynamic provisioning, cross account mounts and per node AWS credentials, and it pays off for teams that want shared file storage without managing capacity.
Who is it for?
Adopt the Amazon EFS CSI driver when your pods on AWS need shared, elastic file storage that several workloads read and write at once, especially when the data already lives in EFS or S3 and the team does not want to manage capacity. Skip it if a single pod can live with a plain block volume, or if you need snapshot or expansion CSI calls, because the implemented interface list does not include them.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the EFS CSI driver replaces in a Kubernetes cluster

Amazon Elastic File System provides serverless, fully elastic file storage, so file data can be shared without provisioning or managing storage capacity and performance. On a Kubernetes cluster running on AWS, the driver makes that file system usable the same way a block volume is usable, as a persistent volume that a pod mounts. Since version `3.0.0` or above, the driver mounts both Amazon EFS file systems and Amazon S3 file systems.

The S3 side is the newer of the two. S3 Files is described as a shared file system that connects any AWS compute directly with data in Amazon S3, giving fast, direct access to S3 data as files with full file system semantics and low latency, and the data never leaves S3. For teams that have spent years accumulating objects in a bucket, that is the interesting part of this project, because file based applications, agents and teams can work with the same data through the file system tools they already depend on.

The driver is written in Go and implements the Container Storage Interface, so it plugs into Kubernetes through the standard CSI plumbing rather than through a vendor specific admission controller or in tree volume plugin. That is the practical difference from the older approach of running the mount helper on every node by hand: the driver packages the EFS utilities inside its own containers and manages the mount process itself.

Static and dynamic provisioning through access points

Both provisioning modes are supported, and the choice determines who creates the file system.

With static provisioning, the Amazon EFS file system or Amazon S3 file system is created manually first, and then it can be mounted inside a container as a persistent volume using the driver. Nothing is created on your behalf, which suits a shared file system that already exists and whose lifecycle is managed by another team.

With dynamic provisioning, a persistent volume claim triggers creation of a persistent volume. On creating a PVC, Kubernetes requests an Amazon EFS or Amazon S3 file system to create an access point in a file system, and that access point is what gets mounted for the PV. The access point is the unit of isolation here, and it is what allows several workloads to share one underlying file system while keeping their roots separate.

Mount options can be specified in the persistent volume for static provisioning or in the storage class for dynamic provisioning, which defines how the volume should be mounted. Because the same option surface exists in two places, teams with mixed provisioning styles tend to end up with divergent mount behaviour between their hand written PVs and their storage classes, and that difference is worth auditing before it reaches production.

The volumeHandle prefix split between EFS and S3

Here is the sharpest operational edge in the project, and it is a migration problem rather than a feature.

For static provisioning with an Amazon S3 file system, the `volumeHandle` in your PersistentVolume must include the `s3files:` prefix. Amazon EFS handles behave differently: they do not need a filesystem type prefix, and the driver accepts both the unprefixed and prefixed forms, emitting the unprefixed form for dynamically provisioned volumes so that handles stay usable by consumers that predate the typed format.

The wrinkle is history. Driver versions `v3.0.0` through `v3.4.2` emitted `efs:` prefixed handles instead. Because `spec.csi.volumeHandle` is immutable, a PersistentVolume provisioned by one of those versions keeps its prefix and has to be recreated to take the unprefixed form. Recreating a PV is not a rename, it means tearing down and re-establishing the volume binding, so teams carrying stateful workloads from an older driver should plan that work rather than discovering it during an upgrade.

The scale of that surface is bounded by the recent release history: v3.5.1 on 2026-09-28 and v3.5.2 on 2026-10-16, so the current line sits well past the affected range, and the fix has been available for some time.

Cross account mounts and the DNS dependency behind them

Amazon EFS file systems from different AWS accounts can be mounted from an Amazon EKS cluster, and the driver offers three provisioning modes for it.

The first is efs-utils DNS resolution, enabled with the `crossaccount=true` parameter. The second is a pinned availability zone mount target, selected with the `az` parameter. The third is a per node AZ to IP map, which the documentation presents as a way to get availability zone resilience without DNS prerequisites.

That third mode is the interesting one for anyone who has fought DNS from inside a VPC. Resolving a mount target by name is the simplest configuration, but it ties the mount to name resolution working from every node, and the per node map trades that convenience for a configuration file you have to keep correct as the cluster changes. A map that goes stale is worse than a DNS lookup that fails loudly, so treat the per node approach as an operational commitment rather than a free improvement.

The examples directory holds a cross account mount walkthrough and a separate parameters reference documents the cross account provisioning keys, and the README points at both, so the concrete configuration for each of the three modes is available even though the summary here is thin.

Encryption in transit by default, and where the driver stops

Amazon EFS and Amazon S3 file systems are mounted with encryption in transit enabled by default in the master branch version of the driver. This is worth checking against your own policy, because a default is not the same as a configuration you can point at in an audit. The wording is specific to the master branch, so a tagged release may not behave identically, and the release notes are the place to confirm which behaviour a given image carries.

The implemented CSI interface list tells you what the driver will and will not do. The controller service covers CreateVolume, DeleteVolume, ControllerGetCapabilities and ValidateVolumeCapabilities. The node service covers NodePublishVolume, NodeUnpublishVolume, NodeGetCapabilities, NodeGetInfo, NodeGetId and NodeGetVolumeStats. The identity service covers GetPluginInfo, GetPluginCapabilities and Probe. Snapshot calls and volume expansion calls are absent from that list, and a Kubernetes storage workflow that relies on either will not find the support it expects.

One operational warning is stated bluntly: do not install `amazon-efs-utils` directly on EKS worker nodes. The EFS CSI driver already packages `efs-utils` within its containers and manages the mount process, and installing the package at node level can cause unexpected mount behaviour. Node images that predate your move to the driver are the usual source of that mistake.

Installing the driver and checking the first mount

The project does not publish a single copy and paste install command in its overview. Installation is documented separately in the driver installation guide, and the repository ships a Helm chart alongside a deploy directory, so those are the two routes to check. The current chart release tracks the driver: `helm-chart-aws-efs-csi-driver-4.5.2` was published on 2026-10-16 alongside driver version `v3.5.2` on the same day.

Images ship in two registries, and the tag you pin should be the driver version rather than a moving channel:

bash
public.ecr.aws/efs-csi-driver/amazon/aws-efs-csi-driver:v3.5.2

The private EKS registry carries the same tag under your account and region, which is the form to use when your cluster pulls from a registry you control. The image is multiarch on ECR, and the build covers both amd64 and arm64 targets, so a mixed architecture cluster is handled by the same tag.

For the first real use, start with a static mount of a file system you already trust and check that the pod sees the expected content before touching provisioning. If the mount is backed by S3, the handle in the PersistentVolume needs the prefix:

bash
s3files:fs-01234567890abcdef0

If the pod starts but the mount behaves oddly, check the CloudWatch metrics that the mount helper publishes for mount status. The client includes a mount helper program that simplifies mounting Amazon EFS and Amazon S3 file systems and enables Amazon CloudWatch metrics to monitor mount status, which makes it the first place to look when a mount silently misbehaves.

Capacity that does not exist and version rules that do

Two details reward close reading.

The first is storage capacity. Amazon EFS and S3 Files are fully elastic and scalable file systems which automatically scale up or down based on usage, so there is no need to manage capacity. The actual storage capacity value in the persistent volume and persistent volume claim is a placeholder value that must be specified because Kubernetes requires it, but it is not actually used, and you can specify any valid value. This catches teams out in a specific way: a policy or a scheduler that reasons about requested capacity will see a number that means nothing, and a PVC requesting a large size for a large file will appear to reserve resources it never reserves. Pick a small consistent value and document that it carries no meaning.

The second is versioning. The driver follows semantic versioning, and the `MAJOR.MINOR.PATCH` rules after `v2.2.0` are explicit: significant breaking changes come as a MAJOR update, new features as a MINOR update, and bug or vulnerability fixes as a PATCH update. That is a clear contract for operators who gate upgrades on change type, and it is the reason the release notes matter here. The project also warns that the latest release version may not include the most recent code changes on the master branch, and points to the changelog for the corresponding version, so the master branch behaviour and the released image can differ.

The licence is Apache-2.0, the standard permissive grant used across Kubernetes SIG projects, and the repository carries the usual licence file and a THIRD-PARTY directory. The repository is not archived and the last push was on 2026-10-16, the same day as the v3.5.2 release, so the code is current.

Editorial conclusion

Adopt the Amazon EFS CSI driver when your pods on AWS need shared, elastic file storage that several workloads read and write at once, especially when the data already lives in EFS or S3 and the team does not want to manage capacity. Skip it if a single pod can live with a plain block volume, or if you need snapshot or expansion CSI calls, because the implemented interface list does not include them. Verify first that your cluster runs the driver version matching your Kubernetes release using the compatibility matrix, then read parameters.md for the mount options you intend to set, and confirm that your PersistentVolumes do not carry the efs: prefix written by versions v3.0.0 through v3.4.2 if you plan to migrate them.

Frequently asked questions

Which Kubernetes versions does the Amazon EFS CSI driver support?

The project publishes a compatibility matrix as part of its documentation set, alongside the parameters reference, installation guide, FIPS support page and FAQ. The go.mod file pins Kubernetes libraries at v0.33.2 and the Kubernetes dependency at v1.33.6, and the driver image is built with golang:1.25.5 in the Dockerfile.

Do I need to install amazon-efs-utils on EKS worker nodes?

No. The EFS CSI driver already packages efs-utils within its containers and manages the mount process, and installing amazon-efs-utils at the node level can cause unexpected mount behavior.

Can I mount an EFS file system that lives in another AWS account?

Yes, Amazon EFS file systems from different AWS accounts can be mounted from an Amazon EKS cluster. Three provisioning modes are offered: efs-utils DNS resolution with crossaccount=true, a pinned-AZ mount target through the az parameter, and a per-node AZ to IP map for availability zone resilience without DNS prerequisites.

Why does my EFS PersistentVolume have an efs: prefix on its volumeHandle?

Driver versions v3.0.0 through v3.4.2 emitted efs: prefixed handles, while current versions emit the un-prefixed form for dynamically provisioned volumes and accept both forms. Because spec.csi.volumeHandle is immutable, a PersistentVolume created by an affected version keeps its prefix and has to be recreated to take the un-prefixed form.

Does the storage size I request in a PersistentVolumeClaim limit my EFS usage?

No. EFS and S3 Files are fully elastic and scale automatically with usage, so the capacity value in the persistent volume and claim is a placeholder that Kubernetes requires but that the driver does not use. You can specify any valid value for the capacity.

Official sources

  1. Issues
  2. kubernetes-sigs/aws-efs-csi-driver on GitHub
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kubernetes-sigs-aws-efs-csi-driver.svg)](https://hysenlabs.com/projects/kubernetes-sigs-aws-efs-csi-driver)

Was this useful?