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.