Step-by-Step Guide to Deploying a Full-Stack Spring Boot Application in AWS

Building and deploying a full-stack web application into the cloud can be a challenge even for experienced software engineers. Often times we become so specialized in front-end, back-end, or dev-ops that releasing even a trivial full-stack application can be an odyssey into stackoverflow and beyond. This guide starts with a simple Spring Boot hello world application, wires it into a database, and goes through each step in deploying it to AWS backed by a Postgres database.

We will first build and deploy the application locally and then deploy it to AWS.

 Setting up your dev environment

The first thing is getting your environment set up with the Java 8 JDK, git, Maven 3, and PostgresSQL. For mac users with homebrew installed, this may be as simple as:

brew install java
brew install maven
brew install git
brew install postgresql

 Building the application locally

Now that our dev environment is configured, lets build a web application. Pull down the sample application from git using git clone This Spring Boot hello application is a few commits ahead of the hello world project published by Spring’s developers in that it persists user input with Postgres.

To start, let’s make sure the application works locally by rolling it back a few commits so it doesn’t require a database connection, and then building and running it. In the project’s root directory, execute git reset --hard 6e9236b2e725642b122ae01a2aa8f2bb0642875f to rollback and then cd to the PROJECT_ROOT/complete directory and executing mvn spring-boot:run to build the app and start it up in an embedded Tomcat server. After about 5 seconds the terminal will output the following text if you’re environment is configured corretly:

TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080
Started Application in 6.999 seconds (JVM running for 7.979)

This tells us that the app has been deployed to a local tomcat server running on port 8080. In your browser go to http://localhost:8080/greeting?name=YOUR_NAME to display our gorgeous new website:

Screen Shot 2016-12-30 at 10.04.06 AM.png

 Connecting the application to Postgres

It’s time to wire the application into a Postgres database. First, apply git pull to bring back my commits that require Postgres. Instead of going through the hurtles of setting up Postgres locally, lets set it up in AWS which we’ll wire into the local application and then do another local build and deploy to confirm confirm that it’s backed by the AWS database.

 Setting up Postgres in AWS

Go ahead and register an account with AWS if you haven’t already done so. Running applications on their t2.micro instances is free or nearly free. Only you’ve logged into the AWS console, head over to the RDS service and click Launch a DB Instance.

For simplicity’s sake, lets name our db instance, username, and database helloworld. Follow the images below and in a couple of clicks AWS will begin spinning up your Postgres instance. It takes about 10 minutes for it to be operational. Coffee time.
Screen Shot 2016-12-30 at 10.09.49 AM.png

Screen Shot 2016-12-30 at 10.14.32 AM.png

 Persistence in the hello world application

From the hello world template, I’ve added a class that Spring will automagically map to the Postgres table we’ll create. The class looks like this:

public class Person {
    private String name;

which will represent rows in a Postgres Person table with a single column named name.

Configuring the database is done in the PROJECT_ROOT/complete/src/main/resources/ file:


And that’s all it takes programatically to wire in a datasource. The future is now. Using the endpoint for the postgres database that AWS provided us with:

Screen Shot 2016-12-30 at 11.56.03 AM.png

We can now modify spring.datasource.url in to point to our Postgres database. In a production environment it is advisable to not hard code credentials into the project being deployed, but for this exercise it’ll be ok. The last step in the database setup is to create a table called person with a column called name. In a terminal login to the AWS database and execute the create table command:

psql --host=AWS_RDS_ENDPOINT --port=5432 --username=helloworld --password --dbname=helloworld 
CREATE TABLE person (name varchar(50));

Start up the application the same as before (mvn spring-boot:run). The application will take about 30 seconds to setup as it now has to connect to the AWS database. Head over to http://localhost:8080/greetings?YOUR_NAME and note that each time a new name is entered, it gets persisted and rendered on the page!

Screen Shot 2016-12-30 at 10.19.46 AM.png


 Create an Elastic Bean Stalk environment

In your browser, go to Elastic Beanstalk service in AWS. Elastic Beanstalk (EBS) simplifies a lot of the complexity of deploying applications in AWS and is a good starting point for using AWS but is not suitable for complex services architectures. In EBS create a new application using default settings and then create a new environment within the new application. When prompted to choose a web environment tier, choose Web server environment. You’ll be prompted to choose a platform, select Tomcat and leave all other fields as default. AWS will then take about 10 minutes to prepare the environment.

 A pinch of AWS basics

A key concept of AWS is that RDS (Relational Database Service) and application servers like Tomcat both run on EC2 (Elastic Cloud Compute) instances which are typically Linux virtual machine that Amazon assigns to you. Elastic Beanstalk created an EC2 Tomcat instance. The EC2 Tomcat instance can’t communicate with the Postgres EC2 instance by default even though we can connect locally. The reason for this is that EC2 instances have Security Groups that govern how instances can talk to each other. We need to update the RDS security group to allow it to communicate via TCP with other instances in its security group, and then apply that security to the Tomcat EC2.

We could have configured the database using EBS however doing so will tightly couple the database and the application environment so that if the application gets deleted then the database goes with it. I’ve gone through half a dozen environments while working on a single application and didn’t want to recreate the same database each time.

Let’s go through each step of configuring the Security Group…

 Configuring the Security Group

Look at your RDS info and note the name of the security group created for it.

Screen Shot 2016-12-30 at 10.28.52 AM.png

Now head over to the EC2 service and select Security Groups on the left sidebar under Network and Settings. Find that SG from the list and add an Inbound Rule allowing all TCP traffic.


The last step is to add this SG to the Tomcat EC2 instance. Find the Tomcat EC2 instance that matches the name of the application environment you created


And then add the RDS security group to it.

Pat yourself on the back and be glad that’s over with.

 Uploading the war file to Elastic Bean Stalk

 Build the war file

The sample application builds a war file that can be deployed in a Tomcat server. Locally we’ve been running it as a simple jar file with an embedded Tomcat server which is generally a better way to deploy Spring Boot applications but we’re using a war for simplicity sake. It makes deploying to EBS literally push button. If a monkey were to mash the keyboard on the EBS page there’s a decent chance he’d accidentally deploy the war file. In the project root, execute mvn install and it will generate complete/target/gs-serving-web-content-0.1.0.war.

 Deploy the war file

Navigate to the environment you created for your EBS application. There will be to a link to this apps URL at the top. Click it and you should see the sample application that AWS deployed.



Click the big Upload and Deploy button and select the war file that we built.

Give it 10 minutes to upload and then head back to that URL. Congratulations! You have just deployed a database backed full stack web application to AWS!


Now read this

Java 9’s Immutable Collections Are Easier To Create But Use With Caution

Code is easier to reason about when collections cannot be altered after their creation. Having to keep track of the current state of a collection as it gets passed around from this method to that equates to more mental balls to juggle.... Continue →

Subscribe to Carl Martensen

Don’t worry; we hate spam with a passion.
You can unsubscribe with one click.