Unlocking AWS Power for Microservices: A Guide to IAM Roles for Service Accounts (IRSA)
Table of contents
What is iRSA?
IAM Roles for Service Accounts (IRSA) is a system that automates the provisioning and rotation of IAM temporary credentials, known as Web Identity tokens, which a Kubernetes ServiceAccount can utilize for making AWS API calls. With IRSA, you can grant AWS service permissions, such as S3, SES, and SNS, to your microservices application.
In this article, I will demonstrate how to set up IRSA in your environment.
Prerequisite -
AWS console admin access
Running EKS cluster
Configuration -
Create an IAM OIDC Identity Provider:
If you haven't already, create an OIDC identity provider for your EKS cluster using the AWS CLI:
eksctl utils associate-iam-oidc-provider --region <region> --cluster <cluster-name> --approve
Create an IAM Role:
Create an IAM role that your pods will assume. This role should have the necessary permissions to access AWS resources. You can do this using the AWS Management Console or AWS CLI.
aws iam create-role --role-name <role-name> --assume-role-policy-document file://eks-oidc-trust-policy.json
Here, eks-oidc-trust-policy.json is a JSON file containing a trust policy allowing your EKS cluster to assume this role. Replace <role-name>
with your desired role name.
Example trust policy (eks-oidc-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/<eks-cluster-id>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.<region>.amazonaws.com/id/<eks-cluster-id>:sub": "system:serviceaccount:<namespace>:<service-account-name>"
}
}
}
]
}
Replace <account-id>
, <region>
, <eks-cluster-id>
, <namespace>
, and <service-account-name>
with appropriate values.
Attach IAM Policies to the IAM Role:
Attach the necessary IAM policies to the IAM role you created in the previous step. These policies should grant permissions to access AWS resources like S3, RDS, etc., as needed by your Nginx pods.
aws iam attach-role-policy --role-name <role-name> --policy-arn <policy-arn>
Replace <role-name>
with your role name and <policy-arn>
with the ARN of the IAM policy you want to attach.
For example, here I am giving S3readonly policy -
aws iam attach-role-policy --role-name <role-name> --policy-arn <policy-arn>
Create a Kubernetes Service Account:
Create a Kubernetes service account in your EKS cluster, and annotate it with the IAM role ARN that you created earlier. This annotation informs EKS to associate the IAM role with the service account.
Create a YAML file, e.g., service-account.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/<role-name>
name: poc-sa
Apply this configuration to your cluster:
kubectl apply -f service-account.yaml
Create Your Deployment:
Create a deployment or pod that uses the service account you created. Ensure that the serviceAccountName field in your pod specification references the service account you created earlier.
Here I am using a simple Ubuntu image to show an example, you can use whatever you like or based on your requirements.
Example Deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: ubuntu
name: ubuntu
namespace: poc
spec:
replicas: 1
selector:
matchLabels:
name: ubuntu
template:
metadata:
labels:
name: ubuntu
spec:
containers:
- command:
- /bin/bash
- -c
- |
sleep 900000000
image: ubuntu
imagePullPolicy: Always
name: ubuntu
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- SYS_ADMIN
- NET_ADMIN
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
workingDir: /code
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: regcred
restartPolicy: Always
schedulerName: default-scheduler
serviceAccount: poc-sa
serviceAccountName: poc-sa
Deploy your app:
kubectl apply -f deployment.yaml
Test Your Configuration:
To test the configuration login inside the pod and install awscli -
apt update ; apt install awscli -y
after installation is complete, run the following command -
aws s3 ls s3://<bucket name>
If previous configurations are correct it should display the object listing from your bucket.
Troubleshooting -
While creating a role and policy if you are making any mistakes you can get the following error -
An error occurred (AccessDenied) when calling the AssumeRoleWithWebIdentity operation: Not authorized to perform sts:AssumeRoleWithWebIdentity
If you are facing the same issue, please recheck arn
, account-id
, and cluster-id
.
That's it! You've set up an app deployment with IRSA configuration in Amazon EKS. Your app pods will now have the necessary AWS permissions to access resources based on the IAM policies attached to the IAM role associated with the service account.
If still facing any errors please feel free to drop a comment.
Thanks
Subscribe to my newsletter
Read articles from Abhishek Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Abhishek Singh
Abhishek Singh
Hi This is Abhishek Singh, Devops Engineer by profession and Gamer by passion. I'm a devops engineer with more than 3 years of experience in Linux, Monitoring and Devops. I'm huge Open source supporter and Linux lover. In free time I love to play Minecraft and Valorant.