Learn how to secure and scale your WordPress site with an AWS Elastic Load Balancer configured for SSL encryption. This detailed step-by-step how-to guide will get you up and running quickly and painlessly.

Summary

In recent past AWS introduced new serverless load-balancing models that are designed to sit in front of your web app architecture and importantly, these new ELB models are both highly-reliable and free.  If you use an AWS EC2 instance to host your WordPress environment then there are many advantages to adding an AWS Elastic Load Balancer (ELB) to your infrastructure architecture.

  • Horizontally scale your WordPress site.
  • Add an automatically-renewing SSL certificate to your site for free.
  • Improved site response times
  • Perform maintenance to your server without having to take your site offline

Unfortunately, getting an ELB with an SSL certificate to work with WordPress is tricky. Namely, WordPress can get stuck in an infinite loop of URL redirections whenever you try to redirect traffic to HTTPS. After a long afternoon of banging my head against the keyboard I finally got HTTPS working. This article will hopefully help you to get your own ELB and SSL certificate up and running quickly and painlessly. Let’s get started!

Theory

This wasn’t immediately obvious to me, but, HTTPS and SSL are only necessary for traffic between your site’s visitors and the ELB. The upstream traffic between your ELB and your EC2 instance(s) resides inside your Virtual Private Cloud (VPC) and can therefore communicate safely using HTTP. This means that you only need to add an SSL certificate to your ELB, and you can (mostly) continue to use HTTP on your EC2 instance.

AWS Architecture

This is not only easier to manage but also provides better page hosting performance. The tricky part is configuring WordPress so that is doesn’t get confused or otherwise behave in a way that would undermine our aim of providing site visitors with a secure browsing experience.

Implementation

First, this article assumes that your WordPress environment is hosted on a single AWS EC2 instance, largely based on AWS’ Tutorial: Install a LAMP Web Server with the Amazon Linux AMI and Hosting a WordPress Blog with Amazon Linux.

1. Get an SSL certificate thru AWS Certificate Manager.

I highly recommend using AWS Certificate Manager to create your SSL certificate. This is an especially good choice if you’re new to SSL because the certificate application process is well-documented and intuitive. Take a look at my how-to article for requesting a SSL certificate from AWS.

2. Create an ELB

You’ll find the link to the Elastic Load Balancer console on the left sidebar of the EC2 console.

ELB Step 1
ELB Step 2
ELB Step 3

3. Add The Certificate To Our New ELB

Add Certificate Step 1

In Step 3 (Configure Security Groups) you should select the same security group that your EC2 instance currently uses. Note however, that your security group must include HTTPS (port 443) in its inbound rules.

Add Certificate Step 2
Add Certificate Step 3

In Step 4 you will configure routing of your inbound web traffic. That is, as site traffic arrives to your application ELB, you need to provides instructions on where the ELB should send this traffic. You’ll be able to edit this information later, just fyi.

Now then, to get the ELB to work at all I had to get creative with a couple of things. One of my more vexing problems regarded Health Checks. The theory behind this is simple: AWS ELB’s will regularly try to ping a certain file. For any EC2 instance included in your Target Pool, if the success code returned matches up with the value in the routing configuration (the, “Success Code”) then the EC2 instance is considered healthy. Mind you, there are additional details which hopefully are self explanatory. Ok, so, in my case i host multiple virtual servers from the same Apache server, and this, along with the fact that all web sites are WordPress sites, caused problems with the default health check, which is to ping index.php. To workaround these problem I created an empty file in the root of each of my WordPress sites named health.aws. Additionally, Apache didn’t necessarily return a 200 status code; even if the file could be pinged. After some investigating I learned that — sometimes, depending on particulars of your server state — Apache might send a redirection code like say, 301, instead of a success code like 200. To work around this I added 301 as a possible valid response code, and voilá, the ELB can correctly determine the health (or lack thereof) of my EC2 instances.

In the screen that follows you’ll add one (or more) EC2 server instance(s) to your Target Group. Keep in mind that with AWS ELB it’s possible for you to horizontally scale your WordPress platform. But, also keep in mind that, on the basis of this article alone, you are definitely not ready to manage an ELB with multiple EC2 targets. Thus, the prudent thing for you to do at this point is to add your sole EC2 instance to the list of registered targets, and to leave horizontal scaling experiments for another day.

Add Certificate Step 4

And, that’s a wrap. You’ve configured your first AWS Application ELB! Now that the heavy lifting is behind us we can shift our attention to re-configuring Apache and WordPress on our EC2 instance.

4. Modify Apache Configuration To Redirect HTTP to HTTPS

You will not make any changes to your Apache configuration. If that seems counterintuitive then let me explain why. In AWS’ own support documentation they recommend that you add “X-Forwarded-Proto” headers to redirect your HTTP traffic to HTTPS, and while this is in fact the correct methodology, we cannot do this YET because if we did it would cause an infinite loop. Instead, we’re going to add these headers from within our wp-config.php file in the next section.

A little more explanation: by default Apache is installed to use HTTP (port 80), therefore all configuration for this protocol was taken care of for you when your originally setup your server. Importantly, inbound traffic originating from the ELB also is traveling over HTTP as per the diagram above and thus we a) should continue to listen on port 80, and b) we should continue to use HTTP all the way to our WordPress server. Now then, to provide an end-to-end HTTPS connection for our users we’ll need our WordPress server to return all web pages over HTTPS rather than over HTTP. We do that below. Meanwhile, following is a sample Apache virtual server configuration which contains a snippet of the code that AWS actually recommends. You can uncomment the snippet and add to your own config in order to test/verify my claim:

  ServerName blog.lawrencemcdaniel.com
  ServerAlias blog.lawrencemcdaniel.com

  DocumentRoot /var/www/html/blog.lawrencemcdaniel.com
  ServerAdmin lpm0073@gmail.com
  ErrorLog /var/www/logs/error_log_blog.lawrencemcdaniel

  #I'm leaving you with a copy of the snippet referenced above in case you want to experiment.
  #RewriteEngine On
  #RewriteCond %{HTTP:X-Forwarded-Proto} =http
  #RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

Restart Apache
sudo service httpd restart

Here is some additional reading on how and why this configuration works:

5. Update WordPress Configuration

We need to update the WordPress Address URL and the Site Address URL; both of which are visible within the Settings -> General console window. However, you’ll need to update these values using your wp-config.php file located in the root directory of your site.

define('WP_HOME','https://blog.lawrencemcdaniel.com');
define('WP_SITEURL','https://blog.lawrencemcdaniel.com');

// Update 8-April-2018: I moved https redirection from the Apache virtual server config to wp-config.php using this snippet.
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
       $_SERVER['HTTPS']='on';

Cached files and cookies in your browser will affect your browser behavior while you’re implementing and testing these changes. Make sure you regularly clear these two elements of your browser cache to avoid confusing and misleading results.

6. Update Webmaster tools

It’s really important to be aware that Google distinguishes between HTTP and HTTPS in terms of recognizing and indexing your site. Make sure that you add your “new” HTTPS site as a new Web Property in Webmaster Tools.