Post

Accessing AWS resources with IRSA within EKS

IRSA allows connecting K8s service accounts with AWS IAM roles. This allows permissions to be managed through AWS IAM.

In this blog post we will:

  • create text file
  • upload to AWS S3
  • create iam role to read the file
  • deploy program within k8s to read the file and print contents. The program will use role associated with the service account to read file and print the contents.

Prerequisites

  • AWS CLI installed and configured
  • Kubernetes installed and configured

Create Environment variables

1
2
3
4
5
6
7
OIDC_ID=$(aws eks describe-cluster --name my-cluster --query "cluster.identity.oidc.issuer" --output text | cut -f8 -d"/")
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
AWS_REGION="eu-west-2"
BUCKET_NAME="my-bucket-name"
IAM_ROLE="s3-reader"
K8S_NAMESPACE="default"
K8S_SERVICEACCOUNT="irsa-test"

Create an S3 Bucket with AWS cli

1
aws s3api create-bucket --bucket ${BUCKET_NAME} --region ${AWS_REGION}"

Create a File

1
echo "Hello world" > hello.txt

Upload the File to S3

1
aws s3 cp hello.txt s3://${BUCKET_NAME}/

Create trust policy for IAM Role with Web Identity (IRSA)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cat <<EOF > trust.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/oidc.eks.${AWS_REGION}.amazonaws.com/id/${OIDC_ID}"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "oidc.eks.${AWS_REGION}.amazonaws.com/id/${OIDC_ID}:sub": "system:serviceaccount:${K8S_NAMESPACE}:${K8S_SERVICEACCOUNT}"
        }
      }
    }
  ]
}
EOF

Create an IAM role

1
aws iam create-role --role-name ${IAM_ROLE} --assume-role-policy-document file://trust.json

Attach AWS Managed S3 readonly policy

1
aws iam attach-role-policy --role-name ${IAM_ROLE} --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

Create K8s service account

1
2
3
4
5
6
7
8
kubectl apply -f - <<EOF 
apiVersion: v1
kind: ServiceAccount
metadata:
    name: ${K8S_SERVICEACCOUNT}
    annotations:
        eks.amazonaws.com/role-arn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/${IAM_ROLE}
EOF

Create Kubernetes Deployment File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
kubectl apply -f - <<EOF 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: s3-reader
spec:
  replicas: 1
  selector:
    matchLabels:
      app: s3-reader
  template:
    metadata:
      labels:
        app: s3-reader
    spec:
      serviceAccountName: ${K8S_SERVICEACCOUNT}
      containers:
      - name: s3-reader
        image: python:3.8
        command: ["/bin/sh","-c"]
        args:
        - |
          pip install boto3 && \
          echo 'import os
          import boto3
          from botocore.exceptions import NoCredentialsError

          def download_from_s3(bucket, item, aws_region):
              s3 = boto3.resource("s3", region_name=aws_region)
              try:
                  s3.Bucket(bucket).download_file(item, item)
                  print(f"Downloaded {item} from {bucket}")
              except NoCredentialsError:
                  print("Credentials not available")

          def read_file(file_name):
              with open(file_name, "r") as file:
                  data = file.read()
                  print(f"S3 {file_name}:", data)

          def main():
              bucket = os.getenv("S3_BUCKET")
              item = os.getenv("S3_OBJECT")
              aws_region = os.getenv("AWS_REGION")

              download_from_s3(bucket, item, aws_region)
              read_file(item)

          if __name__ == "__main__":
              main()' > script.py && python script.py
        env:
        - name: AWS_REGION
          value: "${AWS_REGION}"
        - name: S3_BUCKET
          value:  "${BUCKET_NAME}"
        - name: S3_OBJECT
          value: "hello.txt"
EOF

View the output in log file

1
kubectl logs s3-reader

output should contain

1
S3 hello.txt: Hello world
This post is licensed under CC BY 4.0 by the author.