In this blog, we will dive into configuring Kubernetes Pods to use IAM Roles for Service Accounts (IRSA), enabling applications running in your Pods to securely access AWS services without embedding AWS credentials. This approach is secure, scalable, and aligns well with modern DevOps best practices.
Prerequisites
Before getting started, ensure you have the following ready:
An existing Amazon EKS cluster: If you don’t have one, follow the guide in Get started with Amazon EKS.
IAM OpenID Connect (OIDC) provider configured: Learn to create one or verify its existence by following the Create an IAM OIDC provider for your cluster guide.
AWS CLI installed: Ensure version 2.12.3 or later or version 1.27.160 or later is installed and configured. Check your version with:
aws --version | cut -d / -f2 | cut -d ' ' -f1
Update it if needed, following the Installing AWS CLI guide.
kubectl installed: Ensure it matches your Kubernetes version (within ±1 minor version). Follow the Set up kubectl and eksctl guide if necessary.
Step-by-Step Guide to Enable IAM Roles for Service Accounts
- Create an IAM Policy
First, let's create an IAM policy that defines the permissions required by your application. For example, if your application needs read-only access to an S3 bucket, create a policy file s3-readonly-policy.json with the following content:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
Then create the policy using the AWS CLI:
aws iam create-policy --policy-name S3ReadOnlyPolicy --policy-document file://s3-readonly-policy.json
- Create an IAM Role for the Service Account
Using the IAM OIDC provider, let's create an IAM role that trusts the OIDC provider associated with your cluster.
First, retrieve the OIDC provider URL:
aws eks describe-cluster --name my-cluster1 --query "cluster.identity.oidc.issuer" --output text
Then, create a trust policy trust-policy.json for your service account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::your-account-id:oidc-provider/oidc-provider-url"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc-provider-url:sub": "system:serviceaccount:namespace:service-account-name"
}
}
}
]
}
Replace your-account-id
, oidc-provider-url
, namespace
, and service-account-name
with the appropriate values.
Let's create the IAM role as follows:
aws iam create-role --role-name S3ReadOnlyRole --assume-role-policy-document file://trust-policy.json
Attach the policy to the role:
aws iam attach-role-policy --role-name S3ReadOnlyRole --policy-arn arn:aws:iam::your-account-id:policy/S3ReadOnlyPolicy
- Create a Kubernetes Service Account Let's create a Kubernetes service account and annotate it with the IAM role ARN:
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::your-account-id:role/S3ReadOnlyRole
- Configure Your Pod to Use the Service Account
Let's update your Pod's YAML configuration to use the newly created service account:
apiVersion: v1
kind: Pod
metadata:
name: my-app
namespace: default
spec:
serviceAccountName: s3-access-sa
containers:
- name: app
image: public.ecr.aws/nginx/nginx:1.12.0
Let's deploy the Pod now,
kubectl apply -f pod.yaml
- Verify the Configuration
Once the Pod is running, we will need to check the ARN of the IAM role that the Pod is using.
kubectl describe pod my-app | grep AWS_ROLE_ARN:
We will find the output as follows.
AWS_ROLE_ARN: arn:aws:iam::111122223333:role/my-role
Conclusion
Configuring IAM roles for service accounts is a powerful way to grant AWS permissions to Kubernetes workloads securely. This approach eliminates the need for hardcoding credentials and simplifies permissions management. By following these steps, you’ve enabled a secure and scalable method to integrate AWS services with your Kubernetes applications.
Feel free to reach out in the comments below if you encounter any issues or have questions! 🚀
Top comments (0)