Connecting applications to AWS services from inside an Amazon Elastic Kubernetes Service (EKS) cluster is streamlined through native integration. Leveraging Kubernetes-native constructs like ServiceAccounts and IAM roles for pods, applications can securely access various AWS services using AWS SDKs. This enhances scalability and flexibility while maintaining robust security protocols.
Below document is an example of connecting to S3 from inside of EKS cluster.
Pre-requisites
export CLUSTER_NAME=""
export ACCOUNT_ID=""
export AWS_REGION=""
Step 1 - Get the OIDC provider
Get the OIDC issuer URL and check if the OIDC provider exists
OIDC_ISSUER_URL=$(aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc.issuer" --output text | sed 's/https:\/\///')
Step 2 - Create IAM role with assume role policy and required permissions
-
Create an following assume role policy
# enter your namespace and serviceaccount details
export APP_NS=""
export APP_SA=""
cat > assume-role-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_ISSUER_URL}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_ISSUER_URL}:aud": "sts.amazonaws.com",
"${OIDC_ISSUER_URL}:sub": "system:serviceaccount:${APP_NS}:${APP_SA}"
}
}
}
]
}
EOF
-
Create an IAM role using this assume role policy
IAM_ROLE_ARN=$(aws iam create-role --role-name access-to-s3-role --assume-role-policy-document file://assume-role-policy.json --output text --query 'Role.Arn')
-
Create the IAM policy with the required permissions.
# enter your bucket name details
export S3_BUCKET=""
cat > aws-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::$S3_BUCKET",
"arn:aws:s3:::$S3_BUCKET/*"
]
}
]
}
EOF
aws iam create-policy \
--policy-name "${CLUSTER_NAME}-s3-policy" \
--policy-document file://aws-policy.json
-
Attach the policy to the IAM role
aws iam attach-role-policy --role-name "$CLUSTER_NAME-s3-role" --policy-arn="arn:aws:iam::${ACCOUNT_ID}:policy/${CLUSTER_NAME}-s3-policy"
Step 4 - Annotate the serviceaccount with IAM role ARN
Create a service account in the namespace and annotate it with the IAM role ARN using TrueFoundry platform here with the following serviceaccount spec:
apiVersion: v1
kind: ServiceAccount
metadata:
name: $APP_SA
namespace: $APP_NS
annotations:
eks.amazonaws.com/role-arn: $IAM_ROLE_ARN
Step 5 - Test
-
Run a pod and test if you are able to perform operations on the AWS S3 bucket
kubectl apply -f -<<EOF
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: aws-cli-container
image: amazon/aws-cli
env:
- name: AWS_S3_BUCKET_NAME
value: "${S3_BUCKET}"
command: ["/bin/bash"]
args: ["-c", "sleep 3600"]
serviceAccountName: demo
EOF
-
Go inside the pod and execute the following command
kubectl exec -it my-pod -- /bin/bash
bash-4.2#
-
Run the command
aws s3 ls s3://$AWS_S3_BUCKET_NAME/