ServiceAccounts and IRSA: Giving Pods Cloud Permissions Safely
Intermediate · 5 min read
Key takeaways
- ServiceAccounts and IRSA provide a secure way to manage cloud permissions for Kubernetes pods.
- Correctly configuring the trust policy and annotations is crucial for the pod to assume the IAM role.
- Regularly review and audit IAM roles and policies to ensure they are as restrictive as possible.
The Problem
Imagine you are a DevOps engineer at a growing e-commerce company. Your application, which runs on Kubernetes, needs to interact with various AWS services like S3, RDS, and DynamoDB. However, you face a significant challenge: how do you securely grant your application the necessary permissions to access these cloud resources without compromising security or operational efficiency?
This is where ServiceAccounts and IAM Roles for Service Accounts (IRSA) come into play. By using these tools, you can safely and efficiently manage cloud permissions for your Kubernetes pods, ensuring that your application has the right level of access to the resources it needs, while minimizing the risk of unauthorized access.
Core Concepts
Before diving into the mechanics, let’s define some key terms:
- Kubernetes Pod: The smallest deployable unit in Kubernetes, consisting of one or more containers that share network and storage resources.
- ServiceAccount: A Kubernetes object that provides an identity for processes running in a pod. It is used to authenticate and authorize actions within the cluster.
- AWS IAM Role: An AWS Identity and Access Management (IAM) role is an AWS identity with permission policies that determine what the identity can and cannot do in AWS.
- IAM Roles for Service Accounts (IRSA): A feature that allows you to associate an AWS IAM role with a Kubernetes ServiceAccount, enabling the pods to assume the role and gain the associated permissions.
How It Works
When a pod is created, it can be associated with a ServiceAccount. This ServiceAccount can then be linked to an AWS IAM role through the use of IRSA. Here’s a step-by-step overview of the process:
- A pod is created and associated with a ServiceAccount.
- The ServiceAccount is annotated with the ARN of an AWS IAM role.
- The Kubernetes API server, configured with the AWS IAM Authenticator, authenticates the pod using the ServiceAccount token.
- The pod assumes the AWS IAM role, and the AWS SDKs and CLI within the pod use the assumed role to make API calls to AWS services.
This approach ensures that each pod has the minimum necessary permissions, and the permissions are managed centrally through AWS IAM roles.
Prerequisites
Before you start, you will need the following:
- An AWS account with the necessary permissions to create and manage IAM roles and policies.
- A Kubernetes cluster (e.g., EKS, GKE, AKS, or a self-managed cluster).
- The AWS CLI installed and configured with your AWS credentials.
- kubectl installed and configured to interact with your Kubernetes cluster.
Hands-On Walkthrough
Let’s walk through the steps to set up a ServiceAccount with IRSA for a Kubernetes pod. We’ll assume you have an EKS cluster, but the steps are similar for other Kubernetes distributions.
Step 1: Create an IAM Role and Policy
First, create an IAM policy that defines the permissions your pod will need. For example, if your pod needs to read from an S3 bucket, you might create a policy like this:
s3-read-policy.json:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}
Create the policy using the AWS CLI:
aws iam create-policy --policy-name s3-read-policy --policy-document file://s3-read-policy.json
Next, create an IAM role and attach the policy to it:
aws iam create-role --role-name my-s3-reader --assume-role-policy-document file://trust-policy.json
aws iam attach-role-policy --role-name my-s3-reader --policy-arn arn:aws:iam::123456789012:policy/s3-read-policy
Here, `trust-policy.json` should look like this:
trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}
Step 2: Create a Kubernetes ServiceAccount and Annotate It
Create a ServiceAccount in your Kubernetes cluster and annotate it with the ARN of the IAM role:
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-s3-reader
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-s3-reader
Apply the ServiceAccount:
kubectl apply -f serviceaccount.yaml
Step 3: Deploy a Pod with the ServiceAccount
Create a pod that uses the ServiceAccount:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccountName: my-s3-reader
containers:
- name: my-container
image: amazon/aws-cli
command: [ "/bin/sh", "-c" ]
args: [ "while true; do sleep 30; done;" ]
Apply the pod:
kubectl apply -f pod.yaml
Verifying It Works
To verify that the pod has the correct permissions, you can exec into the pod and run an AWS CLI command:
kubectl exec -it my-pod -- /bin/bash
aws s3 ls s3://my-bucket/
If the pod has the correct permissions, you should see the contents of the S3 bucket. If not, you may see an error message indicating that the pod does not have the necessary permissions.
Common Mistakes
Here are some common mistakes to avoid:
- Incorrect Trust Policy: Ensure that the trust policy of the IAM role allows the Kubernetes nodes to assume the role. The trust policy should include the `ec2.amazonaws.com` service principal.
- Misconfigured Annotations: Make sure the ServiceAccount is correctly annotated with the ARN of the IAM role. Any typos or incorrect ARNs will prevent the pod from assuming the role.
- Insufficient Permissions: Verify that the IAM role has the necessary permissions. If the role lacks the required permissions, the pod will not be able to perform the desired actions.
Going Further
Once you have a basic setup working, consider the following production considerations and advanced topics:
- Scaling: As your application scales, ensure that the number of pods and the associated ServiceAccounts are managed efficiently. Use Kubernetes controllers like Deployments and StatefulSets to manage pod lifecycles.
- Security: Regularly review and audit the IAM roles and policies to ensure they are as restrictive as possible. Use AWS CloudTrail to monitor and log all API calls made by the pods.
- Performance Tuning: Monitor the performance of your pods and the AWS services they interact with. Use tools like Prometheus and Grafana to visualize and alert on performance metrics.
- Alternative Approaches: Consider using AWS Security Token Service (STS) to generate temporary credentials for your pods. This can be useful in scenarios where you need to dynamically adjust permissions based on runtime conditions.
Cleanup
To clean up the resources you created, run the following commands:
kubectl delete -f pod.yaml
kubectl delete -f serviceaccount.yaml
aws iam detach-role-policy --role-name my-s3-reader --policy-arn arn:aws:iam::123456789012:policy/s3-read-policy
aws iam delete-role --role-name my-s3-reader
aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/s3-read-policy
Architecture

References
This article was written with AI assistance.
