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 am working at Cotocus. I blog tech insights 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 I reviewed , and SEO strategies at Wizbrand.Β
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 PINTEREST
Rajesh Kumar at QUORA
Rajesh Kumar at WIZBRAND