Easy AWS permissions for your EKS workloads: Pod Identity - An easy way to grant AWS access
Tags: eks, aws, kubernetes, security
Published: 2024-05-27 05:13:00

📚 Introduction:

Running applications on Kubernetes is great, but sometimes they need to talk to other AWS services like S3 or DynamoDB. In the past, setting up the right permissions for your Kubernetes apps to access these AWS services was a bit of a headache. You had to jump through hoops and follow complex instructions.

But now, there's a new feature called EKS Pod Identity that makes granting AWS permissions to your Kubernetes apps a breeze. With just a few clicks (or commands), you can give your apps the AWS access they need, without any complicated setup.

EKS Pod Identity is a part of Amazon's Elastic Kubernetes Service (EKS), and it's designed to make your life as a Kubernetes user much easier. It's a simple, straightforward way to manage AWS permissions for your Kubernetes workloads, saving you time and effort.

In this blog post, we'll explore what EKS Pod Identity is, how it works, and why you should consider using it for your Kubernetes applications running on EKS.


## Grant AWS Permissions to Your K8S Apps:


When you're running Kubernetes apps on Amazon EKS (Elastic Kubernetes Service), you have two main options to give them the ability to access other AWS services like S3 or DynamoDB:

**_1. IAM Roles for Service Accounts (IRSA):_**

This method allows associating IAM roles with Kubernetes service accounts. It supports various Kubernetes environments on AWS like EKS, EKS Anywhere, OpenShift, and self-managed clusters. IRSA uses core AWS services like IAM and doesn't directly depend on the EKS service.

_**2. EKS Pod Identity:**_

This EKS-specific feature simplifies how cluster admins can configure IAM permissions for Kubernetes apps. It allows directly mapping an IAM role to a Kubernetes service account through EKS APIs. Pods under the associated service account can automatically obtain temporary AWS credentials.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4off8prdbpoerov4krp5.png)


Both options achieve the same goal - granting your Kubernetes workloads on EKS the necessary AWS permissions. However, EKS Pod Identity is a more EKS-specific and simplified approach, while IRSA is a more general solution that works across different Kubernetes environments on AWS.


{% gist https://gist.github.com/seifrajhi/af53b892b6bf8a70efccf564065feca3 file=Pod_Identity-VS-IRSA.md %}


## Pod Identity hands-on:

**_Deploy the cluster:_**

Execute the following commands  to provision the EKS Cluster:


```
git clone https://github.com/seifrajhi/aws-eks-terraform.git
cd aws-eks-terraform
terraform init 
terraform plan 
terraform auto-approve
```

_**Deploy Pod Identity agent:**_

To use EKS Pod Identity in your cluster, the EKS Pod Identity Agent addon must be installed on your EKS cluster. Let's install it using the below command.

```
aws eks create-addon --cluster-name eks-pod-identity-demo --addon-name eks-pod-identity-agent
aws eks wait addon-active --cluster-name eks-pod-identity-demo --addon-name eks-pod-identity-agent
```

Go to EKS Console and view the eks-pod-identity-agent under the Add-on tab.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5eq0d3f1qon6xwit5k7.png)

You can also take a look at what has been created in your EKS cluster by the new addon:

```
$ kubectl -n kube-system get daemonset eks-pod-identity-agent

# Or 

$ kubectl -n kube-system get pods -l app.kubernetes.io/name=eks-pod-identity-agent
```

_**Deploy the sample app:**_

Below is the manifest we will be using:


```
apiVersion: v1
kind: Namespace
metadata:
  name: demo-ns
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: demo-sa
  namespace: demo-ns
--- 
apiVersion: v1
kind: Pod
metadata:
  name: demo-app
  namespace: demo-ns
  labels:
     app: demo-app
spec:
  serviceAccountName: demo-sa
  containers:
    - name: demo-app
      image: amazon/aws-cli:latest
      command: ['sleep', '36000']
  restartPolicy: Never
```

Run the below command to deploy the app:


```
kubectl  apply -f manifests.yaml
```

**_Configure Amazon EKS Pod Identity:_**

Create a trust policy and configure the principal to `pods.eks.amazonaws.com`.

IAM_ROLE_TRUST_POLICY.json:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "pods.eks.amazonaws.com"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ]
        }
    ]
}
```

Using the above trust policy, create the IAM role.
```
aws iam create-role \
        --role-name eks-pod-s3-readonly-access \
        --description  "allow EKS pods readonly acces to S3" \
        --assume-role-policy-document file://IAM_ROLE_TRUST_POLICY.json \
        --output text \
        --query 'Role.Arn'
```

Then create the IAM Policy for S3 to list buckets and get Objects.

IAM_POLICY.json:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectTagging"
            ],
            "Resource": "*"
        }
    ]
}
```

Create the IAM Policy:

```
aws iam create-policy --policy-name eks-pod-s3-readonly-access-policy --policy-document file://IAM_POLICY.json --output text --query Policy.Arn
```

Attach the policy to the IAM Role: 

```
aws iam attach-role-policy --role-name eks-pod-s3-readonly-access \
  --policy-arn eks-pod-s3-readonly-access-policy
```

**_Create Pod Identity association:_**

Create the EKS Pod Identity association for the Service account `demo-sa` in Namespace `demo-ns` for the IAM Role `eks-pod-s3-readonly-access`:

```
$ export IAM_ROLE_ARN=$(aws iam get-role --role-name eks-pod-s3-readonly-access | jq -r '.Role.Arn')

$ aws eks create-pod-identity-association \
  --cluster-name eks-pod-identity-demo \
  --namespace demo-ns\
  --service-account demo-sa \
  --role-arn $IAM_ROLE_ARN
```

We can get the list of current EKS Pod Identity associations using the below command:
```
aws eks list-pod-identity-associations --cluster-name eks-pod-identity-demo
```


**_Test AWS EKS Pod Identity:_**

Run the below command:

```
kubectl -n demo-ns exec -it demo-app -- aws s3 ls

```

The App can list of S3 Buckets 🎉.

**_Conclusion:_**

In short, EKS Pod Identity is a great solution that lets you easily give your Kubernetes apps running on Amazon EKS the AWS permissions they need.



Thank you for Reading !! 🙌🏻😁📃, see you in the next blog.

🚀 Thank you for sticking up till the end. If you have any questions/feedback regarding this blog feel free to connect with me :

♻️ LinkedIn: https://www.linkedin.com/in/rajhi-saif/
♻️ Twitter : https://twitter.com/rajhisaifeddine

The end ✌🏻

🔰 Keep Learning !! Keep Sharing !! 🔰

## References:

https://securitylabs.datadoghq.com/articles/eks-pod-identity-deep-dive/
https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html
https://www.eksworkshop.com/docs/security/amazon-eks-pod-identity/use-pod-identity/