Jan 05, 2023. 5 min

How to Create EKS Cluster Using AWS CodeBuild

Overview

In this blog, you will learn how to automate EKS (Kubernetes) cluster creation with AWS CodeBuild.

What Is EKS Cluster?

Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that makes it easy to deploy, manage, and scale containerized applications using Kubernetes on AWS. EKS runs upstream Kubernetes and is natively integrated with other AWS services, making it easy to build and run applications on a fully managed Kubernetes service.

With EKS, you can deploy and run containerized applications quickly and easily, without the need to install and maintain a separate Kubernetes control plane. EKS takes care of the underlying infrastructure and automatically scales the control plane to meet your workload needs. You can use EKS to run applications in multiple AWS Regions and accounts, and you can easily migrate applications to and from other Kubernetes environments.

What is AWS CodeBuild?

Amazon Web Services (AWS) CodeBuild is a fully managed build service that compiles source code, runs tests, and produces software packages that are ready to deploy. With CodeBuild, you don't need to provision, maintain, or scale your build servers. You can use CodeBuild to build and test a variety of software projects, including those written in languages such as Java, Go, and Ruby.

How to Create an EKS Cluster with AWS CodeBuild?

So far we talked about what is EKS and AWS CodeBuild. Now we are going to talk about how can we create an EKS cluster using AWS CodeBuild.

For that, you first need to create a buildspec.yml file. An example is given below

	
version: 0.1
    
phases:
  install:
    commands:
      - echo Installing app dependencies...
      - curl -o kubectl https://s3.us-west-2.amazonaws.com/amazon-eks/1.24.7/2022-10-31/bin/darwin/amd64/kubectl   
      - chmod +x ./kubectl
      - chmod +x ./aws-auth.sh
      - mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
      - echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
      - source ~/.bashrc
      - curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
      - mv /tmp/eksctl /usr/local/bin
  pre_build:
    commands:
      - echo Entered the pre_build phase...
      - echo Logging in to Amazon EKS...
      - eksctl create cluster --name $AWS_CLUSTER_NAME --region $REGION --nodegroup-name $AWS_CLUSTER_NAME-ng --nodes $NODES --node-type $NODE_TYPE --nodes-min $NODES_MIN --nodes-max $NODES_MAX --ssh-access --ssh-public-key $SSH_PUBLIC_KEY --managed --node-volume-size=$NODE_VOL_SIZE --tags environment=dev --tags owner=$CODEBUILD_INITIATOR
      - aws eks --region $AWS_DEFAULT_REGION update-kubeconfig --name $AWS_CLUSTER_NAME
  build:
    commands:
      - echo Entered the build phase...
      - echo Change directory to secondary source
      - aws sts get-caller-identity
      - kubectl get configmap -n kube-system aws-auth -o yaml
      - ls
      - ./aws-auth.sh > aws-auth.yaml
      - cat aws-auth.yaml
													

And then create aws-auth.sh file. ( replace xxxxxxxxxx with your AWS account ID )

												
#!/usr/bin/env bash

set -o errexit
set -o nounset
set -o pipefail

IAM_GROUP=${1:-Admin}
EKS_ROLE_ARN=${2:-arn:aws:iam::xxxxxxxxxx:role/service-role/codebuild-eks-cluster-automation-service-role}
RBAC_GROUP=${3:-system:masters}

