Skip to content

mayank4singh/Three_Tier_AWS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Three-Tier Product Catalog β€” AWS ECS + CloudFormation + Jenkins CI/CD

AWS Docker Jenkins CloudFormation

A production-style three-tier web application deployed on AWS ECS Fargate using Infrastructure as Code (CloudFormation) with a fully automated Jenkins CI/CD pipeline triggered by GitHub webhooks.


πŸ“ Architecture

                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚        Internet (User)           β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚ HTTP
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚   Frontend ALB (Public)          β”‚
                        β”‚   internet-facing                β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚ Port 3000
                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚         Frontend ECS Service             β”‚
                   β”‚         Node.js / Express                β”‚
                   β”‚         (Public Subnet - Fargate)        β”‚
                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚ /api/* proxy
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚   Backend ALB (Internal)         β”‚
                        β”‚   VPC-only                       β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                       β”‚ Port 5000
                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                   β”‚         Backend ECS Service              β”‚
                   β”‚         Node.js / Express REST API       β”‚
                   β”‚         (Private Subnet - Fargate)       β”‚
                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ—‚οΈ Project Structure

Three_Tier_AWS/
β”œβ”€β”€ Frontend/
β”‚   β”œβ”€β”€ app.js              # Express server with API proxy
β”‚   β”œβ”€β”€ public/
β”‚   β”‚   └── index.html      # Product Catalog UI
β”‚   β”œβ”€β”€ package.json
β”‚   └── Dockerfile
β”œβ”€β”€ Backend/
β”‚   β”œβ”€β”€ app.js              # REST API (products CRUD)
β”‚   β”œβ”€β”€ package.json
β”‚   └── Dockerfile
β”œβ”€β”€ cloudformation/
β”‚   └── stack.yaml          # Complete AWS infrastructure
β”œβ”€β”€ Jenkinsfile             # CI/CD pipeline definition
β”œβ”€β”€ .gitignore
└── README.md

πŸ› οΈ Tech Stack

Layer Technology
Frontend Node.js, Express, HTML/CSS/JS
Backend Node.js, Express REST API
Containerization Docker
Container Registry Amazon ECR
Compute Amazon ECS Fargate
Load Balancing Application Load Balancer (ALB)
Networking VPC, Public/Private Subnets, NAT Gateway
Infrastructure AWS CloudFormation
CI/CD Jenkins (push-based GitHub webhook)
Source Control GitHub

πŸ”„ CI/CD Pipeline Flow

Developer pushes code
        β”‚
        β–Ό
    GitHub Repo
        β”‚  webhook POST
        β–Ό
  Jenkins Server
        β”‚
        β”œβ”€β”€ Stage 1: Checkout code from GitHub
        β”œβ”€β”€ Stage 2: Build Frontend Docker image
        β”œβ”€β”€ Stage 3: Build Backend Docker image
        β”œβ”€β”€ Stage 4: Push images to Amazon ECR
        β”œβ”€β”€ Stage 5: Update ECS Frontend Service
        β”œβ”€β”€ Stage 6: Update ECS Backend Service
        └── Stage 7: Verify deployment stable

Every git push to the main branch automatically triggers the full pipeline β€” no manual steps required.


☁️ Infrastructure (CloudFormation)

The cloudformation/stack.yaml creates all AWS resources in a single deployment:

Resource Details
VPC 10.0.0.0/16 with DNS enabled
Public Subnets 2 AZs for Frontend ALB + Frontend ECS
Private Subnets 2 AZs for Backend ECS
NAT Gateway Allows private subnets to pull ECR images
Internet Gateway Public internet access
Frontend ALB Public-facing, routes to Frontend ECS
Backend ALB Internal-only, routes to Backend ECS
ECS Cluster Fargate-based, no EC2 to manage
Frontend Service 1 task, port 3000
Backend Service 1 task, port 5000
Security Groups Strict least-privilege rules per tier
IAM Role ECS Task Execution Role
CloudWatch Logs 7-day retention for both services

Security Group Rules (Least Privilege)

Internet β†’ Frontend ALB SG  (port 80)
Frontend ALB SG β†’ Frontend ECS SG  (port 3000)
Frontend ECS SG β†’ Backend ALB SG   (port 5000)
Backend ALB SG  β†’ Backend ECS SG   (port 5000)

Each tier only accepts traffic from the tier directly above it.


πŸš€ Deployment Guide

Prerequisites

  • AWS CLI configured (aws configure)
  • Docker installed
  • Node.js installed
  • Jenkins server running

Step 1 β€” Clone the repo

git clone https://github.com/mayank4singh/Three_Tier_AWS.git
cd Three_Tier_AWS

Step 2 β€” Create ECR Repositories

AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
AWS_REGION=us-east-1

aws ecr create-repository --repository-name fullstack-frontend --region $AWS_REGION
aws ecr create-repository --repository-name fullstack-backend  --region $AWS_REGION

Step 3 β€” Build and Push Docker Images

# Login to ECR
aws ecr get-login-password --region $AWS_REGION | \
  docker login --username AWS --password-stdin \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com

# Build and push Frontend
docker build -t fullstack-frontend ./Frontend
docker tag fullstack-frontend:latest \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/fullstack-frontend:latest
docker push \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/fullstack-frontend:latest

# Build and push Backend
docker build -t fullstack-backend ./Backend
docker tag fullstack-backend:latest \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/fullstack-backend:latest
docker push \
  $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/fullstack-backend:latest

Step 4 β€” Deploy CloudFormation Stack

aws cloudformation deploy \
  --template-file cloudformation/stack.yaml \
  --stack-name fullstack-app \
  --region us-east-1 \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    FrontendImage=$AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/fullstack-frontend:latest \
    BackendImage=$AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/fullstack-backend:latest

Get the live URL

aws cloudformation describe-stacks \
  --stack-name fullstack-app \
  --query 'Stacks[0].Outputs[?OutputKey==`AppURL`].OutputValue' \
  --output text

Open the URL in your browser β€” your app is live! πŸŽ‰


Step 5 β€” Configure Jenkins CI/CD

  1. Install plugins: Git, GitHub Integration, Pipeline
  2. Add credentials in Jenkins:
    • aws-access-key-id β€” AWS Access Key
    • aws-secret-access-key β€” AWS Secret Key
  3. Create a Pipeline job:
    • Definition: Pipeline script from SCM
    • SCM: Git β†’ https://github.com/mayank4singh/Three_Tier_AWS.git
    • Branch: */main
    • Script Path: Jenkinsfile
  4. Enable: βœ… GitHub hook trigger for GITScm polling

