Here’s a comprehensive tutorial on how to assign AWS permissions to Pods running in Amazon EKS, covering:
- The problem it solves
- All available options
- Pros and cons of each method
- A comparison table
- Implementation guide for the recommended ones (IRSA and Pod Identity)
🧩 Problem Statement
In Kubernetes (EKS), your Pods often need to access AWS resources like:
- S3 buckets to read/write files
- DynamoDB to store session data
- VPC Lattice for service networking
- CloudWatch for logging
But how do we securely give AWS IAM permissions to a Pod?
🔍 The Core Challenge
Unlike EC2 instances, Pods don’t have IAM roles by default. So, we need a secure way to assign IAM permissions to Pods.
✅ Available Options
Option No. | Method | Recommended | Fine-Grained | Secure | Requires OIDC | Notes |
---|---|---|---|---|---|---|
1 | IAM Roles for Service Accounts (IRSA) | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | Widely used |
2 | EKS Pod Identity (Agent-based) | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No | Newer method |
3 | EC2 Instance IAM Role | ❌ No | ❌ No | ❌ No | ❌ No | All Pods share role |
4 | AWS Credentials in Secrets/Env Vars | ❌ No | ✅ Yes | ❌ No | ❌ No | Insecure |
5 | Custom Identity Proxy/Sidecar Relay | ⚠️ Maybe | ✅ Yes | ✅ Yes | ❌ No | Complex, flexible |
🔎 Option 1: IAM Roles for Service Accounts (IRSA)
🔧 How it works:
- You associate an IAM Role with a Kubernetes Service Account.
- EKS uses OIDC (OpenID Connect) to let your Pod assume that IAM role.
🛠 Prerequisites:
- EKS Cluster with OIDC provider enabled
- IAM Role with trust relationship
- Annotated Kubernetes ServiceAccount
✅ Pros:
- Secure & fine-grained
- Widely supported in production
- Works with
eksctl
, Terraform, AWS CLI
❌ Cons:
- Requires OIDC setup
- Slightly more steps
📘 IRSA Setup Guide:
- Enable OIDC for your cluster (only once):
eksctl utils associate-iam-oidc-provider --cluster <cluster-name> --approve
- Create IAM policy (example for S3 access):
aws iam create-policy \ --policy-name MyAppS3Access \ --policy-document file://s3-policy.json
- Create IAM role for ServiceAccount:
eksctl create iamserviceaccount \ --cluster <cluster-name> \ --namespace <namespace> \ --name <sa-name> \ --attach-policy-arn arn:aws:iam::<account-id>:policy/MyAppS3Access \ --approve
- Use the ServiceAccount in your deployment:
serviceAccountName: <sa-name>
🔎 Option 2: EKS Pod Identity
🔧 How it works:
- Amazon EKS runs a Pod Identity Agent on each node.
- Your Pod’s ServiceAccount is annotated with an IAM role.
- The agent helps the Pod assume that IAM role — no OIDC needed.
✅ Pros:
- No need to set up OIDC
- Easier for beginners
- Native integration, evolving fast
❌ Cons:
- Requires Pod Identity Agent (minor extra setup)
- Newer, evolving feature
📘 Pod Identity Setup Guide:
- Install Pod Identity Agent:
eksctl enable pod-identity --cluster <cluster-name>
- Create IAM policy:
aws iam create-policy \ --policy-name MyAppS3Access \ --policy-document file://s3-policy.json
- Create IAM role and bind to service account:
eksctl create iamidentitymapping \ --cluster <cluster-name> \ --service-name <sa-name> \ --namespace <namespace> \ --arn arn:aws:iam::<account-id>:role/MyAppS3Access
- Annotate your ServiceAccount:
kubectl annotate serviceaccount <sa-name> \ eks.amazonaws.com/role-arn=arn:aws:iam::<account-id>:role/MyAppS3Access \ -n <namespace>
🔎 Option 3: EC2 IAM Role for Node
🛠 How it works:
- Attach the IAM role directly to EC2 instance/node.
- All Pods on that node share the same permissions.
❌ Why it’s bad:
- Not secure for multi-tenant or microservice workloads.
- No fine-grained control — violates least privilege.
🔎 Option 4: Hardcoded AWS Credentials
🛠 How it works:
- Manually inject
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
into the pod.
❌ Why it’s risky:
- Credentials can leak
- Hard to rotate and audit
- Breaks cloud-native best practices
🔎 Option 5: Custom Sidecar Token Relay
🛠 How it works:
- You run a sidecar container (e.g., Vault Agent, identity proxy) alongside your app.
- The sidecar securely handles IAM calls or credential fetching.
✅ When useful:
- Complex enterprise setups with custom identity management
- Using Vault for dynamic credential delivery
📊 Final Comparison Table
Feature / Method | IRSA | Pod Identity | EC2 Role | Env Vars | Sidecar Proxy |
---|---|---|---|---|---|
Secure | ✅ | ✅ | ❌ | ❌ | ✅ |
Granular per-Pod IAM Roles | ✅ | ✅ | ❌ | ✅ | ✅ |
OIDC Required | ✅ | ❌ | ❌ | ❌ | ❌ |
Easy to Set Up | ⚠️ Medium | ✅ Easy | ✅ | ✅ | ❌ Complex |
Production-ready | ✅ | ✅ (new) | ❌ | ❌ | ⚠️ Yes if done right |
AWS-recommended | ✅ | ✅ | ❌ | ❌ | ❌ |
🚀 Conclusion: What Should You Use?
If you’re… | Use this method |
---|---|
Starting fresh in 2024+ | ✅ Pod Identity |
Existing setup using IRSA | ✅ Stick with IRSA |
Insecure or legacy app | ❌ Avoid Env/EC2 roles |
Complex identity control needed | ⚠️ Sidecar/Proxy + Vault |
I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND