DirectorySecurity AdvisoriesPricing
Sign in
Directory
aws-efs-csi-driver logoHELM

aws-efs-csi-driver

Helm chart
Last changed
Request a free trial

Contact our team to test out this Helm chart and related images for free. Please also indicate any other images you would like to evaluate.

Overview
Chart tags
Default values
Chart metadata
Images

AWS EFS CSI Driver

Chainguard's redistribution of the AWS EFS CSI Driver Helm chart, pre-configured with hardened Chainguard Images.

Prerequisites

Authentication is required to access this chart and its images. First, authenticate with Chainguard and configure your environment:

chainctl auth login
chainctl auth configure-docker --pull-token --save
helm registry login cgr.dev

Create an image pull secret for the cluster:

kubectl create secret docker-registry cgr-pull-secret \
  --docker-server=cgr.dev \
  --docker-username="$(echo cgr.dev | docker-credential-cgr get | jq -r '.Username')" \
  --docker-password="$(echo cgr.dev | docker-credential-cgr get | jq -r '.Secret')" \
  --namespace kube-system

Installation

helm install aws-efs-csi-driver oci://cgr.dev/ORGANIZATION/charts/aws-efs-csi-driver \
  --namespace kube-system \
  --set imagePullSecrets[0].name=cgr-pull-secret

About This Chart

This is a redistribution of the upstream AWS EFS CSI Driver Helm chart. All upstream configuration options and documentation apply.

For full documentation, see: https://github.com/kubernetes-sigs/aws-efs-csi-driver

Chainguard Customizations

This chart provides an aws_mp_addon_parameters.json file that defines the IAM permissions required when deploying this product as an EKS Addon.

EKS add-on configuration values

Amazon EKS validates the --configuration-values of aws eks create-addon and aws eks update-addon against aws_mp_configuration_schema.json at the chart root. To list what a version accepts, run:

aws eks describe-addon-configuration \
  --addon-name chainguard_aws-efs-csi-driver-fips \
  --addon-version <version>

The schema accepts the settings of AWS's own aws-efs-csi-driver add-on for driver 3.5.2 (v3.5.2-eksbuild.1) in the same shape, except as listed below. So this schema rejects some values that AWS's add-on accepts, for example a volume backed by a Secret. Defaults come from this chart's values.yaml file, so some differ from AWS's.

The add-on's IAM permissions attach through EKS Pod Identity to the fixed service accounts efs-csi-controller-sa and efs-csi-node-sa.

What the schema narrows
  • The chart writes these strings into its manifests unquoted, so they reject line breaks and control characters and accept only their format: both priorityClassName settings (empty or a DNS subdomain), node.unmountTimeout (a Go duration), and node.kubeletPath (an absolute path with no .. element, which Kubernetes rejects in a hostPath volume).
  • The chart also writes node.efsUtilsConfOverrides and node.s3filesUtilsConfOverrides unquoted. So they reject a colon followed by a space or at the end, and a space followed by #, which would change the manifest's YAML. They also reject the keys that AWS's schema denies in any letter case, because the driver lowercases a key before it checks its own denylist. A key with a Kelvin sign (U+212A) in place of k, or a capital I with dot (U+0130) in place of i, is rejected too, because the driver lowercases them to those letters. The denied keys are dns_name_suffix, dns_name_format, stunnel_check_cert_hostname, stunnel_check_cert_validity, and stunnel_cafile. A region key, in any letter case, takes only a Region name such as us-east-1, because efs-utils builds the STS endpoint URL from it. The schema does not check the section:key=value form, so the driver still refuses a malformed value at startup.
  • In controller.env and node.env, AWS_DEFAULT_REGION and AWS_REGION are empty or a Region name of lowercase letters, digits, and hyphens, such as us-east-1. FIPS_ENABLED is empty, true, or false. None of them takes valueFrom. The driver writes AWS_DEFAULT_REGION and FIPS_ENABLED into efs-utils.conf and s3files-utils.conf as they are, so a line break could add the denied keys above. efs-utils reads AWS_REGION before AWS_DEFAULT_REGION and builds the STS endpoint URL from it.
  • controller.timeout takes a Go duration too. The chart quotes it today, and the format keeps it safe if a later chart drops the quote.
  • Counts in controller.podDisruptionBudget.maxUnavailable and minAvailable, in controller.rollingUpdate.maxUnavailable, and in both node.rollingUpdate counts are an integer from 0, or a percentage from 0% to 100%. controller.rollingUpdate.maxSurge is an integer from 0 or any percentage, such as 200%, because Kubernetes does not cap a Deployment's surge.
  • The chart writes these integers unquoted. Helm writes a number of 1,000,000 or more as 1e+06, and one of -1,000,000 or less as -1e+06, and neither is an integer. So they are at most 999999: controller.replicaCount, controller.workerThreads, node.maxInflightMountCalls, node.volumeAttachLimit, and the integer form of both controller.podDisruptionBudget counts. controller.replicaCount is also at least 0, as Kubernetes requires, and controller.workerThreads is at least 0, because csi-provisioner reads it as an unsigned integer. node.maxInflightMountCalls and node.volumeAttachLimit are from -999999 to 999999, so -1, the default in AWS's schema and the driver, still works.
  • AWS's schema accepts any object for the Kubernetes-shaped settings: affinity, probes, resources, environment variables, volumes, volume mounts, tolerations, topology spread constraints, rolling update, node selectors, pod labels, and pod annotations. This schema types each one as its Kubernetes object and rejects fields that Kubernetes does not define.
    • These objects also follow the Kubernetes API validation rules that one field decides, so most values that the API server would reject fail here instead of at install: required fields, enum values such as operators and taint effects, bounds such as weights from 1 to 100 and ports from 1 to 65535, the label key, label value, and quantity formats, the ConfigMap and Secret names and keys that environment variables read, node names in matchFields, a relative subPath and subPathExpr with no .. element, no .. element in hostPath.path, and the probe rules. A readiness or startup probe is empty or has exactly one handler, a liveness or startup probe's successThreshold is 1, and a readiness probe takes no terminationGracePeriodSeconds.
    • Four kinds of Kubernetes rule stay out, so a value can pass here and still fail at install:
      • rules where one field's allowed values depend on another's, such as a toleration's value with operator: Exists, both node.rollingUpdate counts non-zero, or both controller.rollingUpdate counts 0
      • rules across objects or list items, such as a volume mount that names no volume
      • required fields in an object that a chart default fills, because Helm merges the customer's object into that default: the liveness probes' httpGet.port, and nodeSelectorTerms in nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution, which gets minItems: 1 instead
      • some single-field rules that are not written yet: container resource names, and whole numbers for extended resources; the downward API field paths, resources, and divisors; the iSCSI iqn and initiatorName formats; an ephemeral volume claim's storageClassName and data source fields; and a CSI volume's nodePublishSecretRef name
    • Some rules are stricter than Kubernetes. A later version may widen them if customers need it.
      • An annotation key prefix, such as example.com in example.com/owner, must be lowercase.
      • A quantity cannot be . or a bare +, which Kubernetes reads as 0, and a count capped at 100% cannot be a zero-padded percentage, such as 05%.
      • A CSI volume's driver takes ASCII letters only. Kubernetes lowercases it first, so it also accepts a Kelvin sign (U+212A) as k.
      • Where a rule changed between Kubernetes 1.29 and 1.35, the schema keeps the stricter one. So an environment variable name holds only letters, digits, -, ., and _, and does not start with a digit.
    • No field inside these objects accepts null, list items included. In Helm values a null deletes the chart's value at that path, and an unset optional attribute of a Terraform object is sent as null, so leave such attributes out instead.
    • These settings themselves accept null where AWS's schema does, because there a null renders the same as leaving the setting out: controller.affinity, both nodeSelector, readinessProbe, startupProbe, and resources settings, and the resources of the three sidecars.
    • The csi-provisioner container and the controller's liveness-probe container use controller.resources while sidecars.csiProvisioner.resources or sidecars.livenessProbe.resources is empty. An empty limits or requests would make it non-empty and silently drop the inherited values, so these fields reject an empty map.
    • Strings reject control characters and the Unicode line and paragraph separators.
    • Tab and line feed are allowed only in environment variable values, probe exec commands, and annotation values.
  • controller.podLabels and node.podLabels cannot set app, app.kubernetes.io/name, or app.kubernetes.io/instance. The chart already writes these selector labels on the pods, so a second copy would make the pod labels disagree with the selector.
  • Annotation keys, in podAnnotations and in an ephemeral volume's claim template, cannot start with any of the prefixes below. Kubernetes still applies the AppArmor annotation as a container's AppArmor profile, at every version from 1.30 through at least 1.37. Security contexts are not configurable. The seccomp annotations no longer change a container's seccomp profile and have no other use.
    • container.apparmor.security.beta.kubernetes.io/
    • seccomp.security.alpha.kubernetes.io/
    • container.seccomp.security.alpha.kubernetes.io/
Liveness probes

Helm merges controller.livenessProbe and node.livenessProbe into the chart's default probe, which checks /healthz on the healthz port. Another handler would give the probe two, which Kubernetes rejects, and removing httpGet takes a null, which the schema rejects because it deletes the chart's value. So the liveness probes accept only httpGet and the timing fields. AWS's schema accepts exec, tcpSocket, and grpc there too. Their httpGet.port may be left out, because the chart's default fills it.

AWS settings that the schema leaves out

EKS applies an add-on with cluster-admin rights, so the schema never exposes security contexts or service account identity.

  • controller.containerSecurityContext: security contexts are not configurable.
  • controller.serviceAccount.annotations and node.serviceAccount.annotations: they set the role for IAM Roles for Service Accounts (IRSA), and service account identity is not configurable. Use EKS Pod Identity instead.
  • AWS SDK credential and identity variables in controller.env and node.env: AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_SESSION_NAME, AWS_ACCESS_KEY_ID, AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_SECRET_KEY, AWS_SESSION_TOKEN, AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI, AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_PROFILE, AWS_DEFAULT_PROFILE, AWS_SHARED_CREDENTIALS_FILE, and AWS_CONFIG_FILE. The AWS SDK would read these instead of the Pod Identity credentials, which replaces the service account identity. AWS_REGION and AWS_USE_FIPS_ENDPOINT are accepted.
  • controller.adaptiveRetryMode: the chart does not pass it to the driver, and the schema accepts only settings that the chart applies. The driver keeps its default, adaptive retry mode.
Kubernetes fields that the schema leaves out

This version does not support these fields, which AWS's schema accepts.

  • The claims field of every resources setting. The chart sets no pod resourceClaims, and Kubernetes rejects a container claim that names none.
  • Fields behind a feature gate that is off by default in at least one Kubernetes version from 1.29 to 1.35: the clusterTrustBundle source of a projected volume, env[].valueFrom.fileKeyRef, a volume mount's recursiveReadOnly, an ephemeral volume claim's volumeAttributesClassName and dataSourceRef.namespace, and a pod affinity term's matchLabelKeys and mismatchLabelKeys.

The volume sources below are fields of controller.volumes and node.volumes.

  • The image volume source, because the add-on decides which images it pulls.
  • The serviceAccountToken source of a projected volume, because it mints a credential for the pod's service account.
  • The gcePersistentDisk, azureDisk, azureFile, cinder, vsphereVolume, photonPersistentDisk, portworxVolume, flocker, glusterfs, scaleIO, storageos, flexVolume, and cephfs volume sources, which an EKS cluster cannot use.
  • The secret volume source and the secret source of a projected volume. To read a single value from a Secret, use env[].valueFrom.secretKeyRef.
  • The podCertificate source of a projected volume.
  • The gitRepo, quobyte, and rbd volume sources. Kubernetes deprecates gitRepo and no longer supports the in-tree quobyte and rbd types.
Defaults that differ from AWS's own add-on
  • controller.tolerations: this chart tolerates only the CriticalAddonsOnly and efs.csi.aws.com/agent-not-ready taints, while AWS's schema lists a default that tolerates every taint. To keep AWS's behavior, set controller.tolerations to [{"operator": "Exists"}].
  • node.maxInflightMountCalls and node.volumeAttachLimit: if you opt in with node.maxInflightMountCallsOptIn or node.volumeAttachLimitOptIn and leave the limit unset, this chart passes 10 and 20. AWS's schema lists -1 for both.
Settings for taking over AWS's own add-on

A selector cannot change after its object is created. This chart's selectors include the Helm release name, so they can differ from those on the efs-csi-controller Deployment and efs-csi-node DaemonSet that AWS's own add-on created. Two opt-in settings let this add-on adopt those objects:

  • controller.selectorLabelsOverride replaces the selector of the efs-csi-controller Deployment, its PodDisruptionBudget, and its metrics Service, and adds these labels to the controller pods.
  • node.selectorLabelsOverride replaces the selector of the efs-csi-node DaemonSet and adds these labels to the node pods.

Set each one to exactly the selector that the existing object has:

kubectl get deployment efs-csi-controller -n kube-system -o jsonpath='{.spec.selector.matchLabels}'
kubectl get daemonset efs-csi-node -n kube-system -o jsonpath='{.spec.selector.matchLabels}'

Each override accepts only the keys app, app.kubernetes.io/name, and app.kubernetes.io/instance, with valid, non-empty label values. Unless it is empty, it must include app, set to efs-csi-controller for the controller and efs-csi-node for the node. These limits keep the selectors on this add-on's own pods. Leave both empty for a new install, and the chart renders exactly what the upstream chart renders.

Compatibility settings

None. This chart is the upstream chart from the same project as AWS's own add-on, so every other AWS setting has the same name and shape.

Chart versions
  • 4.5.4-fips

    Latest
  • 4.5.4

  • 4.5.3-fips

  • 4.5.3

View all chart versions

Images

Helm charts contain references to Chainguard Container images. The following images are referenced in the chart:

aws-efs-csi-driver logo

aws-efs-csi-driver


The trusted source for open source

Talk to an expert
PrivacyTerms

Product

Chainguard ContainersChainguard LibrariesChainguard VMsChainguard OS PackagesChainguard ActionsChainguard Agent SkillsIntegrationsPricing
© 2026 Chainguard, Inc. All Rights Reserved.
Chainguard® and the Chainguard logo are registered trademarks of Chainguard, Inc. in the United States and/or other countries.
The other respective trademarks mentioned on this page are owned by the respective companies and use of them does not imply any affiliation or endorsement.