How to Setup Amazon EBS CSI Driver on EKS with KMS Encryption Using OIDC and Deploy a Sample Application

Navya ANavya A
4 min read

Introduction

Amazon Elastic Block Store (EBS) Container Storage Interface (CSI) driver enables Kubernetes clusters on Amazon EKS to dynamically provision and manage persistent block storage backed by Amazon EBS volumes. This guide will help you:

  • Enable OIDC provider for IAM roles in EKS

  • Create IAM roles with KMS permissions for encrypted EBS volumes

  • Install and configure the Amazon EBS CSI driver

  • Create encrypted StorageClass with a custom KMS key

  • Deploy a PersistentVolumeClaim (PVC) and a Pod using the encrypted EBS volume

  • Understand Pod and PVC lifecycle impacts on data and volumes


Prerequisites

  • An existing Amazon EKS cluster (Kubernetes 1.15+)

  • AWS CLI and kubectl installed and configured

  • eksctl installed (optional but recommended)

  • An AWS KMS key created for EBS encryption


Step 1: Enable OIDC Provider for Your EKS Cluster

Amazon EKS uses IAM Roles for Service Accounts (IRSA) to provide fine-grained permissions to pods. First, enable OIDC identity provider for your cluster:

eksctl utils associate-iam-oidc-provider \
  --region <your-region> \
  --cluster <your-cluster-name> \
  --approve

Retrieve your OIDC provider URL for creating IAM trust relationships:

aws eks describe-cluster \
  --name <your-cluster-name> \
  --query "cluster.identity.oidc.issuer" \
  --output text

Step 2: Create IAM Role for EBS CSI Driver with KMS Permissions

2.1 Create Trust Policy (replace placeholders)

Create a file trust-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<account-id>:oidc-provider/oidc.eks.<region>.amazonaws.com/id/<oidc-id>"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.<region>.amazonaws.com/id/<oidc-id>:aud": "sts.amazonaws.com",
          "oidc.eks.<region>.amazonaws.com/id/<oidc-id>:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"
        }
      }
    }
  ]
}

2.2 Create the role

aws iam create-role \
  --role-name AmazonEKS_EBS_CSI_DriverRole \
  --assume-role-policy-document file://trust-policy.json

2.3 Attach managed policy

aws iam attach-role-policy \
  --role-name AmazonEKS_EBS_CSI_DriverRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy

2.4 Create custom KMS policy for encryption

Create kms-policy.json (replace with your KMS ARN):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": ["arn:aws:kms:<region>:<account-id>:key/<key-id>"],
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": "true"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": ["arn:aws:kms:<region>:<account-id>:key/<key-id>"]
    }
  ]
}

Create and attach policy:

aws iam create-policy \
  --policy-name KMS_EBS_Encryption_Policy \
  --policy-document file://kms-policy.json

aws iam attach-role-policy \
  --role-name AmazonEKS_EBS_CSI_DriverRole \
  --policy-arn arn:aws:iam::<account-id>:policy/KMS_EBS_Encryption_Policy

Step 3: Install Amazon EBS CSI Driver Add-on on EKS

Install using AWS EKS add-ons for simplicity and automatic updates:

aws eks create-addon \
  --cluster-name <your-cluster-name> \
  --addon-name aws-ebs-csi-driver \
  --service-account-role-arn arn:aws:iam::<account-id>:role/AmazonEKS_EBS_CSI_DriverRole \
  --region <your-region>

Step 4: Create Encrypted StorageClass with KMS Key

Create a file storageclass.yaml:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-csi-encrypted
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
parameters:
  type: gp3
  fstype: ext4
  encrypted: "true"
  kmsKeyId: arn:aws:kms:<region>:<account-id>:key/<key-id>
  • WaitForFirstConsumer delays volume creation until pod scheduling to ensure AZ affinity.

  • reclaimPolicy: Delete means volume is deleted when PVC is deleted (change to Retain to keep volume).

  • kmsKeyId uses your custom KMS key for encryption.

