In this project, we are going to host and run our java application on AWS using a multi tier web application stack.
For this project we’ll be making use of the following services
EC2 instances: VMs for Tomcat, RabbitMQ, Memcache and MySQL servers.
ELB (Elastic Load Balancer): to automatically distribute incoming traffic across multiple backend servers.
S3 : to store software artifact.
Route53: for private DNS service.
Other services include Security groups, EBS volumes, Public DNS (e.g. Godaddy) etc.
Project Summary
Users will access our web application by using a domain name bought from public dns provider. The domain name URL will point to the ELB endpoint.
Users browsers will use this endpoint to connect to the load balancer by using HTTP on port 80. The ELB will be in a security group that only allows HTTP traffic on port 80.
The application load balancer will then route the request to Tomcat servers (EC2) running in a security group that accepts connection only from the load balancer on port 8080.
The backend servers (MySQL, Memcache and RabbitMQ) for our application will sit in a separate security group and they will be reachable through Route private DNS Zone entries.
Project Architecture
Project Implementation
Step 1: Create Security Groups and Key Pairs
We’ll create 3 security groups. One for the Application load balancer, one for the application server (tomcat instance), one for the backend services (memcache, rabbitmq and mysql instances)
load balancer security group
tomcat application security group
backend servers security group
Next we’ll create a login key pair for our instances
Step 2: Create four servers (EC2 Instances)
We’ll create for EC2 instances for Tomcat, Memcache, RabbitMQ and MySQL servers and place them in their appropriate security groups. We’ll provision the instances and setup the services by using user data scripts.
Create mysql server in the backend servers security group with user data and the created key pair
user data to launch mysql database during instance creation
#!/bin/bash
DATABASE_PASS='admin123'
sudo dnf update -y
sudo dnf install git zip unzip -y
sudo dnf install mariadb105-server -y
# starting & enabling mariadb-server
sudo systemctl start mariadb
sudo systemctl enable mariadb
cd /tmp/
git clone -b main https://github.com/hkhcoder/vprofile-project.git
#restore the dump file for the application
sudo mysqladmin -u root password "$DATABASE_PASS"
sudo mysql -u root -p"$DATABASE_PASS" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '$DATABASE_PASS'"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.user WHERE User=''"
sudo mysql -u root -p"$DATABASE_PASS" -e "DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'"
sudo mysql -u root -p"$DATABASE_PASS" -e "FLUSH PRIVILEGES"
sudo mysql -u root -p"$DATABASE_PASS" -e "create database accounts"
sudo mysql -u root -p"$DATABASE_PASS" -e "grant all privileges on accounts.* TO 'admin'@'localhost' identified by 'admin123'"
sudo mysql -u root -p"$DATABASE_PASS" -e "grant all privileges on accounts.* TO 'admin'@'%' identified by 'admin123'"
sudo mysql -u root -p"$DATABASE_PASS" accounts < /tmp/vprofile-project/src/main/resources/db_backup.sql
sudo mysql -u root -p"$DATABASE_PASS" -e "FLUSH PRIVILEGES"
confirm the required database services are running on db01 server
Create memcache server in the backend servers security group with user data and the created key pair
user data to launch memcache service during instance creation
#!/bin/bash
sudo dnf install memcached -y
sudo systemctl start memcached
sudo systemctl enable memcached
sudo systemctl status memcached
sed -i 's/127.0.0.1/0.0.0.0/g' /etc/sysconfig/memcached
sudo systemctl restart memcached
sudo memcached -p 11211 -U 11111 -u memcached -d
confirm memcache service is running
Create rabbitmq server in the backend servers security group with user data and the created key pair
user data to launch rabbitmq service during instance creation
#!/bin/bash
## primary RabbitMQ signing key
rpm --import 'https://github.com/rabbitmq/signing-keys/releases/download/3.0/rabbitmq-release-signing-key.asc'
## modern Erlang repository
rpm --import 'https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key'
## RabbitMQ server repository
rpm --import 'https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key'
curl -o /etc/yum.repos.d/rabbitmq.repo https://raw.githubusercontent.com/hkhcoder/vprofile-project/aws-LiftAndShift/al2023rmq.repo
dnf update -y
## install these dependencies from standard OS repositories
dnf install socat logrotate -y
## install RabbitMQ and zero dependency Erlang
dnf install -y erlang rabbitmq-server
systemctl enable rabbitmq-server
systemctl start rabbitmq-server
sudo sh -c 'echo "[{rabbit, [{loopback_users, []}]}]." > /etc/rabbitmq/rabbitmq.config'
sudo rabbitmqctl add_user test test
sudo rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test ".*" ".*" ".*"
sudo systemctl restart rabbitmq-server
confirm rabbitmq service is running
Create tomcat server in the tomcat servers security group with user data and the created key pair
user data to launch tomcat service during instance creation
#!/bin/bash
sudo apt update
sudo apt upgrade -y
sudo apt install openjdk-17-jdk -y
sudo apt install tomcat10 tomcat10-admin tomcat10-docs tomcat10-common git -y
confirm status of tomcat service
successfully created the four servers
Step 3: Setup private DNS (Route 53)
We’ll create a private DNS service to resolve internally the server names to IPs so we can conveniently give the names in the application configuration file.
Create hosted zone
Create records in the created hosted zone
create A record type for each of the servers using their private ip addresses
Confirm DNS resolution works
Step 4: Build and Deploy Artifact
In this step, we are going to build the artifact from the source code on our computer using maven then we are going to push it to S3 bucket. On the tomcat instance (app01), we are going to fetch the artifact from S3 and deploy it on the tomcat server
Create S3 bucket
Create IAM access keys for S3
IAM access keys are needed to interact with Amazon S3 via the AWS CLI. The CLI requires the access keys to authenticate and authorise our actions in AWS.
Generate the access keys by creating an s3-admin user, attach s3 full access policy to the user and generate access keys
Create IAM role
Create an s3-admin IAM role and apply it to the tomcat server to allow our tomcat server pull artifact from S3
apply the role to the tomcat server (app01)
Build the artifact
First we need to make sure the backend services information in the source code is correct by editing the application.properties file to match the route 53 records.
Build the application by running “mvn install”
Push the artifact from our CLI to S3
Confirm the artifact (build) has been pushed to S3
Login to tomcat server (app01) and fetch the artifact from S3 to /tmp directory on the tomcat server
Deploy the artifact
Step 5: Setup Load Balancer and DNS
Create a target group
Create the Load Balancer
Add Load balancer URL to our DNS record
Step 6: Validate the deployment
Voila! QED!