CI CD for EKS Using AWS CodePipeline¶
Now, let's see how you can set up CI/CD for a containerized application on EKS using AWS CodePipeline.
Step 1: Create a Private GitHub Repository¶
In the first step let's create a private github repository. Let's call it node-app
. You can name it anything you prefer.
Make sure to choose gitignore
for Node.js application. This will create a .gitignore
file for Node.js application.
Step 2: Clone the GitHub Repository¶
Now, let's clone the repository on local machine so that we can make changes and push it to the repo.
Step 3: Test the Application Locally¶
This is a simple Node.js app using express. Make sure you have Node.js
and npm
installed on your local machine so that you can test it locally.
Assuming your folder structure looks like the one below:
Run the following command to install the npm packages:
Run the following command to test the app:
Now, open another terminal and call localhost on port 5000.
Or, visit these URLs in any browser.
Step 4: Containerize the App and Test it Locally¶
Let's create a Dockerfile
and create a Docker image out of it. Also, add a .dockerignore
file.
Note
A .dockerignore
is a configuration file that describes files and directories that you want to exclude when building a Docker image.
Assuming your folder structure looks like the one below:
Run the following command to build the docker image:
Now, run a container from the docker image:
Verify the application endpoints:
Stop and delete the container:
# list containers
docker ps -a | grep my-node-container
# stop the container
docker stop my-node-container
# Delete the container
docker rm my-node-container
Step 5: Create Amazon ECR Repository¶
Create ECR repository to which we will later push the my-node-app:latest
image that we built.
aws ecr create-repository \
--repository-name my-node-app \
--image-scanning-configuration scanOnPush=true
Step 6: Create Kubernetes Manifest Files¶
Let's prepare kubernetes manifest files for our application.
Note that CONTAINER_IMAGE
is a placeholder that will be replace with actual ECR image URI during deployment.
Step 7: Create Buildspec for AWS CodeBuild¶
A buildspec is a collection of build commands and related settings, in YAML format, that CodeBuild uses to run a build.
The script performs the following actions:
- Verifies whether the necessary dependencies, such as kubectl and aws-cli, are installed.
- Logs into Amazon ECR.
- Builds the Docker image.
- Pushes the image to ECR.
- Updates the deployment manifest by substituting the CONTAINER_IMAGE placeholder with the newly pushed image on ECR.
- Deploys the kubernetes manifests to EKS.
At this point your git repository folder structure should look like the following:
|-- nodeapp
│ |-- k8s-manifests
| | |-- 00-namespace.yml
| | |-- deployment.yml
| | |-- service.yml
│ |-- .dockerignore
│ |-- .gitignore
│ |-- Dockerfile
│ |-- buildspec.yml
│ |-- package-lock.json
│ |-- package.json
│ |-- server.js
Step 8: Create AWS CodeBuild Project¶
AWS CodeBuild is a fully managed continuous integration service that compiles source code, runs tests, and produces software packages that are ready to deploy.
Before we proceed, let's create an IAM role for CodeBuild project. It is important that you create role first otherwise a role will be created in service-role
namespace and AWS EKS doesn't work with that role. This is a bug.
Now, follow the instruction below to create a CodeBuild project:
- Go to AWS CodeBuild console
- Click on
Build projects
in the left navigation panel. - Click on
Create build project
button on the top right corner. - In the
Project configuration
section, provide theProject name
. We'll name itnode-app
. - In the
Source
section selectGitHub
as source provider. - For Repository select
Repository in my GitHub account
. - Select
Connect using OAuth
and click onConnect to GitHub
. - A new window will open for authorization.
- Click on
Authorize aws-codesuite
after you have selected the required permissions. - In the
Source version
provide branch name. It should bemaster
in our case. - In the
Environment
section, selectManaged Image
. - Select
Amazon Linux 2
as theOperating system
. - In the
Runtime
selectstandard
. - For
Image
select the latest version.7.0
as of today. - For
Image version
selectAlways use the latest image for this runtime version
. - Check the
Privileged
checkbox. - In the
Service role
selectexisting
. - In the
Buildspec
section, select Use abuildspec file
. - In the
Buildspec name
provide the name of the buildspec file. It isbuildspec.yml
in our case. - In the
Logs
section, check theCloudWatch logs
. - Leave the
Group name
empty. (Auto create). - Leave the
Stream name
empty. (Auto create).
We need to assign the required permissions to the role attached to the CodeBuild project.
Open the service role attached to the codebuild project and assign the following permissions:
AmazonEC2ContainerRegistryPowerUser
: Allows codebuild project to push image to the ECR repository.- Add the following inline policy. This allows codebuild project to get required EKS permissions.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster"
],
"Resource": "*"
}
]
}
Note
It is recommended to use granular permissions but for simplicity we are avoiding that.
Also, edit the CodeBuild project and add the following environent variables:
REPOSITORY_URI
: ECR repository URI that we createdCLUSTER_NAME
: EKS cluster name
Now, update the aws-auth
ConfigMap to allow CodeBuild to apply k8s manifest files:
# View the current ConfigMap
kubectl get configmap aws-auth -n kube-system -o yaml
# Edit the aws-auth ConfigMap
export KUBE_EDITOR=nano
kubectl edit configmap aws-auth -n kube-system
Update the aws-auth
ConfigMap by adding the following item in the mapRoles
list as shown below:
mapRoles: |
- groups:
- system:masters
rolearn: <codebuild-service-role-arn>
username: <codebuild-project-service-role-name>
Now, trigger the CodeBuild project manually to test if deployment is working as expected.
Step 9: Create AWS CodePipeline¶
Create an AWS CodePipeline to trigger the build whenever a change is pushed to the repository in the master
branch.
Follow the instruction below to create the CodePipeline:
- Go to AWS CodePipeline console.
- Click on
Create pipeline
. - Provide
Pipeline name
. - In
Service role
, selectNew service role
. - Leave everything else as default.
- Click on
Next
. - In Source provider, select
GitHub (Version 2)
. - In
Connection
, click onConnect to GitHub
. - A new window will open to create a new connection.
- Provide connection name and authorize.
- In
GitHub Apps
click onInstall a new App
. - Authorize and install app.
- In
Repository name
select the required repository. - In
Branch name
selectmaster
. - Check the box that says
Start the pipeline on source code change
. - Leave everything else as default
- Click on
Next
. - In
Build
, selectAWS CodeBuild
asBuild provider
. - Select
Region
. - Select
Project name
. - Leave everything else as default.
- Click on
Next
. - Skip deploy stage.
- Click on
Create pipeline
.
Step 10: Verify the Working of CI/CD Pipeline¶
Make some changes to your repository and verify that the pipeline gets triggered automatically.
Change the version of the app to v2
and verify if the changes are reflected in EKS cluster.
References: