Grant AWS Resource Access to AWS EKS: Pod Identity

In Kubernetes, Role-Based Access Control is essential for securing your cluster. In 2019, AWS introduced IAM roles for service accounts (IRSA).

Also, we mentioned IRSA in one of our blog posts here.

Briefly, IRSA lets you associate an IAM role with a Kubernetes service account. It helps you to implement the principle of least privilege by giving pods only the permissions they need.

With Amazon EKS Pod Identity, it’s even easier to configure and automate granting AWS permissions to Kubernetes identities. As the cluster administrator, you no longer need to switch between Amazon EKS and IAM services to authenticate your applications to all AWS resources.

Let’s start by discussing the differences between IRSA and EKS Pod Identity.

If you’re wondering which one is better, here’s a key advantage of using Pod Identity: figuring out which pod can access a specific role in AWS is much easier. You can do this easily by calling ListPodIdentityAssociations. ( Please see here.)

On the other hand, with IRSA, it’s a bit more complex. You have to find IAM roles connected to the cluster’s OIDC provider, analyse some conditions in their policies, and then match those to your pods.

Another perk of Pod Identity is that you can set everything up through the AWS API without needing in-cluster interactions. With IRSA, you have to label service accounts with eks.amazonaws.com/role-arn explicitly.

Another advantage of Pod Identity is that you don’t have to worry about the IAM OIDC provider. With Pod Identity, we won’t need an OIDC provider to give access to the pods.

Steps to start using Amazon EKS Pod Identity can be summarised in a few simple steps:

  • Create an IAM role with required permissions for your application and specify pods.eks.amazonaws.com as the service principal in its trust policy.
  • Install the Amazon EKS Pod Identity Agent add-on using the Amazon EKS console or AWS Command Line Interface (AWS CLI).
  • Map the role to a service account directly in the Amazon EKS console, APIs, or AWS CLI.

Once it’s done, any new pods that use that service account will automatically be configured to receive IAM credentials.

Hands-On Time!

Let’s get our hands dirty!

For the demonstration in this post, we need to configure permission for the pod running in the Amazon EKS cluster, which will return the list of objects in the Amazon Simple Storage Service (Amazon S3) bucket.

Step 1: Creating an IAM Role

We can start creating an IAM Role using AWS CLI. First, Let’s create the Trust Policy JSON:

$ cat <<EOF >> Test-Role-Trust-Policy.json
{
 “Version”: “2012-10-17”,
 “Statement”: [
     {
         "Effect": "Allow",
         "Principal": {
             "Service": "
pods.eks.amazonaws.com"
         },
         “Action”: [
             “sts:AssumeRole”,
             “sts:TagSession”
         ]
     }
 ]
}
EOF

And using the following AWS CLI command, create the role named EKS-Pod-Identity-Role.

$ aws iam create-role \
 --role-name EKS-Pod-Identity-Role \
 --assume-role-policy-document file://Test-Role-Trust-Policy.json

Now we are ready to create a Policy JSON file:

$ cat <<EOF >> eks-pod-identity-role-for-s3.json

{
 “Version”: “2012-10-17”,
 “Statement”: [
     {
         “Effect”: “Allow”,
         “Resource”: “arn:aws:s3:::<BUCKET_NAME>”,
         “Action”: [
             “s3:ListBucket”,
             "s3:GetBucketLocation"
         ]
     }
 ]
}

EOF

And we can attach it to the role we created with the following command:

$ aws iam put-role-policy --role-name EKS-Pod-Identity-Role
--policy-name eks-pod-identity-role-for-s3 --policy-document
file://eks-pod-identity-role-for-s3.json


Step 2: Creating a Bucket to Access

For the sake of the demo, we will give access to the S3 bucket. For that purpose, we’ll create a new bucket. I’ll create a bucket with the name kadir-test-eks-pod-identity. Please don’t forget to change the <BUCKET_NAME> on the eks-pod-identity-role-for-s3.json.

For demonstration, we will upload a test file to the bucket and see if we can access it through the pod on AWS EKS.


Step 3: Install EKS Cluster

Assuming you have an EKS Cluster. If you don’t have an EKS cluster, You can create a new one using eksctl or AWS CLI command.

For demo purposes, we will create a cluster named eks-pod-identity-test-cluster. You can use the following command:

$ eksctl create cluster --name eks-pod-identity-test-cluster --region eu-west-2

For detailed information, please visit here

Step 4: Install the EKS Pod Identity Add-on

At this stage, the IAM role is ready, and now we need to configure the Amazon EKS Pod Identity Agent in the cluster.

We can use the aws eks create-addon command to install the Amazon EKS Pod Identity Agent add-on into the EKS cluster. Here’s the AWS CLI command:

$ aws eks create-addon \
--cluster-name eks-pod-identity-test-cluster \
--addon-name eks-pod-identity-agent \
--addon-version v1.0.0-eksbuild.1

Or, you can use the eksctl command as well:

$ eksctl create addon --cluster eks-pod-identity-test-cluster --name eks-pod-identity-agent

The output should be as follows:

2023-11-29 20:45:05 [!]  no IAM OIDC provider associated with the cluster, try ‘eksctl utils associate-iam-oidc-provider --region=eu-west-2 --cluster=eks-pod-identity-test-cluster’

2023-11-29 20:45:05 [ℹ]  Kubernetes version “1.27” in use by cluster “eks-pod-identity-test-cluster”

2023-11-29 20:45:06 [ℹ]  creating addon

2023-11-29 20:46:12 [ℹ]  addon “eks-pod-identity-agent” active


I want you to pay attention to this output. As you can see, no IAM OIDC provider is associated with the cluster. Because with Pod Identity, we won’t need an OIDC provider to give access to the pods.

  • Once we have Amazon EKS Pod Identity in the cluster, we must associate the IAM role with the Kubernetes pods.

We need to navigate to the Access tab in the EKS cluster. In the Pod Identity Associations section, we can select Create Pod Identity Association to map the IAM role to Kubernetes pods.

  • Here, We use the IAM role that we created in the beginning. We must also define the Kubernetes namespace and a service account to associate with the Pod Identity.

Note: If the namespace and Service account doesn’t exist yet, We can type the names. If they already exist, We can select them from the dropdown menu. Then, We can proceed with Create.

We can create the namespace and service account with the following commands:

$ kubectl create namespace pod-identity-assoc-namespace
namespace/pod-identity-assoc-namespace created

$ kubectl create serviceaccount pod-identity-assoc-sa -n pod-identity-assoc-namespace
serviceaccount/pod-identity-assoc-sa created

And using the following command, We can create a Pod Identity Association:

$ aws eks create-pod-identity-association \
--cluster-name eks-pod-identity-test-cluster \
--namespace pod-identity-assoc-namespace \
--service-account pod-identity-assoc-sa \
--role-arn arn:aws:iam::<REDACTED>:role/EKS-Pod-Identity-Rol

The output should look as below:

{
  “association”: {
      “clusterName”: “eks-pod-identity-test-cluster”,
      “namespace”: “pod-identity-assoc-namespace”,
      “serviceAccount”: “default”,
      “roleArn”: “arn:aws:iam::<REDACTED>:role/EKS-Pod-Identity-Role”,
      “associationArn”: “arn:aws:eks:eu-west-2:<REDACTED>:podidentityassociation/eks-pod-identity-test-cluster/<REDACTED>”,
      “associationId”: “a-xwg01nsckvwk5dd4i”,
      “tags”: {}
  }
}


Those are all the steps we need to do to configure IAM permissions for the applications running on Amazon EKS with EKS Pod Identity. We can see the IAM role is listed in Pod Identity associations.