Apply it:

kubectl apply -f storageclass.yaml

Step 5: Create PersistentVolumeClaim

Create pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-csi-encrypted
  resources:
    requests:
      storage: 2Gi

Apply:

kubectl apply -f pvc.yaml

Step 6: Deploy Sample Pod Using PVC

Create pod.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: ebs-app
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - name: ebs-storage
          mountPath: /usr/share/nginx/html
  volumes:
    - name: ebs-storage
      persistentVolumeClaim:
        claimName: ebs-claim

Apply:

kubectl apply -f pod.yaml

Step 7: Verify Setup

  • Check pod status:
kubectl get pods ebs-app
kubectl describe pod ebs-app
  • Verify PVC bound to a PV:
kubectl get pvc ebs-claim
kubectl describe pvc ebs-claim
  • Check PV and confirm encryption and KMS key from AWS Console or CLI:
aws ec2 describe-volumes --volume-ids <volume-id-from-pv>

What Happens When You Delete a Pod?

  • Pod terminates; volume is detached but PVC and EBS volume remain intact.

  • Data remains persistent on the encrypted EBS volume.

  • You can recreate a pod using the same PVC and access your data.


What Happens When You Delete a PVC?

  • Since reclaimPolicy is Delete, the EBS volume is deleted, and all data is lost.

  • Pod using this PVC will go into an error state due to missing volume.

  • If you want to keep data, set reclaimPolicy to Retain, then manually manage the volume.


Conclusion

This guide walked you through securely provisioning encrypted EBS volumes in EKS with OIDC and IAM Roles for Service Accounts. Using custom KMS keys ensures data-at-rest encryption under your control. Pods can dynamically consume encrypted storage with data persistence across restarts, and you control lifecycle behavior with StorageClass reclaim policies.

0
Subscribe to my newsletter

Read articles from Navya A directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Navya A
Navya A

๐Ÿ‘‹ Welcome to my Hashnode profile! I'm a passionate technologist with expertise in AWS, DevOps, Kubernetes, Terraform, Datree, and various cloud technologies. Here's a glimpse into what I bring to the table: ๐ŸŒŸ Cloud Aficionado: I thrive in the world of cloud technologies, particularly AWS. From architecting scalable infrastructure to optimizing cost efficiency, I love diving deep into the AWS ecosystem and crafting robust solutions. ๐Ÿš€ DevOps Champion: As a DevOps enthusiast, I embrace the culture of collaboration and continuous improvement. I specialize in streamlining development workflows, implementing CI/CD pipelines, and automating infrastructure deployment using modern tools like Kubernetes. โ›ต Kubernetes Navigator: Navigating the seas of containerization is my forte. With a solid grasp on Kubernetes, I orchestrate containerized applications, manage deployments, and ensure seamless scalability while maximizing resource utilization. ๐Ÿ—๏ธ Terraform Magician: Building infrastructure as code is where I excel. With Terraform, I conjure up infrastructure blueprints, define infrastructure-as-code, and provision resources across multiple cloud platforms, ensuring consistent and reproducible deployments. ๐ŸŒณ Datree Guardian: In my quest for secure and compliant code, I leverage Datree to enforce best practices and prevent misconfigurations. I'm passionate about maintaining code quality, security, and reliability in every project I undertake. ๐ŸŒ Cloud Explorer: The ever-evolving cloud landscape fascinates me, and I'm constantly exploring new technologies and trends. From serverless architectures to big data analytics, I'm eager to stay ahead of the curve and help you harness the full potential of the cloud. Whether you need assistance in designing scalable architectures, optimizing your infrastructure, or enhancing your DevOps practices, I'm here to collaborate and share my knowledge. Let's embark on a journey together, where we leverage cutting-edge technologies to build robust and efficient solutions in the cloud! ๐Ÿš€๐Ÿ’ป