Deploying a Spring Boot app to AWS
For this I used the sample Book REST application available here: API Best Practices
Steps
Package up your application
Make sure the spring-boot-maven-plugin is added to your application. Here is what the relevant section of the pom.xml file looks like:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
With this in place run the command:
mvn clean install
This will produce a jar file in the project’s target directory. This is what we will upload to AWS in the next step.
Deploy to AWS
Here, we followed the AWS guide here: Creating and deploying Java applications on Elastic Beanstalk.
As we are using the method of generating a jar file and running this on the embedded web container, as per the instructions in the AWS guide above we had to make sure our app was configured to run on port 5000. This is where the AWS nginx instance that exposes port 80 expects our application to be running on. To do this add this to the application.properties file:
server.port=5000
(Without this in place you will get a 500 nginx error when you try and hit the endpoints.)
Rebuild the jar file if necessary at this point.
At this point we used Elastic Beanstalk to deploy our app, however when we asked AWS to ‘Create and use a new Service role’ this gave the following error:
aws-elasticbeanstalk-ec2-role does not exist
So, we had to manually create the role and attach AWSElasticBeanstalkWebTier, AWSElasticBeanstalkWorkerTier, AWSElasticBeanstalkMulticontainerDocker policies to it, and specify Amazon EC2 as a trusted entity in the trust relationship policy (as described here)
For info, here is the trusted entities section of the role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Once this was in place, we went back to Elastic Beanstalk, Environments –> Create Environment, use the existing role created above and uploaded the jar file generated earlier. We just took the defaults for everything else.
After a couple of minutes of AWS provisioning the EC2 instance and deploying the app, the service was available on a generated URL:
Test the deployment
Go to the URL generated by AWS, with ‘/books’ appended. For example: http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books
If the EC2 instance is running you will see output such as:
{
"_embedded": {
"bookDTOList": [
{
"author": "George Orwell",
"authorFirstName": "George",
"authorLastName": "Orwell",
"isbn": "1-2-3",
"title": "Animal Farm",
"_links": {
"self": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books/1-2-3"
},
"books": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books?title="
}
}
},
{
"author": "JRR Tolkien",
"authorFirstName": "JRR",
"authorLastName": "Tolkien",
"isbn": "4-5-6",
"title": "The Lord of the Rings",
"_links": {
"self": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books/4-5-6"
},
"books": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books?title="
}
}
},
{
"author": "Harper Lee",
"authorFirstName": "Harper",
"authorLastName": "Lee",
"isbn": "7-8-9",
"title": "To Kill a Mockingbird",
"_links": {
"self": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books/7-8-9"
},
"books": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books?title="
}
}
}
]
},
"_links": {
"self": {
"href": "http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books?title="
}
}
}
This shows that the app has deployed successfully.
You can also test this using curl, e.g.
curl -v -X GET http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books/1-2-3
or create a book like this:
curl -X POST http://booksapi-env.eba-brmnyhim.eu-west-2.elasticbeanstalk.com/books -H 'Content-type:application/json' -d '{"isbn" : "9-9-9", "title": "Test Book", "author": "Sandy Else"}'
Other useful notes
It is good to change the version in the pom.xml file each time you deploy, so that you can keep track of deployments. Ideally the whole versioning and deployment process would be automated, but that is for another time!
Useful resources
Spring guide for deploying to AWS
AWS Guide to Creating and deploying Java applications on Elastic Beanstalk