Stanislav Hordiyenko
Stanislav Hordiyenko

Reputation: 707

Assume AWS role from service account in AWS EKS

Current setup: python application is running as a Docker container in AWS EKS cluster. AWS keys are supplied as secrets in kubernetes cluster so that python code can read, initialise boto3 session and work with S3 bucket.

How I would like to change it: assume role of a serviceaccount under which the Docker container is running in AWS EKS cluster and then initialise boto3 session with this credentials and work with S3 bucket. I don't want to supply AWS keys into each service as I have many of them.

Is there any way to implement desired configuration?

Thank you.

Upvotes: 6

Views: 7846

Answers (1)

Sumit Murari
Sumit Murari

Reputation: 1689

This is done by what AWS calls IRSA(IAM Roles for serviceaccount)

Simplified Kubernetes version 1.12 OIDC JSON web token, Amazon EKS now hosts a public OIDC discovery endpoint per cluster containing the signing keys for the JSON web tokens so external systems, like IAM, can validate and accept the OIDC tokens issued by Kubernetes.


AWS guide for this is at: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

AWS guide at github: https://github.com/aws/amazon-eks-pod-identity-webhook/


Steps are mentioned below

  1. Get OIDC provider URL: aws eks describe-cluster --name cluster_name --query "cluster.identity.oidc.issuer" --output text

  2. Create the role with federated identity and get ARN for role

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::AWS_ACCOUNT_ID:oidc-provider/OIDC_PROVIDER"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "OIDC_PROVIDER:sub": "system:serviceaccount:SERVICE_ACCOUNT_NAMESPACE:SERVICE_ACCOUNT_NAME"
        }
      }
    }
  ]
}

Keep in mind, you need to mentioned NAMESPACE over here, ensure you have namespace with name SERVICE_ACCOUNT_NAMESPACE.

  1. Create service account in kubernetes
apiVersion: v1
kind: ServiceAccount
metadata:
  name: SERVICE_ACCOUNT_NAME
  annotations:
    eks.amazonaws.com/role-arn: ARN_OF_ABOVE_IAM_ROLE



  1. Run a pod using serviceaccount
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: SERVICE_ACCOUNT_NAME
  ...

If all done properly, you will be able to assume the role in your k8s pod. Try running any python script in docker container like,

import boto3
client = boto3.client('iam') 
response = client.list_users()
for x in response['Users']:
print (x['UserName']) 

Given the permission to IAM this would list the users in AWS Account.

Reference:

Upvotes: 7

Related Questions