- Goal
- Pre-Requisites
- Pre-Deployment
- VPC Deployment
- Maven (Build)
- 3-Tier Architecture
- Application Deployment
- Post-Deployment
- Validation
The primary objective of this project is to deploy a scalable, highly available, and secure Java application using a 3-tier architecture. The application will be hosted on AWS, utilizing various services like EC2, RDS, and VPC to ensure its availability, scalability, and security. The application will be accessible to end-users via the public internet.
Before starting the deployment, ensure you have the following:
-
AWS Free Tier Account:
- Sign up for an Amazon Web Services (AWS) Free Tier account.
- Set up the AWS CLI on your local machine.
- Configure your CLI with
aws configure
.
-
GitHub Account and Repository:
- Create a GitHub account if you don't have one.
- Fork the Java source code from the Java-Login-App repository to your GitHub account.
-
SonarCloud Account:
- Create an account on SonarCloud for static code analysis and code quality checks.
- Generate a SonarCloud token for integration with your GitHub repository.
-
JFrog Cloud Account:
- Sign up for a JFrog Cloud account.
- Set up a Maven repository in JFrog to store your build artifacts.
Creating a Global AMI involves installing necessary agents and software on an EC2 instance, which will be used to create custom AMIs for different components.
-
Install AWS CLI:
- Install AWS CLI by following the instructions here.
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" sudo installer -pkg AWSCLIV2.pkg -target / aws --version
-
Install CloudWatch Agent:
- Install CloudWatch Agent to monitor your EC2 instances.
sudo yum install amazon-cloudwatch-agent sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a start
-
Install AWS Systems Manager (SSM) Agent:
- The SSM Agent is necessary for managing EC2 instances via AWS Systems Manager.
sudo yum install amazon-ssm-agent sudo systemctl start amazon-ssm-agent sudo systemctl enable amazon-ssm-agent
Golden AMIs will be created for the different tiers (Nginx, Tomcat, Maven) of the architecture.
-
For Nginx:
- Launch an EC2 instance and install Nginx:
sudo amazon-linux-extras install nginx1.12 sudo systemctl start nginx sudo systemctl enable nginx
- Create a custom CloudWatch metric for memory usage:
#!/bin/bash while true; do memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}') aws cloudwatch put-metric-data --metric-name MemoryUsage --namespace Custom --value $memory_usage --dimensions InstanceId=$(curl http://169.254.169.254/latest/meta-data/instance-id) sleep 60 done &
-
For Apache Tomcat:
- Launch another EC2 instance and install Apache Tomcat:
sudo yum install java-11-openjdk-devel wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.53/bin/apache-tomcat-9.0.53.tar.gz sudo tar -xvzf apache-tomcat-9.0.53.tar.gz -C /opt/ sudo ln -s /opt/apache-tomcat-9.0.53 /opt/tomcat sudo sh /opt/tomcat/bin/startup.sh
- Configure Tomcat as a systemd service:
sudo nano /etc/systemd/system/tomcat.service
Add the following content:
[Unit] Description=Apache Tomcat Web Application Container After=network.target [Service] Type=forking Environment=JAVA_HOME=/usr/lib/jvm/jre Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid Environment=CATALINA_HOME=/opt/tomcat Environment=CATALINA_BASE=/opt/tomcat Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC' Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom' ExecStart=/opt/tomcat/bin/startup.sh ExecStop=/opt/tomcat/bin/shutdown.sh User=tomcat Group=tomcat UMask=0007 RestartSec=10 Restart=always [Install] WantedBy=multi-user.target
- Enable and start the Tomcat service:
sudo systemctl daemon-reload sudo systemctl start tomcat sudo systemctl enable tomcat
-
For Apache Maven Build Tool:
- Install Maven, Git, and JDK 11 on a separate EC2 instance:
sudo yum install git sudo yum install java-11-openjdk-devel wget https://mirrors.ocf.berkeley.edu/apache/maven/maven-3/3.8.4/binaries/apache-maven-3.8.4-bin.tar.gz sudo tar -xvzf apache-maven-3.8.4-bin.tar.gz -C /opt/ sudo ln -s /opt/apache-maven-3.8.4 /opt/maven
- Update the system PATH:
echo "export M2_HOME=/opt/maven" | sudo tee -a /etc/profile.d/maven.sh echo "export PATH=\$M2_HOME/bin:\$PATH" | sudo tee -a /etc/profile.d/maven.sh source /etc/profile.d/maven.sh
- Verify the installation:
mvn -version
-
Create VPCs:
- Create two VPCs for the application architecture:
aws ec2 create-vpc --cidr-block 192.168.0.0/16 --region us-east-1 aws ec2 create-vpc --cidr-block 172.32.0.0/16 --region us-east-1
-
NAT Gateway and Internet Gateway:
- Set up a NAT Gateway in the public subnet and an Internet Gateway for outbound access:
aws ec2 create-nat-gateway --subnet-id subnet-xxxx --allocation-id eipalloc-xxxx aws ec2 create-internet-gateway aws ec2 attach-internet-gateway --vpc-id vpc-xxxx --internet-gateway-id igw-xxxx
-
Transit Gateway:
- Create a Transit Gateway to allow communication between the VPCs:
aws ec2 create-transit-gateway aws ec2 attach-transit-gateway-vpc-attachment --transit-gateway-id tgw-xxxx --vpc-id vpc-xxxx
-
Route Tables:
- Update route tables for the private and public subnets to route traffic through the NAT Gateway and Internet Gateway:
aws ec2 create-route-table --vpc-id vpc-xxxx aws ec2 create-route --route-table-id rtb-xxxx --destination-cidr-block 0.0.0.0/0 --gateway-id igw-xxxx
-
Deploy Bastion Host:
- Launch an EC2 instance in the public subnet as a Bastion Host:
aws ec2 run-instances --image-id ami-xxxx --count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-xxxx --subnet-id subnet-xxxx --associate-public-ip-address
-
Security Groups:
- Create
a security group allowing SSH access from your IP:
aws ec2 create-security-group --group-name BastionSG --description "Security group for Bastion Host" --vpc-id vpc-xxxx
aws ec2 authorize-security-group-ingress --group-id sg-xxxx --protocol tcp --port 22 --cidr YOUR_IP/32
-
Launch EC2 Instance Using Maven AMI:
- Launch an EC2 instance using the Maven Golden AMI:
aws ec2 run-instances --image-id ami-maven --count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-maven --subnet-id subnet-maven
-
Clone the Repository:
- Connect to the instance and clone your GitHub repository:
git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git cd YOUR_REPO
-
Update
pom.xml
:- Update
pom.xml
with SonarCloud and JFrog deployment details.
- Update
-
Build the Application:
- Run the Maven build command to compile the project:
mvn clean install -s settings.xml
-
SonarCloud Integration:
- Integrate SonarCloud with Maven:
mvn sonar:sonar -Dsonar.projectKey=YOUR_PROJECT_KEY -Dsonar.organization=YOUR_ORGANIZATION -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=YOUR_SONAR_TOKEN
-
Deploy MySQL RDS:
- Create a MySQL RDS instance in the private subnet:
aws rds create-db-instance --db-instance-identifier mydbinstance --db-instance-class db.t2.micro --engine mysql --allocated-storage 20 --master-username admin --master-user-password password --vpc-security-group-ids sg-db --db-subnet-group-name mydbsubnetgroup
-
Network Load Balancer:
- Create a private-facing Network Load Balancer:
aws elbv2 create-load-balancer --name private-nlb --subnets subnet-xxxx subnet-yyyy --type network
-
Auto Scaling Group:
- Set up an Auto Scaling Group for the Tomcat instances:
aws autoscaling create-auto-scaling-group --auto-scaling-group-name tomcat-asg --launch-configuration-name TomcatLC --min-size 1 --max-size 3 --vpc-zone-identifier subnet-xxxx,subnet-yyyy
-
Public Network Load Balancer:
- Create a public-facing Network Load Balancer:
aws elbv2 create-load-balancer --name public-nlb --subnets subnet-xxxx subnet-yyyy --type network
-
Auto Scaling Group:
- Set up an Auto Scaling Group for the Nginx instances:
aws autoscaling create-auto-scaling-group --auto-scaling-group-name nginx-asg --launch-configuration-name NginxLC --min-size 1 --max-size 3 --vpc-zone-identifier subnet-xxxx,subnet-yyyy
-
User Data Scripts:
- Use user data scripts to deploy artifacts during the EC2 instance launch. Ensure the script fetches the
.war
file from JFrog and places it in the Tomcatwebapps
directory.
- Use user data scripts to deploy artifacts during the EC2 instance launch. Ensure the script fetches the
-
Database Setup:
- Log into the MySQL database from the Tomcat server and create the database schema:
mysql -h mydbinstance.123456789012.us-east-1.rds.amazonaws.com -u admin -p CREATE DATABASE mydatabase; USE mydatabase; SOURCE /path/to/schema.sql;
-
Cron Job for Logs:
- Set up a Cron job to push Tomcat logs to an S3 bucket:
crontab -e
Add the following entry:
0 0 * * * /usr/bin/aws s3 cp /path/to/tomcat/logs s3://mybucket/tomcat-logs/ --recursive --region us-east-1 && rm -rf /path/to/tomcat/logs/*
-
CloudWatch Alarms:
- Set up CloudWatch alarms to monitor database connections:
aws cloudwatch put-metric-alarm --alarm-name "DBConnectionsHigh" --metric-name DatabaseConnections --namespace AWS/RDS --statistic Average --period 300 --threshold 100 --comparison-operator GreaterThanOrEqualToThreshold --evaluation-periods 1 --alarm-actions arn:aws:sns:us-east-1:123456789012:MySNSTopic
-
EC2 Access:
- Verify SSH access to EC2 instances via the Bastion Host and Systems Manager.
-
Application Accessibility:
- Ensure the application is accessible from a public internet browser.