Step 5: Testing If it works!

  • Let’s prepare the manifest to test it with the annotated service account.
  • Let’s create the pod with the manifest we prepared
  • Now, Let’s verify that the pod has the necessary permissions to access AWS resources. You can do this by checking the logs of the pod.

$ cat << EOF >> deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
Name: pod-identity-assoc-deployment
namespace: pod-identity-assoc-namespace
spec:
selector:
  matchLabels:
    app: pod-identity-assoc-deployment
template:
  metadata:
    labels:
      app: pod-identity-assoc-deployment
  spec:
    serviceAccountName: pod-identity-assoc-sa
    containers:
    - name: main
        image: demisto/boto3py3:1.0.0.81279
        command: [“python”]
        args: ["-c","import boto3; print(boto3.client('sts').get_caller_identity()['Arn']);print(boto3.client('s3').list_objects(Bucket='kadir-test-eks-pod-identity'))"]
EOF

$ kubectl apply -f deployment.yaml

$ kubectl logs pod-identity-assoc-deployment-86b689fc7b-cm6rc -n pod-identity-assoc-namespace

The output is as follows:

arn:aws:sts::<REDACTED>:assumed-role/EKS-Pod-Identity-Role/eks-eks-pod-
id-pod-identi-bd42554c-4692-40c4-b2c6-b70602ba1274

{'ResponseMetadata': {'RequestId': 'VRP9Q49P4K259M24', 'HostId':
‘lL9h6...(shortened)...lfVQo=’, ‘HTTPStatusCode’: 200, ‘HTTPHeaders’:
{'x-amz-id-2': 'lL9h6...(shortened)...UWlfVQo=', 'x-amz-request-id':
'VRP9Q49P4K259M24', 'date': 'Thu, 30 Nov 2023 11:27:24 GMT',
‘x-amz-bucket-region’: ‘eu-west-2’, ‘content-type’: ‘application/xml’,
‘transfer-encoding’: ‘chunked’, ‘server’: ‘AmazonS3’}, ‘RetryAttempts’:
0}, 'IsTruncated': False, 'Marker': '', 'Contents': [{'Key':
'
bion_logo_dark.png', 'LastModified': datetime.datetime(2023, 11, 30,
19, 39, 56, tzinfo=tzlocal()), 'ETag': '"7d8...(shortened)...bc8b"',
‘Size’: 22657, ‘StorageClass’: ‘STANDARD’, ‘Owner’: {‘ID’:
'9c42...(shortened)...6a69ca'}}], 'Name':
'
kadir-test-eks-pod-identity', 'Prefix': '', 'MaxKeys': 1000,
'EncodingType': 'url'}

As you can see from the output, we got the bucket object as an output on the logs. Our pod could access the bucket using the IAM role we created.

Finally, it is worth mentioning that from now on, pods created in this namespace, with the specified service account annotation, will automatically up with these permissions and will be able to perform their operations using these permissions we have determined in the IAM Role associated with the Pod Identity.  

Conclusion

Amazon EKS Pod Identity is a powerful feature that can simplify IAM permissions management for applications running on Amazon EKS clusters. By automatically assigning IAM roles to pods, EKS Pod Identity eliminates the need to manage IAM roles for each application manually. It helps to ensure that applications only have the permissions they need. This can save you time and effort and improve security.

Amazon EKS Pod Identity simplifies the experience of managing IAM roles for applications running on Amazon EKS. We can easily reuse IAM roles across multiple EKS clusters without updating the role trust policy each time a new cluster is created.

Another good part is Pricing – Amazon EKS Pod Identity is available at no charge.

If you run applications on Amazon EKS, let me encourage you to try EKS Pod Identity.

We hope this post helps you make your EKS clusters more secure and use Kubernetes service accounts effectively on AWS.

We also offer a Kubernetes Security Audit; if you’d like to hear more about it, please look at our Kubernetes Security Audit page.

Leave a Comment