Provision an OpenID Connect (OIDC) identity provider, map an AWS IAM Role to a Kubernetes Service Account, and verify access using a test Pod.
Prerequisites
- An active Amazon EKS cluster.
kubectl,eksctl, andawsCLI tools configured and authenticated.
Step 1: Associate an OIDC Provider
EKS clusters have an OIDC issuer URL. You must associate an IAM OIDC provider with this cluster so IAM can validate the tokens generated by Kubernetes.
# Replace <cluster-name> and <region> with your cluster details
export CLUSTER_NAME="eks-cluster"
export AWS_REGION="us-east-1"
eksctl utils associate-iam-oidc-provider \
--cluster $CLUSTER_NAME \
--region $AWS_REGION \
--approve
Step 2: Create an AWS IAM Policy
Create a policy that defines the exact AWS permissions the Pod requires. In this lab, we will grant read-only access to Amazon S3.
cat <<EOF > s3-readonly-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "*"
}
]
}
EOF
# Create the policy and capture the ARN
POLICY_ARN=$(aws iam create-policy \
--policy-name EKSS3ReadOnlyPolicy \
--policy-document file://s3-readonly-policy.json \
--query 'Policy.Arn' \
--output text)
echo $POLICY_ARN
Step 3: Create the IAM Role and Kubernetes Service Account
This step creates an IAM role, attaches the policy from Step 2, and creates a Kubernetes Service Account annotated with the IAM Role ARN. It establishes the trust relationship.
eksctl create iamserviceaccount \
--name s3-reader-sa \
--namespace default \
--cluster $CLUSTER_NAME \
--region $AWS_REGION \
--attach-policy-arn $POLICY_ARN \
--approve \
--override-existing-serviceaccounts
Step 4: Deploy a Test Pod
Deploy an AWS CLI Pod configured to use the newly created Service Account (s3-reader-sa).
cat <<EOF > test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: aws-cli-tester
namespace: default
spec:
serviceAccountName: s3-reader-sa
containers:
- name: aws-cli
image: amazon/aws-cli:latest
command: ["sleep", "3600"]
restartPolicy: Never
EOF
kubectl apply -f test-pod.yaml
Wait for the Pod to be in the Running state:
kubectl get pods aws-cli-tester -w
Step 5: Verify IRSA Configuration
Exec into the Pod and verify that the AWS CLI is automatically picking up the injected web identity token.
1: Check the environment variables: Kubernetes automatically injects AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE when the Service Account is annotated.
kubectl exec -it aws-cli-tester -- env | grep AWS2: Verify Identity: Check which IAM role the Pod is assuming.
kubectl exec -it aws-cli-tester -- aws sts get-caller-identityExpected Output: The Arn should reflect the IAM role created in Step 3, not the worker node’s IAM role.
3: Test S3 Access:
kubectl exec -it aws-cli-tester -- aws s3 lsExpected Output: A list of S3 buckets in your account.
4: Test Unauthorized Access (Validation): Attempt to create an S3 bucket to ensure the least privilege policy is enforced.
kubectl exec -it aws-cli-tester -- aws s3 mb s3://my-irsa-test-bucket-12345Expected Output: AccessDenied error.
Step 6: Teardown
Remove the resources to avoid any ongoing configuration drift or clutter.
kubectl delete -f test-pod.yaml
eksctl delete iamserviceaccount \
--name s3-reader-sa \
--namespace default \
--cluster $CLUSTER_NAME \
--region $AWS_REGION
aws iam delete-policy --policy-arn $POLICY_ARN
rm s3-readonly-policy.json test-pod.yaml