DEV Community

Dipak Prasad
Dipak Prasad

Posted on

Building a Production-Grade AWS 3-Tier Java Application

A hands-on project building a production-grade 3-tier Java application on AWS using Auto Scaling, ALB, RDS MySQL with Proxy, Redis caching, and secure networking. The focus is on real-world architecture, security, scalability, and operational best practices rather than demo-level setups.

This article walks through everything I built, step by step, and explains why each component exists.

What We’re Building

At the end of this project, the application looks like this:

User
 ↓
Route 53
 ↓
CloudFront
 ↓
Application Load Balancer
 ↓
EC2 Auto Scaling Group
 ↓               ↓
Redis Cache   RDS Proxy
                 ↓
         RDS MySQL + Read Replica
Enter fullscreen mode Exit fullscreen mode

Technology Stack

  • Backend: Java, Spring Boot
  • Compute: EC2 Auto Scaling Group
  • Networking: VPC, Subnets, IGW, NAT Gateway
  • Load Balancing: Application Load Balancer
  • Database: Amazon RDS MySQL + Read Replica
  • DB Connections: Amazon RDS Proxy
  • Secrets: AWS Secrets Manager (automatic rotation)
  • Cache: Amazon ElastiCache (Redis)
  • Edge: CloudFront
  • DNS: Route 53
  • Access: Bastion Host
  • Security: IAM Roles, Security Groups

PHASE 1: NETWORKING (FOUNDATION)

AWS Subnets

  1. Create VPC
  2. Create Subnets (8 total)
    • Public Subnets (2 total)
      • Used for Load Balancer, NAT Gateway, Bastion Host
    • Private App Subnets (2 total)
      • Used for EC2 Auto Scaling Group
    • Private DB Subnets (2 total)
      • Used for RDS, RDS Proxy, Read Replica
    • Private Cache Subnets (2 total)
      • Used for Redis (ElastiCache)
  3. Internet Gateway - Allows public subnets to access the internet.
    • Create Internet Gateway
    • Attach Internet Gateway to VPC
  4. NAT Gateway - Private subnets need outbound-only internet access.
    • Create a NAT Gateway in public subnet and allocate an elastic IP.
  5. Route Tables
    • Public Route Table
      • Route: 0.0.0.0/0Internet Gateway
      • Subnet Associate: public-a, public-b
    • Private Route Table
      • Route: 0.0.0.0/0NAT Gateway
      • Subnet Associate: private-app-*, private-db-*, private-cache-*
  6. Security Groups
    • ALB Security Group (alb-sg)
      • Inbound: 80, 443 from 0.0.0.0/0
      • Outbound: 8080 to app-sg
    • Bastion Security Group (bastion-sg)
      • Inbound: SSH (22) from your IP
      • Outbound: SSH to app-sg
    • App Security Group (app-sg)
      • Inbound: 8080 from alb-sg, 22 from bastion-sg
      • Outbound: All
    • DB Security Group (db-sg)
      • Inbound: 3306 from app-sg
      • Outbound: Local
    • Redis Security Group (redis-sg)
      • Inbound: 6379 from app-sg
      • Outbound: Local

PHASE 2: COMPUTE LAYER

  1. Create a Bastion Host - This is the only SSH entry point.
    • Subnet: public-a
    • Public IP: Enabled
    • SG: bastion-sg
  2. Create an Application Load Balancer
    • Type: Application
    • Scheme: Internet-facing
    • Subnets: public-a, public-b
    • SG: alb-sg
  3. Create a Target Group - ALB routes traffic to target groups, not directly to EC2.
    • Target type: Instance
    • Port: 8080
    • Health check path: /health
  4. Create a Launch Template
    • AMI: Ubuntu
    • Instance type: t3.micro
    • SG: app-sg
    • IAM Role: ec2-app-role
    • User data: #!/bin/bash sudo apt update -y && sudo apt upgrade -y sudo apt install default-jdk git -y sudo apt install maven -y
  5. Create an Auto Scaling Group
    • Subnets: private-app-a, private-app-b
    • Min: 1 | Desired: 2 | Max: 3
    • Attach ALB target group

PHASE 3: DATABASE LAYER

  1. Create DB Subnet Group (RDS must know which private subnets to use) and select private DB subnets.
  2. Create RDS MySQL database
  3. Create AWS Secret Manager for DB password and enable autamatic rotation.
  4. Create Read Replica
  5. Create RDS Proxy

PHASE 4: REDIS CACHE

  1. Create Cache Subnet Group and select private cache subnets
  2. Create Redis Cluster

PHASE 5: Cloudfront & Route53

  1. Request SSL Certificate
  2. Create CloudFront Distribution
  3. Create a hosted zone record

Source Code Link

To run the application:

git clone https://github.com/dipakprasad22/AWS-3tier-Java-Spring-Boot-App.git
mvn clean package
java -Xms256m -Xmx512m -jar app.jar
curl http://localhost:8080/health
http://<ALB-DNS-NAME>/hello
Enter fullscreen mode Exit fullscreen mode

Top comments (0)