How to: Deploy a Java Web App on AWS Elastic Beanstalk
Tags: beanstalk, cloudnative, aws, cloud
Published: 2023-02-27 15:58:02

**Prerequisite**
- [AWS account](https://aws.amazon.com/free)
- Have a VPC (or you may also use the default VPC)
- Have [maven](https://maven.apache.org/) and [JDK8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html) installed
- [AWS account](https://aws.amazon.com/free/)
- Have a signed certificate (SSL from Certificate Manager)
- You have a domain name 

Lets Begin!

**1. Create Key Pairs for Beanstalk instance**
Incase of troubleshooting, we need provide a secure way of accessing the EC2 instances.
 
- Login into your AWS account.
- Type Key pair in the AWS search bar
- Click **_create key pair_**
- Enter _**Name**_, _**Type**_ and **_Format_**
- Click _**create key pair**_

![key pair](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0amvvxkdt15c58i4ya4o.png)

**2. Create Security group (SG)**
Next, create security group for the backend services (RDS MySQL, Amazon MQ and ElastiCache/memcahed ). All services need to be able to communicate between each other. This means we All traffic should route to itself. To do this, you need to add dummy inbound rule, save it and then click on edit, delete it, and then add All traffic and destination would be the name of the security group.

- Type Security groups in the AW search bar
- Click on create security group
- Enter a **_Name_** and add a _**inbound rule**_ and click _**create security group**_

![SG](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/27uutyjq25tu7fxod0od.png)
- Click on _**edit inbound rules**_ again, this time, delete it and click on **_add rule_**
- Select _**All traffic**_ and select the SG you just created as the destination.
- Click on _**save rules**_

![save rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68ma88dwscq8p8slwcrd.png)


**3. Create Backend Services**

_**RDS MySQL Database**_
- As usual, type RDS in the AWS Search bar
- Select subnet groups
- Select _**create DB  subnet group**_
- Enter _**Name**_, select the your VPC and select two AZs as shown in the diagram below
- Select subnets and click **_create_**

![Subnet group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7drplagaz0p2z495cvk.png)

Next, still on this same page, click _**Parameter groups**_ and click _**create parameter group**_. This is useful, if some parameter for the database needs some level of customization.

Enter the following values below
- Parameter family: **_Mysql5.7_**
- Type: **_DB parameter group_**
- Group name: **_rds-parameter-gp_**
- Description: **_rds parameter group_**
- Click on **_create_**

![parameter group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xv99t88yy7egtgpfcq8.png)

Next, still on the same page, click _**Databases**_ and click _**create database**_

- Standard create
- Engine Options: _**MySQL**_
- Engine version: _**5.7.***_
- Template: Dev/Test (or Free tier for low cost)
- DB instance identifier: _**rds-mysql-database**_
- master username: _**admin**_
- Select **_Auto generate a password_**
- DB instance class: **_Burstable classes_**:**_db.t3.micro_**
- Allocated storage: _**20GB**_
- Select VPC
- Select your **DB subnet group**
- Public access: **_NO_**
- VPC security group: vprofile_backend_service SG
- Additional configuration - enter database name: **accounts**
- _**Click Create Database**_

Click on view credentials to copy your password. 
![credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/28il8msmjc41soz1nt0e.png)

_**Amazon Elastic Cache**_
Like RDS, you need to create parameter group and subnet groups.
For parameter group, enter a name and select **_1.4_** for **family_**, enter a description and click create.

![memchached family](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j1f3cphbigf1iyw3mzlr.png)

For Subnet group, enter a **_Name_**, _**VPC**_ and leave the default settings and click **_create_**.

![security group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7id6rn3xrdzssm0ok1u.png)

Next, Click _**Memcached clusters**_ and click create _**Memcached clusters**_

- Location: AWS CLoud
- Name: **_vprofile-memcached-cluster_**
- Engine version: _**1.4.5**_
- Parameter groups: vprofile_memcached-pg
- Node type: _**cache.2t.micro**_
- Subnet group:vprofile_memcached-sg **_ and click next
- select manage under _**security group**_, select backend_service sg, click next to review
- Click _**create**_


![vprofile-memcached-cluster](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v66v5ysxq377n19f5r10.png)

_**Create Amazon MQ**_ 
- Broker engine: _**RabbitMQ**_
- Deployment mode: _**single-instance**_
- Enter Name: _**app-rmq**_
- Broker instance type: _**t3 micro**_
- Enter _**username**_ and **_password_**
- Under _**additional settings**_, select _**private access**_ below network
- Select the default VPC and the security group we created from the dropdown.
- Enter and click next to review settings
- Click **_create broker_**

![rabbitmq](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9zf0az3hokiac8mpi81.png)

_**4. Login into the instance and initialize RDS DB**_
At this point, you add the database _**accounts**_ schema to RDS MYSQL. To do this lunch a temporary EC2 instance to initialize the database with the database schema.

Lunch a EC2 instance
- Enter instance name
- AMI : ubuntu 20 / free tier
- Instance type: _**t2.micro**_
- Select your key pair
- Create Security group: Name: _**mysql-client-sg**_: Allow **_SSH_** to **_MyIP_** ( in some cases you might need to use _**0.0.0.0/0**_ instead)
- Add User data
```bash 
#!/bin/bash
# update ubuntu OS and install MySQL client at startup
sudo apt update
sudo apt install mysql-client -y
```
- Click **_lunch instance_**

![Instance](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oli17p7fxdzwd5xhkkkb.png)

Update backend security group (_**backend services**_) to allow MySQL traffic from the security group of the instance.

![access](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/av6ob91vg3kg4tvwglsz.png)
Next, copy the Endpoint of RDS MYSQL database for **_accounts _** which is the hostname, you will need this to connect to RDS MYSQL and also to update the connection to the application.

![endpoint](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/24aq8uuk18yyfy871m0i.png)

SSH into the instance and Connect to RDS MYSQL

Clone the application repo [Here](https://github.com/devopshydclub/vprofile-project) 

```bash
# Make sure git is installed and clone repo
git clone https://github.com/devopshydclub/vprofile-project

# navigate to **_src/main/resource_**

mysql -h <Replace RDS Endpoint> -u admin 
-p<Replace RDS DATABASE PASSWORD> accounts < db_schema.sql

# Show all database 
show databases;

# Use databases accounts
use accounts;

# Show the tables in the database accounts
show tables;
```

![sql](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vghtuzg9bbuj8vhmjcnq.png)

Copy the endpoint for Amazon MQ

![Amazon MQ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95bnq7bmmr3vnqg65ckq.png)

Copy the endpoint for Memcached Cluster

![elasticache](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stlhat69a84yh5o3fsor.png)

Update web application with backend connection credentials. Navigate to **_src/main/resource_** in the repo and open _**application.properties**_ with the editor of your choice.

```bash
# update the file with the endpoints, username, and password
vi application.properties
```

![update](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2i99bqt9qz34u7lx44qf.png)

Build Artifact with Backend information using Maven on your local machine.
Make sure you are in the top level of the folder where the pom.xml is located.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d90nljluduxw3k59ymx2.png)
![maven](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/30mcp2wum3z7x1z7811l.png)

_**5. Configure Beanstalk**_


- Click _**Configuration**_
- Edit _**Instances**_, add EC2 Security Group : Backend service SG and continue.
- Edit _**Capacity**_,
  Environment type: **_Load balancer_**
  Instances: _**Min:2**_ and _**Max:4**_
  Placement: **_us-east-1a_** and _**us-east-1b**_
  Click on continue.
-  Edit _**Load Balancer**_ 
   Listeners: add lister _**443**_ for HTTPS and select _**SSL certificate**_ as shown in the diagram below and click 
![https](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4o0nk4cyr0nw5noy9nn.png)
- Processes: click on action to edit the default process
  Scroll down to Health check and add _**/login**_ as the endpoint and click save.
-Click continue
![endpoint](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3n2d3t2erf0y0r7fcgox.png)
- Rolling updates and deployments
  Deployment policy: _**Rolling**_
  Percentage : _**50%**_ and click on continue.
- Security: select key pair and Create instance profile and click Continue. 

_The simple application created earlier enable beanstalk to create the instance profile for us._

![role](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oe1rqs461q9cl6g11h11.png)
You should also add an email for notification.
Click on _**apply all changes**_ and _**confirm**_

![save](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7cdzndo2x85b1gph8sz.png)

After the changes are applied the Health would be serve as shown in the diagram below. This is because of the endpoint /login we added, however the current application does not have this endpoint but our application does.

![serve](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/siadosnw6z6u4tpo9l6g.png)

_**Deploy the Application**_
- Click on _**Upload and deploy**_
- Click choose file : Select the build _**vprofile-v2.war**_ file from your machine. (located in the targets folder)
- Enter Labal version: v2

![deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3yqkejjqdgykmxyi551o.png)

**Next, Update backend security group**
- Add rabbit MQ, elasticache and RDS MYSQL ports - 3306, 11211 and 5671  to Security Group created by beanstalk.

![SG updated](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17vbnld9zzqa1euqt0kk.png)
_Note, Elastic beanstalk would create two SGs, check the names and make sure you are not pointing to the Load balancer SG_

9. Update Entry in Route 53 Hosted Zone

![Route 53](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v3lcpyhsw5020otldyge.png)

10. Test The URL

![Iwebsite](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/35i9magvm6inf47fp58f.png)
Login

![Login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m8rfi8ahjgbs325gdi8x.png)

Username: Admin_vp
Password: Admin_vp

> _Note: Incase you face any issues while uploading your artifact, disable your anti-virus software and try the upload again._

_Source: visualpath_

As always, I look forward to getting your thoughts on this article. Please feel free to leave a comment!