mapusers(){
    local IAM_GROUP_NAME=$1
    local RBAC_GROUP=$2
    local USER_LIST=""
    
    USER_LIST="$(aws iam get-group --group-name "${IAM_GROUP_NAME}" --query 'Users[*].Arn' --output text)"

    for user in ${USER_LIST}
    do
    echo -n "
    - userarn: ${user}
      username: ${user#*/}
      groups:
        - ${RBAC_GROUP}"
    done
}

mapclusters() {
  configmap="$(kubectl get configmap aws-auth -n kube-system -o yaml| grep rolearn: | sed 's/rolearn://g' )"
  for p in $configmap
  do
    echo -n "
    - rolearn: ${p}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes"
  done
}

cat << EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: ${EKS_ROLE_ARN}
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
      $(mapclusters)
  mapUsers: |
$(mapusers "${IAM_GROUP}" "${RBAC_GROUP}") 
EOF

Create a git repo and push those files over there. Once these two files have been created then you either create an AWS CodeBuild project manually or via CloudFormation template. Here I give you one sample CF Template which creates the CodeBuild Project.


AWSTemplateFormatVersion: 2010-09-09
Parameters:  
	AWSCLUSTERNAME:
	Description: "AWS CLUSTER NAME"
	Type: String
	Default: ""  
	GITURL:
	Description: "Github Url"
	Type: String
	Default: ""  
	NODETYPE:
	Description: "NODE TYPE"
	Type: String
	Default: "t3.medium"
	serviceRoleForCodeBuild:
	Description: "Name of the service role"
	Type: String
	Default: ""
	NODES: 
	Description: "NODES"
	Type: String
	Default: "2"
	NODESMIN: 
	Description: "NODES MIN"
	Type: String
	Default: "1"
	NODESMAX: 
	Description: "NODES MAX"
	Type: String
	Default: "4" 
	BUILDSPECFILE: 
	Description: "Buildspec File name"
	Type: String
	Default: "buildspec.yml"
	NODEVOLSIZE:
	Description: "NODE VOLUME SIZE"
	Type: String
	Default: "10"  
	SSHPUBLICKEY:
	Description: "SSH KEY PAIRS"
	Type: String
	Default: "ssh-key-ohio"
	NGINIXCONTROLLERVERSION:
	Description: "NGINIX INGRESS CONTROLLER VERSION"
	Type: String
	Default: "v1.0.0"
	ENVNAME:
	Description: "Environment dev/stg/prod"
	Type: String
	Default: ""
	
Resources:    
	microserviceBuildProject:
	Type: AWS::CodeBuild::Project    
	Properties:
		Name: !Join [ "-", ["cb", "eksClusterCreation", !Ref ENVNAME] ]
		Description: "Pipeline for Micro Services"
		ServiceRole: !Ref serviceRoleForCodeBuild
		Artifacts:
		Type: no_artifacts
		Environment:
		Type: LINUX_CONTAINER
		Image: "aws/codebuild/amazonlinux2-x86_64-standard:4.0"
		ComputeType: BUILD_GENERAL1_SMALL
		PrivilegedMode: True 
		EnvironmentVariables:
			- Name: AWS_CLUSTER_NAME
			Type: PLAINTEXT
			Value: !Ref AWSCLUSTERNAME
			- Name: NODE_TYPE
			Type: PLAINTEXT
			Value: !Ref NODETYPE          
			- Name: NODES
			Type: PLAINTEXT
			Value: !Ref NODES          
			- Name: NODES_MIN
			Type: PLAINTEXT
			Value: !Ref NODESMIN
			- Name: NODES_MAX
			Type: PLAINTEXT
			Value: !Ref NODESMAX          
			- Name: REGION
			Type: PLAINTEXT
			Value: !Ref "AWS::Region"          
			- Name: NODE_VOL_SIZE
			Type: PLAINTEXT
			Value: !Ref NODEVOLSIZE          
			- Name: SSH_PUBLIC_KEY
			Type: PLAINTEXT
			Value: !Ref SSHPUBLICKEY
			- Name: CB_SERVICE_ROLE
			Type: PLAINTEXT
			Value: !Ref serviceRoleForCodeBuild
			- Name: NGINIX_CONTROLLER_VERSION
			Type: PLAINTEXT
			Value: !Ref NGINIXCONTROLLERVERSION
			
		Source:    
		Auth:
			Resource: !Join [ "", ["arn:aws:codebuild:", !Ref "AWS::Region" , ":" , !Ref "AWS::AccountId" ,  ":token/github" ] ]
			Type: OAUTH    
		Type: GITHUB
		Location: !Ref GITURL
		BuildSpec: !Ref BUILDSPECFILE
		GitCloneDepth: 1
		GitSubmodulesConfig: 
			FetchSubmodules: false 
		ReportBuildStatus: false 
		InsecureSsl: false      
		TimeoutInMinutes: 60
		SourceVersion: !Ref ENVNAME
		EncryptionKey: !Join [ "", ["arn:aws:kms:", !Ref "AWS::Region", ":" , !Ref "AWS::AccountId"  , ":alias/aws/s3" ] ]
		LogsConfig: 
		CloudWatchLogs:
			Status: ENABLED 
			GroupName: "microServiceDeploymentPipeline"		

This CF (CloudFormation) template has a lot of parameters that you can use to fine-tune your installation. This template assumes that you have created one ssh key file named “ssh-key-ohio”. If you want to use a different ssh key file then just replace the name with your ssh key file name. The next step is to create a CF Stack using the template which is given above. This will create one AWS CodeBuild project that can be used to create the EKS cluster. Once the CodeBuild project is being created then go to the AWS CodeBuild project and click the Start Build button to start the process. If things have been configured as described above then finally it will create the desired EKS Cluster with your own SSH Key pair and desired node size. Hope this helps you to get started with AWS EKS using CodeBuild.

Curious about AIOps?

Solve problems in seconds with a comprehensive AI-powered observability solution.

Did you know that CloudAEye supports sophisticated log management and monitoring with anomaly detection for EKS? Request a free demo today!

Atiqur Rahman

Atiqur Rahman works as a Pricipal Engineer at CloudAEye. He graduated from BUET, the top engineering university in Dhaka, Bangladesh. He is an AWS certified solutions architect. He has successfully achieved 4 certifications from AWS including Cloud Practitioner, Solutions Architect, SysOps Administrator, and Developer Associate. He has more than 12 years of working experience with designing complex SaaS applications. His YouTube channel has over 3K subscribers!