How to give permission to AWS Code build to access EKS cluster using a role

Vishnu ks
Adfolks
Published in
3 min readFeb 5, 2020

TL;DR — This is for DevOps who have working knowledge on AWS Codebuild, IAM roles, EKS cluster and AWS CLI

It is very common practice to use roles for making AWS services talk to each other. It’s the best practice rather than sharing credentials with developers. Credentials can be leaked out and get your environment compromised.

Here I am gonna explain how we can give permission to AWS CodeBuild service to access AWS EKS environment securely without storing kubeconfig file anywhere. I have seen many people storing there EKS cluster kubeconfig file in S3 bucket or in their git repo, which is very frightening 😱.

Here is the recipe 🤗

The Workflow consists of 4 steps,

1 — Create IAM Role with trust relationship from CodeBuild Service Role

TRUST=”{ \”Version\”: \”2012–10–17\”, \”Statement\”: [ { \”Effect\”: \”Allow\”, \”Principal\”: { \”AWS\”: \”arn:aws:iam::44755xxxxxxx:role/YOUR-CODEBUILD-ROLE\” }, \”Action\”: \”sts:AssumeRole\” } ] }”aws iam create-role — role-name EksCodeBuildkubectlRole — assume-role-policy-document “$TRUST” — output text — query ‘Role.Arn’

In my example, the CODEBUILD role is service-role/codebuild-BUILD222-service-role, this is auto-generated when you create a CodeBuild.

TRUST=”{ \”Version\”: \”2012–10–17\”, \”Statement\”: [ { \”Effect\”: \”Allow\”, \”Principal\”: { \”AWS\”: \”arn:aws:iam::44755xxxxxxx:role/service-role/codebuild-BUILD222-service-role\” }, \”Action\”: \”sts:AssumeRole\” } ] }”
aws iam create-role — role-name EksCodeBuildkubectlRole — assume-role-policy-document “$TRUST” — output text — query ‘Role.Arn'

2 — Configure aws-auth configmap to authenticate in the cluster using the role created in step1

ROLE="    - rolearn: arn:aws:iam::44755xxxxxxx:role/EksCodeBuildkubectlRole\n      username: build\n      groups:\n        - system:masters"kubectl get -n kube-system configmap/aws-auth -o yaml | awk "/mapRoles: \|/{print;print \"$ROLE\";next}1" > /tmp/aws-auth-patch.ymlkubectl patch configmap/aws-auth -n kube-system --patch "$(cat /tmp/aws-auth-patch.yml)"

3 — Create a Policy and attach to CodeBuild Service Role, to perform STS:assumerole and permission to READ in EKS:* to the role created in step 1

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EKSREADONLY",
"Effect": "Allow",
"Action": [
"eks:DescribeNodegroup",
"eks:DescribeUpdate",
"eks:DescribeCluster"
],
"Resource": "*"
},
{
"Sid": "STSASSUME",
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::44755xxxxxxx:role/EksCodeBuildkubectlRole"
}
]
}

4 — Using aws eks update-kubeconfig with the argument — role-arn <Role created in step1>, you will be able to authenticate in the EKS cluster. Below is a sample buildspec file which you can try ✌️

version: 0.2phases:
install:
runtime-versions:
docker: 18
commands:
- echo test
build:
commands:
- curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.16.0/bin/linux/amd64/kubectl
- chmod +x ./kubectl
- export PATH=$PWD/:$PATH
- apt-get -y install jq
- aws eks update-kubeconfig --name $EKS_CLUSTER_NAME --role-arn arn:aws:iam::44755xxxxxxx:role/EksCodeBuildkubectlRole
- kubectl get nodes

Now you can manually trigger a build to test it. If everything is configured as I mentioned in above steps, kubectl commands against the EKS cluster will execute successfully and it can be verified in build logs.

Hope you find this article useful and helped in building a secure CICD pipeline 👍

--

--