Skip to content

kaizenacademy/project-nodejs-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Node.js Application - Cloud-Native Deployment

Project Overview

This project demonstrates a complete cloud-native deployment of a Node.js Nyan Cat application on AWS EKS using modern DevOps practices. The application consists of a three-tier architecture with a MySQL database, Node.js API backend, and a web frontend, all containerized and deployed using Kubernetes. The infrastructure is provisioned using Terraform, with multiple deployment options including GitHub Actions CI/CD, Jenkins pipelines, and GitOps with ArgoCD. The project showcases best practices for container orchestration, infrastructure as code, automated testing, security scanning, and continuous deployment in a production-ready environment.

Main Project Components

Application Services - Three-tier microservices architecture deployed via Helm charts:

  • MySQL - StatefulSet with EBS persistent storage (1Gi gp3), ClusterIP service on port 3306
  • API - Node.js backend Deployment with HPA (1-5 replicas, 50% CPU/80% memory targets), connects to MySQL
  • Web - Node.js frontend Deployment with HPA (1-5 replicas), communicates with API service
  • All services run in nodejs namespace with resource limits (64-128Mi memory, 100-250m CPU)

Infrastructure as Code - Terraform modules for AWS EKS infrastructure:

  • cluster - EKS 1.28+ with managed node groups, VPC, security groups, OIDC provider, IAM roles
  • backend-bucket - S3 bucket for Terraform state with versioning and AES256 encryption
  • github-oidc-policy - GitHub Actions OIDC trust policy for Role-GitHubActionsTerraformEKSInfra
  • modules/iam-roles - EKS cluster role, node role, EBS CSI driver role, ALB controller role
  • modules/helm - Reusable Helm deployment module for application charts

CI/CD Pipelines - GitHub Actions workflows with OIDC authentication:

  • setup_github_oidc.yaml - Configure GitHub OIDC provider and create Role-GitHubActionsTerraformEKSInfra for workflow authentication
  • create_buckets.yaml - Create S3 bucket for Terraform state storage with versioning and encryption
  • create_clusters.yaml - Provision EKS cluster with Terraform including VPC, node groups, IAM roles, and OIDC provider
  • deploy_applications.yaml - Deploy full stack (MySQL, API, Web) with Metrics Server, EBS CSI driver, and HPA configuration
  • deploy_argocd.yaml - Deploy ArgoCD with Helm including IRSA roles for ECR access and automated password configuration
  • deploy_jenkins.yaml - Deploy Jenkins with Helm including persistent storage, RBAC, and Kaniko IRSA for ECR builds

GitOps with ArgoCD - Declarative application deployment with automated sync:

  • api_app.yaml / web_app.yaml / mysql_app.yaml - ArgoCD Application manifests with Helm values and sync policies
  • nodejs-app-stack.yaml - App of Apps pattern managing all three services
  • IRSA roles: Role-ArgoCD-Deployment (ECR/EKS/S3), Role-ArgoCD-RepoServer (ECR read), Role-ArgoCD-ImageUpdater (ECR monitoring)
  • Auto-sync, self-heal, and prune enabled for continuous deployment

Jenkins CI/CD - Alternative CI/CD platform with Kaniko builds:

  • Jenkinsfile - Multi-stage pipeline: checkout → Kaniko build → ECR push → kubectl deploy → test
  • Deployed via Helm chart with 5Gi persistent storage (jenkins-storageclass)
  • RBAC: jenkins-cd ClusterRole with full namespace access
  • IRSA: Role-JenkinsKanikopushECR for ECR authentication

Setup Instructions:

1. Configure AWS IAM User and Keys

You need an AWS user that GitHub Actions can use to deploy infrastructure.

  1. Go to AWS Console → IAM → Users → Add user

    • User name: user-devops or any you like
    • Enable: Programmatic access
  2. Attach permissions (choose either full access or least privilege):

    • AmazonS3FullAccess → needed for Terraform state in S3
    • AdministratorAccess → full control for EC2, VPC, IAM
      (or create your own least-privilege policy for tighter security)
  3. After creation, download the credentials file (.csv) or just copy from AWS.
    It contains:

    • AWS_ACCESS_KEY_ID
    • AWS_SECRET_ACCESS_KEY
  4. Store these in GitHub as secrets:

    • Go to GitHub → Your Organization → Settings → Secrets and variables → Actions
    • Add two organization secrets (or repo-level if you prefer):
      • AWS_ACCESS_KEY_ID_DEV → paste the access key
      • AWS_SECRET_ACCESS_KEY_DEV → paste the secret key

2. Configure GitHub Token for Private Repository Access

If your workflows in a public repo need to use a private repo, configure a token.

  1. Generate a token

    • Go to GitHub → Organization → Settings → Developer settings → Personal access tokens → Fine-grained tokens
    • Click Generate new token
    • Under "Resource owner", select your organization
    • Limit access only to the private repo(s) you want
  2. Set required permissions

    • Repository → Contents: Read (mandatory to clone)
    • Repository → Metadata: Read (auto-enabled)
    • (Optional) Contents: Read & Write if workflows need push/write
    • Admin access is not required
  3. Save the token as a GitHub secret

    • Go to Org → Settings → Secrets and variables → Actions → New organization secret
    • Name it: PRIVATE_REPO_TOKEN
    • Paste the token value
    • Assign to all repositories or only the one hosting workflows

3. Configure GitHub Secrets

Go to your repo(with project) Settings → Secrets and variables → Actions and add:

  • AWS_ACCOUNT_ID - Your AWS Account ID
  • AWS_ACCESS_KEY_ID - From IAM user creation on AWS
  • AWS_SECRET_ACCESS_KEY - From IAM user creation
  • DOCKERHUB_USERNAME - Your Docker Hub account
  • DOCKERHUB_TOKEN - Docker Hub → Account Settings → Security

4. (optional) Deploy Bastion VM on AWS - Install the following tools before deploying the application:

Deploy Ubuntu 22 VM 'Bastion' on your default VPC, and in security group open ports 22, 80 and 8080. Install on VM next applications(optional):

1. AWS CLI (v2.x or later)

2. kubectl (v1.28 or later)

3. Terraform (v1.6.0 or later)

4. Helm (v3.12 or later)

5. Docker (v24.x or later)

5. Deploy infrastrucutre

  • Run workflow setup_github_oidc.yaml - Configure GitHub OIDC provider and create all needed Roles for workflow authentication
  • Run workflow create_buckets.yaml - Create S3 bucket for Terraform state storage with versioning and encryption
  • Run workflow create_clusters.yaml - Provision EKS cluster with Terraform including VPC, node groups, IAM roles, and OIDC provider
  • Run workflow deploy_applications.yaml - Deploy full stack (MySQL, API, Web) with Metrics Server, EBS CSI driver, and HPA configuration

6. Deploy/Access ArgoCD

  • Run workflow deploy_argocd.yaml to deploy ArgoCD with LoadBalancer

Access ArgoCD UI:

# Get LoadBalancer URL
kubectl get svc argocd-server -n argocd

# Get admin password
kubectl get secret argocd-secret -n argocd -o jsonpath="{.data.admin\.password}" | base64 --decode
echo ""

# Access via browser: http://<LOADBALANCER-URL>
# Username: admin
# Password: (from command above)

Configure Repository Access (For Private Repos):

If your repository is private, ArgoCD needs credentials:

# Create GitHub Personal Access Token at: https://github.com/settings/tokens
# Select scope: 'repo' (Full control of private repositories)

# Add repository to ArgoCD
argocd repo add https://github.com/K8-Team/project-nodejs-app.git \
    --username YOUR_GITHUB_USERNAME \
    --password YOUR_GITHUB_TOKEN \
    --insecure-skip-server-verification

# Verify
argocd repo list

Deploy NodeJS Applications with ArgoCD (GitOps):

# Apply ArgoCD applications (after configuring repository access)
kubectl apply -f ArgoCD/mysql_app.yaml
kubectl apply -f ArgoCD/api_app.yaml
kubectl apply -f ArgoCD/web_app.yaml

# OR use App of Apps pattern (deploys all three)
kubectl apply -f ArgoCD/nodejs-app-stack.yaml

# Check status
argocd app list
argocd app get api

7. Deploy/Access Jenkins

# Port-forward to Jenkins
kubectl port-forward -n jenkins svc/jenkins 8080:8080

# Open browser: http://localhost:8080
# Username: admin
# Get Jenkins password
kubectl get secret -n jenkins jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode
echo
# Password: (from above command)

Configure Jenkins Pipeline

  1. In Jenkins UI, click "New Item"
  2. Enter name: CD
  3. Select "Pipeline"
  4. Under Pipeline, select "Pipeline script from SCM"
  5. SCM: Git
  6. Repository URL: https://github.com/YOUR_USERNAME/project-nodejs-app.git
  7. Script Path: Jenkins-Deployment/Jenkinsfile
  8. Click "Save"

8. Deploy NodeJS Applications with Helm (Manual):

# Create namespace
kubectl create namespace nodejs

# Deploy MySQL
helm install mysql ./Kubernetes-Helm/mysql \
  --namespace nodejs \
  --set statefulset.image.tag=8.0

# Deploy API
helm install api ./Kubernetes-Helm/api \
  --namespace nodejs \
  --set deployment.image.repository=$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com/nodejs-nyan-app/api \
  --set deployment.image.tag=latest

# Deploy Web
helm install web ./Kubernetes-Helm/web \
  --namespace nodejs \
  --set deployment.image.repository=$(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com/nodejs-nyan-app/web \
  --set deployment.image.tag=latest

Required IAM Roles and Kubernetes Roles:

AWS IAM Roles

  • Role-GitHubActionsTerraformEKSInfra - Allows GitHub Actions workflows to authenticate with AWS and manage EKS infrastructure.
  • Role-cluster-role-{cluster_name} - Provides permissions for the EKS control plane to manage AWS resources.
  • Role-node-group-role-{cluster_name} - Grants EC2 instances in EKS node groups permissions to join the cluster.
  • Role-aws-load-balancer-controller-{cluster_name} - Enables the AWS Load Balancer Controller to create and manage load balancers.
  • Role-CSIdriverECRtoEBS - Allows the EBS CSI driver to create and manage EBS volumes for persistent storage.
  • Role-JenkinsKanikopushECR - Grants Jenkins Kaniko pods permission to build and push Docker images to ECR.
  • Role-ArgoCD-Deployment - Provides ArgoCD Application Controller with access to ECR, EKS, Secrets Manager, and S3.
  • Role-ArgoCD-RepoServer - Allows ArgoCD Repo Server to pull images from ECR and access Helm charts.
  • Role-ArgoCD-ImageUpdater - Enables ArgoCD Image Updater to monitor ECR for new image tags.

Kubernetes RBAC Roles

  • jenkins-cd-role - Grants Jenkins service account cluster-wide permissions to deploy applications.
  • argocd-manager-role - Provides ArgoCD service account with full cluster access to manage resources.

About

CI/CD, Deployments, Infra

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages