IAM Permissions Not Working in EKS? Here's How to Fix It (With IRSA)

You have a working Amazon EKS cluster and deployed pods. Now, your pods need secure, fine-grained access to AWS services like S3, DynamoDB, or Secrets Manager, but:
You don't want to hardcode AWS credentials in pods.
You want to follow AWS best practices using IAM roles for Kubernetes service accounts (IRSA).
Solution: Use IRSA (IAM Roles for Service Accounts):
With IRSA, each pod uses a Kubernetes service account that is linked to an IAM role, which defines what that pod can access in AWS.
This blog walks through enabling IRSA for your existing pods.
Assumptions
You have an EKS cluster already running
Your pods are already deployed
You're using AWS CLI, kubectl, and eksctl
You have access to create IAM roles and policies
Step-by-Step Guide
Step 1: Verify OIDC Provider for Your EKS Cluster
eksctl utils associate-iam-oidc-provider \
--region <aws-region> \
--cluster <cluster-name> \
--approve
Step 2: Create an IAM Policy with Required Permissions
For example, for S3 read access:
- Create s3-read-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["<service-action>"],
"Resource": ["<arn>"]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::rambunct-app"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::rambunct-app/*"]
}
]
}
- Create a policy
aws iam create-policy \
--policy-name <your-policy-name> \
--policy-document file://s3-read-policy.json
Step 3: Create a Kubernetes Service Account Linked to IAM Role
This account will be used by your pod.
eksctl create iamserviceaccount \
--name <serviceaccount-name> \
--namespace <namespace> \
--cluster <cluster-name> \
--region <region> \
--attach-policy-arn arn:aws:iam::<account-id>:policy/<policy-name> \
--approve \
--override-existing-serviceaccounts
Step 4: Patch the Pod (or Deployment) to Use the New Service Account
If you’re using plain pods (not Deployments):
kubectl delete pod <your-pod>
Then update your YAML ;
spec:
serviceAccountName: <your-serviceaccount>
Apply it:
kubectl apply -f <your-pod>
Step 5: Verify from Pod Logs
kubectl logs <your-pod>
Conclusion
By using IAM Roles for Service Accounts (IRSA), you can give your existing pods secure access to AWS services without compromising credentials. This is a production-grade method to connect workloads running in EKS with services like S3, Secrets Manager, and DynamoDB.
If your app needs AWS access, don’t use long-lived keys use IRSA. It's more secure, scalable, and AWS-native.





