Skip to main content

Command Palette

Search for a command to run...

CI/CD: GitHub Actions Pipeline for Automated AWS Deployment

Updated
4 min read

Project Difficulty: ⭐ ⭐ ⭐

Project Goal: To design and implement a CI/CD pipeline using GitHub Actions that automates the build, testing, and deployment of an application to AWS Kubernetes Cluster. This pipeline eliminates manual deployment steps ensuring faster, more reliable releases, improves code quality through continuous integration, and demonstrates my practical experience with modern DevOps practices and cloud infrastructure.

The running CI workflow:

A simple trick I recommend for building a complex pipeline is to outline all the steps in simple words before diving deeper to define the actions required.

This is what I mean:

Checkout & Build (Node) → Upload ArtifactsAuthenticate (Docker) → Dockerize & PushAuthenticate (AWS/EKS) → Deploy (Kubectl) → Verify Deployment.

Here's the workflow and exposition of what the pipeline does. This part takes care of Countinuous integration:

Line 10-33 -: This build-test job is the CI validation stage. It ensures the application is installable, buildable, and ready to be packaged before anything moves toward deployment.

This job runs on a fresh Ubuntu runner (for the working directory in this job, I've set to /app because my package.json and server.js lives in that folder hence commands must execute in /app for this pipeline to not fail). Then It checks out the code using pre-defined Actions, sets up Node.js v20 via actions/setup-node, installs dependencies, and builds the app (--if-present prevents failure if no build script exists) and Finally uploads a build artifacts using actions/upload-artifact so downstream jobs can reuse the exact build output > ensures consistency across the pipeline and avoids redundant work.

Line 36-57 -: This job handles containerization and image distribution after a successful build.

It runs on a fresh Ubuntu runner and depends on the build-test job (needs:build-test), ensuring only validated code is packaged. It checks out the code using GitHub Actions, then authenticates to DockerHub via docker/login-action using stored secrets. Next, it builds the Docker image from the project context and pushes it using docker/build-push-action. The image (scheduler-app) is tagged with both a static version (v2.1) and a unique commit SHA, enabling version control and traceability across deployments.

Line 60-90 -: This part takes care of Countinuous deployment. Handles the deployment to AWS EKS Cluster.

The job runs after the image is built and pushed needs: docker-build-push and checks out the deployment configs using GitHub Actions and then configures AWS access via aws-actions/configure-aws-credentials, installs kubectl, and authenticates to the Amazon EKS cluster by updating the kubeconfig.

Finally, For the deploy-AWS-eks job to run successfully, there must be:

  1. AWS Credentials stored as AWS_SECRET_ACCESS_KEY and AWS_ACCESS_KEY_ID for the pipeline to consume in github secrets just as docker requires (DOCKER_USERNAME. and DOCKER_PASSWORD)

  2. The AWS k8 cluster. I will create a cluster with command eksctl create cluster --name node-app-prod-us-east --region us-east-1 --nodes 2 via AWS cli.

  • Creates a cluster in AWS named node-app-prod-us-east in us-east-1 region and two nodes will be provisioned 👇

The CI/CD pipeline can now run the full aws eks update-kubeconfig in Line 80 to update kubeconfig file in the kubernetes cluster running on AWS

Once connected, it verifies cluster access (kubectl get nodes), applies the Kubernetes manifests to deploy the application (my scheduler-deployment.yaml), and confirms the rollout by checking the deployment status (get deployments).

Once this is done I run a git push to trigger the workflow to run in Github.

The CI/CD pipeline job is now completed

Heres the cluster

The application

My next project will demonstrate a few things on how to use kubectl to manage the nodes running these pods and their containers.

More from this blog