Deploy a Java Spring Boot application to AWS Elastic Beanstalk

Kim T
Kim T
Jun 3 · 7 min read
Image for post
Image for post
Spring Boot and Elastic Beanstalk makes a great combination

Spring Boot has become a top framework for the Java development community. Recently it has seen great improvements, to the point that Netflix and other large companies are using the framework in production.

Let’s take a look at how to get started with Spring Boot, and quickly deploy an application to platform-as-a-service AWS Elastic Beanstalk. We will be covering the following steps:

  1. Installing development tools
  2. Creating a Java Spring Boot project
  3. Creating an Elastic Beanstalk environment
  4. Adding a local MySQL database
  5. Creating an AWS RDS instance
  6. Shutting down unused instances

So without further ado, let’s get started…

Image for post
Image for post
First we need to get our local development tools set up!

Installing development tools

brew cask install java

Install Maven using the instructions. If you are using a Mac with Homebrew the command is:

brew install maven

Follow the instructions to install the Spring Client on your local machine. If you are using a Mac with Homebrew the commands are:

brew tap pivotal/tap
brew install springboot

If you haven’t already, sign up for an AWS account and install the AWS Client. If you are using a Mac with Homebrew the command is:

brew install awscli

If you are planning on containerizing your app, or using a database, I would recommend also installing Docker.

Before continuing, validate you have Java, Maven, Spring Client, AWS Client and Docker installed by running:

java -version
mvn -version
spring --version
aws --version
docker --version
Image for post
Image for post
Make a web application using Spring Boot

Creating a Java Spring Boot project

spring init --artifactId project-name --dependencies "web,devtools" --description "Something" --groupId com.company-name folder-name

This will create a project with the following options:

  • Project: Maven
  • Language: Java
  • Version: 2.30
  • Packaging: Jar
  • Java: 8
  • Dependencies:
    Spring Boot DevTools - Provides fast app restarts, LiveReload
    Spring Web - RESTful apps using Spring MVC and Apache Tomcat

Open the newly created folder in your chosen code editor. In my case I’ve configured Visual Studio Code to work with Java projects.

To support Elastic Beanstalk you’ll need to change the default port in /src/main/resources/application.properties from 8080 to 5000 using:

server.port=5000

Follow the addition steps in the quick start guide to expose an example Hello World endpoint from your src/main/java/.../Application.java

package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@GetMapping("/hello")
public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello %s!", name);
}
}

Then run the app using the command

mvn spring-boot:run

You should be able to see the endpoint you created at: http://localhost:5000/hello

Build a compiled .jar version of the app using the maven package command:

mvn clean package spring-boot:repackage

This will create a compiled .jar file at:
./target/springelastic-0.0.1-SNAPSHOT.jar

Now we can create an S3 bucket and upload the compiled .jar file:

aws s3 mb s3://project-name
aws s3 cp target/springelastic-0.0.1-SNAPSHOT.jar s3://project-name/springelastic-0.0.1-SNAPSHOT.jar
Image for post
Image for post
Deploy web applications easily using Elastic Beanstalk

Creating an Elastic Beanstalk environment

aws elasticbeanstalk create-application --application-name project-name
aws elasticbeanstalk create-environment --application-name project-name --cname-prefix project-name --environment-name development --solution-stack-name "64bit Amazon Linux 2018.03 v2.10.7 running Java 8"

You should be able to view your running environment at:
https://us-west-2.console.aws.amazon.com/elasticbeanstalk/home

To deploy the new application version to Elastic Beanstalk, now simply run the commands:

aws elasticbeanstalk create-application-version --application-name project-name --version-label "0.0.1" --source-bundle S3Bucket="project-name-files",S3Key="springelastic-0.0.1-SNAPSHOT.jar"
aws elasticbeanstalk update-environment --environment-name development --version-label "0.0.1"

If all is well, you should be able to load your endpoint at:
http://project-name.us-west-2.elasticbeanstalk.com/hello

Working locally your code will automatically live reload. To update the cloud url, you will need to recompile the binary and then deploy it using the AWS commands:

mvn clean package spring-boot:repackage
aws s3 cp target/springelastic-0.0.1-SNAPSHOT.jar s3://project-name/springelastic-0.0.1-SNAPSHOT.jar
aws elasticbeanstalk create-application-version --application-name project-name --version-label "0.0.1" --source-bundle S3Bucket="project-name-files",S3Key="springelastic-0.0.1-SNAPSHOT.jar"
aws elasticbeanstalk update-environment --environment-name development --version-label "0.0.1"

This is great, but what if we need a database too? The next section explains how to get MySQL set up to load and save data from your web application.

Image for post
Image for post
Add a MySQL relational database using Docker

Adding a local MySQL database

There is an official Spring guide for getting started with MySQL. One of the topics it doesn’t cover is using Docker to run a MySQL database along with the Adminer user interface locally on your machine.

We are going to use Docker Compose to run our Spring Boot app and MySQL database together, using a single command! Start by creating a docker-compose.yml file at the root of your project containing the following configuration:

version: '3.1'
services:
backend:
image: maven:3.6.3-jdk-8
command: mvn spring-boot:run
depends_on:
- db
environment:
MYSQL_HOST: db
MYSQL_USERNAME: exampleuser
MYSQL_PASSWORD: examplepass
ports:
- 5000:5000
- 5005:5005
volumes:
- .:/usr/src/mymaven:rw
working_dir: /usr/src/mymaven
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: examplerootpassword
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
ports:
- 3306:3306
adminer:
image: adminer
ports:
- 8080:8080

Before running the Docker containers we need to update ./src/main/resources/application.properties with our database connection details:

server.port=5000
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${MYSQL_DB:exampledb}
spring.datasource.username=${MYSQL_USERNAME:exampleuser}
spring.datasource.password=${MYSQL_PASSWORD:examplepass}
spring.devtools.remote.secret=exampleremotesecret

Now we can run the Docker Compose command to start the Spring Boot application and MySQL database:

docker-compose up

One startup has completed, you should be able to access all the services:

Follow the other steps of the official guide to add some endpoints for saving/getting data: https://spring.io/guides/gs/accessing-data-mysql/

Once you’ve created the /demo REST API, you should be able to create and read data from your terminal commands:

curl localhost:5000/demo/add -d name=First -d email=some@email.com
curl localhost:5000/demo/all
Image for post
Image for post

You can also view the data in your browser at: http://localhost:5000/demo/all

Image for post
Image for post

Or alternatively view and modify the entire database structure in the Adminer user interface at: http://localhost:8080

Image for post
Image for post

This all works well locally, but how do we deploy this to the cloud, and make sure the database is running on AWS?

Image for post
Image for post
We can use an AWS RDS relational database in the cloud

Creating an AWS RDS instance

aws rds create-db-instance \
--db-name exampledb \
--db-instance-identifier project-name \
--db-instance-class db.t2.micro \
--allocated-storage 20 \
--engine mysql \
--master-username exampleuser \
--master-user-password examplepass

Once launched, you can view the database via the AWS console at:
https://us-west-2.console.aws.amazon.com/rds/home

Update Elastic Beanstalk environment variables with database connection settings:

aws elasticbeanstalk update-environment --environment-name development --option-settings Namespace=aws:elasticbeanstalk:application:environment,OptionName=MYSQL_HOST,Value=project-name.c1234.us-west-2.rds.amazonaws.com

You’ll notice that you aren’t able to connect the RDS database using the MySQL Client command:

mysql -h project-name.c1234.us-west-2.rds.amazonaws.com -P 3306 -D exampledb -u exampleuser -p

This is because your RDS instance is configured with VPC traffic rules preventing access. Once you have deployed your application inside the VPC it will be able to access the RDS instance.

Shutting down unused instances

aws s3 rm s3://project-name-files --recursive
aws rds delete-db-instance --db-instance-identifier project-name --final-db-snapshot-identifier project-name-snapshot
aws elasticbeanstalk terminate-environment --environment-name development
aws elasticbeanstalk delete-application --application-name project-name

Summary

You can view the full source code to my project here:
https://github.com/kmturley/spring-boot-elastic-beanstalk

Creative Technology Concepts & Code

find, learn, share

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store