Deploy a Java Spring Boot application to AWS Elastic Beanstalk
By: Kim T
Tags: Spring Boot, AWS, Elastic Beanstalk, Maven, Java

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:

So without further ado, let’s get started…

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

Installing development tools

Install Java SDK v1.8 or higher using the instructions. If you are using a Mac with Homebrew the command is:

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

Make a web application using Spring Boot

Creating a Java Spring Boot project

We will follow the Spring quick-start guide at https://spring.io/quickstart. Generate your initial project using the Spring client:

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

Maven Language: Java

Java Version: 2.30

2.30 Packaging: Jar

Jar Java: 8

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 class DemoApplication { public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

public String hello(

return String.format("Hello %s!", name);

}

} @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

Deploy web applications easily using Elastic Beanstalk

Creating an Elastic Beanstalk environment

We can now use the AWS Client with Elastic Beanstalk commands to set up an application 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.

Add a MySQL relational database using Docker

Adding a local MySQL database

There are many options for database types, and approaches for implementing using different libraries. Elastic Beanstalk’s default configuration is to use Amazon RDS (relational database service) so we will use MySQL for our local 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/all curl localhost:5000/demo/add -d name=First -d email=some@email.com curl localhost:5000/demo/all

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

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

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

We can use an AWS RDS relational database in the cloud

Creating an AWS RDS instance

You can follow the official guide to create an RDS instance. You can alternatively use the AWS Client to create the database via the command line:

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

To clean up environment instances (and save billing costs), delete your buckets and resources using the commands:

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

So that was a quick introduction into creating a Sprint Boot web application on Elastic Beanstalk. Hope that helps you get started yourself!

You can view the full source code to my project here:

https://github.com/kmturley/spring-boot-elastic-beanstalk