Overview
This project demonstrates the migration of an on-premise Java Spring Boot application to AWS using a "Replatforming" strategy. The application is containerized using Docker and deployed to Amazon ECS (Fargate) for serverless compute, utilizing Amazon RDS for managed persistence.
Problem Statement
An on-premise Java Spring Boot application with a MySQL database needs to be migrated to AWS to leverage cloud scalability, reliability, and managed services while minimising operational overhead.
Migration Strategy: Replatforming
Replatforming involves moving the application to a new platform with minimal changes to the application code.
- App: Java Spring Boot "Customer Management Service."
- Hosting: Running on a physical Linux server (or VM) using java -jar app.jar.
- Database: Local MySQL instance installed on the same server.
- Issues: Scaling is hard (manual hardware upgrades), single point of failure (if the server dies, the app dies), maintenance overhead (patching OS).
Goals & Objectives:
- Containerize the existing Java Spring Boot application using Docker.
- Deploy the containerized application to AWS using ECS Fargate.
- Use Amazon RDS for the MySQL database to offload database management tasks.
- Implement Infrastructure as Code (IaC) using Terraform for reproducible deployments.
- Set up a CI/CD pipeline for automated deployments using GitHub Actions (or AWS CodePipeline).
- Ensure security best practices, including network isolation and secrets management.
- Optimize for cost and performance.
- Document the architecture and decisions made during the migration.
- Provide clear instructions for running the application locally and deploying to AWS.
- Include monitoring and logging for operational visibility.
- Facilitate easy rollback and updates through deployment strategies.
- Ensure high availability and fault tolerance in the deployed architecture.
- Leverage AWS managed services to reduce operational overhead.
- Promote best practices in cloud architecture and DevOps.
- Create a modular and reusable Terraform codebase for future projects.
π Architecture
Pattern: Microservices-ready Containerization on Serverless Infrastructure.
Traffic Flow: Internet -> Application Load Balancer (Public Subnet) -> ECS Fargate Tasks (Private Subnet).
Data Flow: ECS Tasks -> RDS MySQL (Private Subnet).
Security:
Database is strictly isolated in private subnets.
Security Groups act as a virtual firewall (App SG -> DB SG on port 3306).
Secrets managed via Environment Variables (in prod, use AWS Parameter Store).
By this , we achieve : >>>>
Application Load Balancer (ALB) (HTTPS/443).
ALB distributes traffic across ECS Tasks (Docker containers) running in private subnets across two Availability Zones (AZ).
ECS Tasks talk to Amazon RDS (MySQL) located in a private database subnet.
ECS Tasks pull database credentials securely from AWS Systems Manager Parameter Store (No hardcoded passwords!).
π§ Architectural Decisions & Trade-offs
- Compute: ECS Fargate vs. EC2 Decision: Fargate. Reasoning: Removing the burden of OS patching and server management allows the team to focus on code. Trade-off: Fargate is slightly more expensive per vCPU than raw EC2, but saves significant operational hours (Human cost > Infrastructure cost).
- Database: Amazon RDS vs. EC2 Hosted DB Decision: Amazon RDS. Reasoning: Automated backups, point-in-time recovery, and easy Multi-AZ setup for High Availability. Trade-off: Less control over the underlying OS configuration, but guarantees 99.95% uptime.
- Optimization Strategy Cost: Used Linux-based containers (cheaper than Windows). Implemented Auto-scaling based on CPU load.(Here,I used t3.micro for the DB and low CPU for Fargate. In a real scenario, I would implement ECS Service Auto Scaling based on CloudWatch CPU metrics to handle traffic spikes automatically.) Performance: The application is stateless, allowing horizontal scaling behind the Load Balancer.
- Security Network Isolation: Placed ECS tasks and RDS instances in private subnets. Access Control: Used Security Groups to restrict traffic between components. Secrets Management: AWS Parameter Store or Secrets Manager for production. IAM Roles: Least privilege principle applied to ECS Task Execution Role. Data Encryption: Enabled encryption at rest for RDS and enforced TLS for data in transit. Monitoring & Logging: Integrated AWS CloudWatch for logs and metrics. 5.Infrastructure as Code Tool: Terraform Reasoning: Enables version control, repeatability, and easy collaboration. Trade-off: Initial learning curve, but long-term benefits outweigh the costs. Modules: Used Terraform modules for VPC, ECS, RDS, and Load Balancer to promote reusability. State Management: Used remote state storage in S3 with state locking via DynamoDB.
- CI/CD Pipeline (GitHub Actions) Tool: GitHub Actions (or AWS CodePipeline).
Reasoning: Automates build, test, and deployment processes.
Trade-off: Initial setup time, but reduces manual errors and speeds up deployments.
Steps: On push to main branch, build Docker image, push to ECR, and deploy to ECS.
Workflow Steps:
Integration: On every push to main, Maven builds the JAR and runs unit tests to ensure code quality.
Delivery:
Authenticates with AWS using IAM credentials stored in GitHub Secrets.
Builds a Docker image and pushes it to Amazon ECR.
Deployment:
Triggers an ECS Service Update (--force-new-deployment).
ECS pulls the new image from ECR and performs a rolling update (starts new container, health check passes, drains old container).
Design Choice: 'Rolling Update'
I utilized ECS's native rolling update mechanism. This ensures zero downtime during deployment.
The Load Balancer keeps sending traffic to the old version until the new version is healthy (Green/Blue deployment can be added for advanced scenarios).
π How to Run Locally (Docker)
Build: docker build -t aws-poc-app .
Run: docker run -p 8080:8080 -e DB_URL=jdbc:mysql://host.docker.internal:3306/db -e DB_USER=root -e DB_PASS=root aws-poc-app Alternatively, use Docker Compose if a docker-compose.yml is provided.
Access: Open http://localhost:8080 in your browser.
Database: Ensure a local MySQL instance is running and accessible.
Stop: docker stop <container_id>
Remove: docker rm <container_id>
Logs: docker logs <container_id>
Debug: Use docker exec -it <container_id> /bin/bash to access the container shell.
Environment Variables: Set DB_URL, DB_USER, and DB_PASS for database connectivity.
Network: Use host.docker.internal to connect to host services from Docker on Windows/Mac. Option 2: Use Docker desktop with WSL2 backend for Linux users.(for beginners)
βοΈ Deployment Steps (Terraform)
Navigate to infrastructure/.
Run terraform init.
Run terraform apply.
Terraform will output the Load Balancer URL.
π Project Structure
aws-migration-poc/
βββ src/ # Java Spring Boot Application Source Code
βββ Dockerfile # Dockerfile for containerizing the application
βββ infrastructure/ # Terraform scripts for AWS infrastructure
β βββ provider.tf # provider configuration for AWS
β βββ vpc.tf # VPC and Subnets configuration
β βββ ecs-cluster.tf # ECS Cluster
β βββ ecs-service.tf # ECS Fargate Service configuration
| βββ ecs-task-def.tf # ECS Task Definition
| βββ ecr.tf # ECR Repository configuration
| βββ network.tf # VPC, Subnets, andSecurity Groups configuration
β βββ database.tf # RDS Instance configuration
β βββ iam.tf # IAM Roles and Policies
β βββ variables.tf # Input variables for Terraform
β βββ outputs.tf # Output values from Terraform
βββ README.md # Project documentation
βββ .gitignore # Git ignore file
Follow my github account for codebase!!!

Top comments (0)