Step 6 β€” Configure GitHub Webhook

  1. Go to repo Settings β†’ Webhooks β†’ Add webhook
  2. Payload URL: http://YOUR_JENKINS_IP:8080/github-webhook/
  3. Content type: application/json
  4. Events: βœ… Just the push event

🌐 How Frontend Connects to Backend

The frontend and backend communicate through the ALBs, not directly:

Browser
  β”‚  GET /api/products
  β–Ό
Frontend ALB
  β”‚
  β–Ό
Frontend ECS (Express server)
  β”‚  proxy: GET http://internal-backend-alb:5000/api/products
  β–Ό
Backend ALB (internal)
  β”‚
  β–Ό
Backend ECS (REST API)
  β”‚
  └── returns JSON

The BACKEND_URL environment variable is automatically injected by CloudFormation using !Sub "http://${BackendALB.DNSName}:5000". The frontend Express server proxies all /api/* requests to the backend β€” the browser never directly calls the backend ALB.


πŸ“‘ API Endpoints

Method Endpoint Description
GET /health Health check
GET /api/products List all products
GET /api/products/:id Get single product
POST /api/products Add new product
DELETE /api/products/:id Delete product

πŸ§ͺ Local Development

# Terminal 1 β€” Start Backend
cd Backend
npm install
node app.js
# Running on http://localhost:5000

# Terminal 2 β€” Start Frontend
cd Frontend
npm install
node app.js
# Running on http://localhost:3000

Open http://localhost:3000 in your browser.


Built with ❀️ and lots of β˜• by Mayank Singh

About

Three-tier architecture on AWS ECS Fargate using Docker, ECR, CloudFormation, and a push-triggered Jenkins CI/CD pipeline.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors