kubectl run --image amazon/aws-cli awscli -n <serviceAccountNamespace> ec2 describe-instances
The aws-cli container will try to describe ec2 instances, but it failed:
Next we proceed our setup.
1. Create an OIDC provider for your cluster.
eksctl utils associate-iam-oidc-provider --cluster --approve
Note the OIDC provider:
OIDC_PROVIDER=$(aws eks describe-cluster --name --query "cluster.identity.oidc.issuer" --output text | sed -e "s/^https:\/\///")
2. Create a new namespace for running docker pod. (Optional)
kubectl create ns
3. Setup a Kubernetes service account for the namespace.
Every namespace has a default service account resource called default
. When a pod is created, if a service account is not specified, it is automatically assigned to run under the default
service account in the same namespace. You can use the default service account for learning purpose. But it is advisable to create a separate service account for each of your application for better management.
Create a new service account:
kubectl create sa -n
Example yaml file for specifying the service account to use for running a pod:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
serviceAccountName: serviceAccountName
...
4. Create an IAM role and attach IAM policy for designated AWS services access. (In our case, we will use the AWS managed policy named “arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess”)
Copy the following code block to a file named trust.json
Replace with your ACCOUNT_ID, OIDC_PROVIDER, serviceAccountNamespace and service AccountName with the above values. Note the StringEquals statement will confine the access to match a particular service account in that namespace only.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam:::oidc-provider/${OIDC_PROVIDER}" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { ":sub": "system:serviceaccount:<serviceAccountNamespace>:<serviceAccountName>" } } } ] } aws iam create-role --role-name --assume-role-policy-document file://trust.json --description ""
Next assign the “AmazonEC2ReadOnlyAccess” policy to this new IAM role.
aws iam attach-role-policy --role-name --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
5. Associate the IAM role with the service account by adding the following annotation to the service account.
kubectl annotate sa -n <serviceAccountNamespace> eks.amazonaws.com/role-arn=$IAM_ROLE_ARN
When we describe the service account again, we see that the service account include the ARN of the IAM role as an annotation.
5. The Amazon EKS Pod Identity Webhook on the cluster will apply the aforementioned environment variables AWS_ROLE_ARN
and AWS_WEB_IDENTITY_TOKEN_FILE
to the new pods that are running under this service account with this annotation.
You can examine the AWS credential environment variables set in the pod.
kubectl exec -n <serviceAccountNamespace> env | grep AWS
6. Relaunch your aws-cli pod and verify the pod’s IAM permission by issuing AWS CLI command to verify EC2 permission.
kubectl run --image amazon/aws-cli awscli -n <serviceAccountNamespace> ec2 describe-instances
You should be able to see a list of EC2 instances if any.
This conclude the EKS identity mapping to AWS IAM role.