Blog Post

Redirect HTTP to HTTPS - Spring Boot - Elastic Beanstalk Load Balancer

https, load-balancer

Yesterday I had a difficult time getting AWS Elastic Beanstalk redirecting HTTP traffic to HTTPS with an AWS classic load balancer and a Spring Boot app. I’m using a simple standard configuration for high-availablity Elastic Beanstalk: 64bit Amazon Linux 2016.09 v2.5.1 running Tomcat 8 Java 8. My app is set to use provided Tomcat so my solution cannot use the Spring Boot TomcatEmbeddedServletContainerFactory which some solutions on they internet suggest. Also I didn’t want to ssh into any EC2 instances as that solution wouldn’t scale.

When AWS refers to Classic Load Balancer they’re talking about Apache2 load balancer. You could also set up NGINX but I don’t discuss that here, you should be able to figure it out with this post (and poke around the AWS Labs Github repo linked below). AWS’ has new options for Application Load Balancing but this is something you’ll have to enable.

There are a few stackoverflow posts which helped me come up with a solution, but this QA was by far the most helpful with Zags answer giving me the guidance I needed. In their solution rewrite_module isn’t enabled by default so you’ll get an error “Invalid command ‘RewriteEngine’, perhaps misspelled or defined by a module not included in the server configuration”. It seems like this was a change from Apache2.2 but I couldn’t find anything in the change logs. There is an easy fix, load the module first:

LoadModule rewrite_module modules/mod_rewrite.so
The other issue I dealt with was finding the correct directory location to put my .ebextensions conf files. What worked for me was putting the file here:

/src/main/webapp/.ebextensions/httpd/conf.d/elasticbeanstalk.conf

Apache Module mod_rewrite documentation explains the syntax for mod_rewrite. The code I ended up using is from AWS Labs and is shown here (be careful copying and pasting, whitespace matters):

<VirtualHost *:80>
    LoadModule rewrite_module modules/mod_rewrite.so
    
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
    
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>
    
    ProxyPass / http://localhost:8080/ retry=0
    ProxyPassReverse / http://localhost:8080/
    ProxyPreserveHost on
    
    ErrorLog /var/log/httpd/elasticbeanstalk-error_log
    
</VirtualHost>

I found

this code here: AWS Labs .ebextensions HTTPS redirection for Java and Tomcat

I’m most likly going to change the rewrite rule to include HTTP response status 301 to indicate a perminant redirect.’

RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

If you notice another wrong with this post or know a better way, please create an issue on my personal website.

I’ve created an example Spring Boot app to help get you started: Github Example Code

Much Love!

Matt Sommer