Add SSL Certification to EC2 WordPress Instance to use HTTPS

Home/Amazon Web Service, DevOps, Infrastructure/Add SSL Certification to EC2 WordPress Instance to use HTTPS

Add SSL Certification to EC2 WordPress Instance to use HTTPS

Using HTTPS in your apps and websites is becoming increasingly important. Using it gets you in the good graces of Google, keeps your customer’s data safe and secure, and (with Amazon Web Services) opens up the doors to efficiently load balancing your traffic. I wanted to add SSL to this website to not only get the experience and learn how to tackle the task with AWS but to also rake in that sweet SEO bonus (of course). So I wrote the steps I took (minus the 4 hours of banging my head on the keyboard) to get this successfully installed. It was great practice and actually a lot of fun despite the endless redirect loop that WordPress stumped me with, so I highly recommend it.

For this guide, we’re going to add SSL certificate to a load balancer that we’re going to put in front of our WordPress instance. We’re going to tackle all that entails, such as updating our DNS and Search Console, to configuring WordPress to properly handle the HTTPS traffic all the way through to your admin panel.

What does it mean to add SSL

Simply put, SSL is a way to encrypt all data sent from one server to another. This is useful for all sorts of reasons, including banks, online retailers, and all sorts of applications that handle sensitive and personal information. Web sites that provide SSL encryption are flagged with ‘HTTPS’ or the secured version of ‘HTTP’ and are seen as trustworthy services. This is why Google now gives SEO weight to SSL encrypted websites – and why I wanted it here! So let’s get started!

Provision your SSL Certificate with AWS Certificate Manager

Before beginning this step, make sure that the WHOIS information for your website is correct and you have access to the email account listed.

The easy steps first: log in to your console and select ‘Certificate Manager’ from the list of available services. At the top, you want to ‘Request a certificate’ and enter the different domain names of the website you want to add SSL to. You can use wildcards as described in the examples on the page, so for this website, I set the domain names to www.davidmeents.com, davidmeents.com, *.davidmeents.com. Then click ‘Add another name to this certificate’ followed by ‘Review and request’. Lastly, click ‘Confirm and request’ and on the next screen read the warning and click ‘Confirm’.

You’ll shortly receive an email sent to all the emails listed on the WHOIS information for your domain. Follow the directions in the email to confirm that you requested the SSL and you now have a certificate!

Add SSL with AWS Classic Load Balancer

Amazon Web Services makes the process to add SSL super easy. We’ll be putting a classic load balancer in front of the WordPress instance (created with EC2 ) and we’ll route traffic through it. We’ll offload the certificate at this presentation layer and then send the secured user down into our website. While provisioning the SSL through Amazon is free, creating the Load Balancer will inquire typical charges based on usage at the rate of 2.5 cents an hour. This comes out to be about $20 a month – which is steep for just providing SSL, however, the load balancer has lots of other tricks for making your application or website highly available. I would recommend looking into them to really get the most value out of your ELB.

Provisioning the Load Balancer

First things first, go to your EC2 dashboard and select ‘Load Balancers’  and click ‘Create Load Balancer’. You’ll then be presented with a decision between an ‘application load balancer’ and a ‘classic load balancer’. Despite the message that the ‘application load balancer’ is preferred for HTTP/HTTPS, we’re going to use a classic load balancer for this tutorial. Using an application load balancer would require us to offload the SSL certificate inside our application, which for this tutorial is WordPress. I don’t know about you, but I would much rather not mess with that mess. Select ‘Classic Load Balancer’. The ELB will handle the certificate and then pass the encrypted user down into our WordPress app with very little effort on our part.

Load Balancer Basic Configuration

On the next screen, set the basic configuration for our load balancer. Give your ELB a friendly name that ideally matches the convention you’ve been using for your different architecture. For example, my EC2 instance for this website is called dpm-wordpressso I named my ELB the same thing. This keeps everything unified and I know exactly what the service is being used for. Next, you are going to leave the ‘Create LB Inside’ setting to the default ‘My Default VPC’. Leave the other options the same.

Lastly, on this page, we want to add an additional ‘Load Balancer Protocol’. Click add, and in the protocol drop down select ‘HTTPS (Secure HTTP)’. This should auto-populate the load balancer port to 443 (the secured port used for HTTPS instead of 80). Leave the ‘Instance Protocol’ and ‘Instance Port’ set to their default options (HTTP and 80) and click the next option.

Setting the Security Groups and SSL

On the next screen, you’ll select your security group that you assigned to your WordPress EC2 instance.  For the sake of thoroughness, your security group should allow inbound traffic through the TCP Protocol on the Types and Ranges: HTTP / 80, SSH / 22, and HTTPS / 443.

After selecting your desired security group click next and on the next screen you’ll be setting the SSL certificate. In the ‘Certificate type’ section select ‘Choose an existing certificate from AWS Certificate Manager (ACM)’. Then (obviously) select the certificate you just created. In the last section leave the ‘Cipher’ settings to the defaults.

Add your WordPress instance and Create a health check

On the next page, we’re presented with creating a health check for our load balancer. The health check will ping our WordPress website on the port and protocol that we specify. Select ‘TCP’ from the ‘Ping Protocol’ and change the port to ‘443’. As we’re only load-balancing a single WordPress instance I upped the ‘Interval’ to 60 seconds and left everything else to their default values. Next, select the EC2 instance where you have your WordPress website installed, and leave the ‘Availability Zone Distribution’ to its defaults. Give your load balancer a tag called ‘Name’ and pop in your naming convention one more time for good measure. This websites name tag is of course ‘dpm-wordpress’. After a quick review of all the settings, click create!

Note: your classic load balancer is going to fail its health check and mark your instance status ‘OutOfService’. This is because we haven’t finished configuring WordPress or your DNS to accept encrypted traffic sent from the 443 port.

Configuring WordPress for HTTPS sent from a Load Balancer

The next step to add SSL is arguably the most difficult – but we’re not going to have any problems. You’re almost there! The first thing we want to do is FTP into our WordPress instance where we’ll be editing the .htaccess and wp-config files. If you’re using the Bitnami WordPress installation (which I highly recommend!) you can find these files at /opt/bitnami/apps/wordpress/htdocs. 

Always take the proper precautions when editing these critical WordPress files. Create backups!

Add an Apache Rewrite Rule to WordPress

Save your progress: following this tutorial any further will cause your website to no longer function properly until the rest of this tutorial is completed. I recommend reading the rest thoroughly before making these changes. Should you run into any issues you can simply undo these steps and everything should return to normal.

Open up your .htaccess file first and let’s add in the rewrite rule we’re going to use to direct all inbound traffic ‘HTTPS’. Because our load balancer is taking all traffic handling it on port 443 and encrypting it before send it down to our WordPress instance on port 80 we want to ensure that WordPress continues to honor the ‘HTTPS’ protocol and exclusively use only that. At the very top of this file, before anything else, add in the following rule. Be sure to replay ‘your-domain’ with your actual domain name.


# Begin force ssl
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{SERVER_PORT} 443
  RewriteRule ^(.*)$ https://your-domain/$1 [R,L]
</IfModule>

Easy as that you just added an Apache rewrite rule to take all traffic and direct it towards the HTTPS URL.

Force SSL on the admin pages

We also want to encrypt and use HTTPS on the WordPress admin pages. To do so open up your wp-config file and add in the following code underneath the ‘MySQL settings’ – but be sure to keep the code above the comment that says ‘stop editing’.


/** force ssl on admin pages **/
define('FORCE_SSL_ADMIN', true);
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';

There are two different things happening here. The first one is we’re telling WordPress to simply use SSL for the admin pages. The next command prevents us from getting stuck in a never ending redirect loop. If you remember, we are taking all traffic to our website through 443, offloading our certificate, and then pushing it down into our WordPress application on port 80. Then, since we’re forcing SSL, WordPress tries to redirect us back to port 443. And so on, and so on. This second command checks the headers of the user as it enters the website to validate if it’s already coming from HTTPS and stops this redirect loop.

Lastly, a little bit further down we want to change the default WordPress site URLs. Sometimes this can be done from the admin control panel, but it’s just as easy to change it here in the wp-config file since we have it open. Scroll down to the appropriate section and just add in the ‘s’ in front of ‘HTTP’, like so:

Save all of your changes and let’s jump back into our Amazon console to make some DNS changes.

Updating your DNS to point to the Load Balancer

At this point, if you try to access your website you’re going to get a nasty error saying that your site isn’t secure. This is because we are redirecting all of our traffic to ‘https’ without sending along the SSL certificate. So what we need to do now is point our DNS records to our load balancer, which will then take all the traffic, offload its SSL certificate, and pass it along properly to our website. We’re going to assume you’re using Amazon’s Route 53 for this task as well, however, the process should be similar to any DNS service.

Go to Route 53 and select your WordPress site out of the ‘Hosted Zones’. You want to update your ‘A’ records to point to the load balancer we made, and luckily for us, Amazon makes this ridiculously easy. Select the A record and then change the Alias from ‘no’ to ‘yes’. You should be presented with a list of load balancers – just select the right one. Be sure to update all of the A records you have. The DNS changes should only take a few moments but could take up to an hour.

That should be it! Your load balancer should be passing its health check and your website should be nice and secure. If you’re still having issues with your connection not being private, try emptying your cache, retyping in the domain name, or waiting a little longer. If that’s not working – leave some details in the comments below and we can try to get it working!

Last steps and getting SEO ready

There were some small things I did after updating my domain to HTTPS. Since I was mostly concerned about any SEO benefit (at this time) I wanted to make sure that Google was aware of my now nicely encrypted website. What I found out was that in the Search Console you need to have all variations of your website listed. For example, ‘http://www.davidmeents.com’ and ‘http://davidmeents.com’. This means that you want to also add the ‘HTTPS’ versions of these two. Your WordPress site should have four properties when you’re done.

You’ve successfully gone through all the steps required to add SSL! I spent a good amount of time compiling this and getting stuck with redirect loops at every turn when I did it the first time. So hopefully I saved you some time, or solved your frustrating problems! Either way, please let me know in the comments if you have questions.

By | 2017-02-20T17:36:32+00:00 February 12th, 2017|Amazon Web Service, DevOps, Infrastructure|8 Comments

About the Author:

React.js developer, web designer, devops engineer, and business owner.
  • randsroark

    Thanks for the great tutorial. It seemed to work ok, but I’m not yet getting “Secure” in front of the url at https://projectlibe.com. Does it take time, or could this be a misconfiguration?

    • Most likely it could be your browsers cache – it’s working great for me! Nice job randsroark!

      • randsroark

        Thanks for the reply. It was a mixed content issue. WordPress was calling the logo and a background image insecurely. Probably because they were hard coded that way in the theme settings.

  • lora

    Thank you for this guide– was super straightforward.
    I am having an issue though– everything works when when the url is input as http://www.domain.com, forwards to https://www.domain.com just fine, checks out with browser. But, when i input the domain.com without the www, it redirects to https://domain.com but is still considered “not secure.” I roamed the internet for a solution (serverAlias virtual host, etc) but not sure if i’m putting this in the right places because either nothing has worked or I am missing something because having no luck. I have my domain registered at godaddy and everything else on AWS. Should I change DNS records on both AWS and godaddy? Tried and failed on many fronts… any advice?

    • Hey! Thanks for asking! It is likely that the certificate you made was only for http://www.domain.com not the non-www url domain.com. Without the ‘www’ the certificate won’t recognize https://domain.com as a secured address.

      AWS makes it super easy to just swap out a new certificate into your loadbalancer. Or you can write some fancy rewrite rules to get all of your non-www traffic to route to www. But that’s a pain and in my experience isn’t the best route.

      I’d recommend just making a new certificate, and make sure to add both ‘*.domain.com’ and ‘domain.com’

      Thanks for reading!

      • lora

        Hi, thanks! So I did have additional names for the original certificate (www.domain.com with additional names ‘domain.com’ and ‘*.domain.com’). Seeing this though I created a new certificate so domain.com was the main certificate name and the other two were additional. Switched the certificate on the load balancer, and now neither the www nor the non-www will redirect correctly (both are marked as “not secure” by the browser. Was there another step? Should I just delete everything and start again?

        • Hm, that’s strange. Nothing is coming to mind as possible solution, I’m sorry! I feel like the issue is still in the certificate, so destroying it all and starting over likely wouldn’t solve anything. Best of luck, if you find out what caused it please let me know!

  • Nikhil Tayal

    Hey David
    Thank you for the thorough guide and the explanations.
    I followed all the steps as you mentioned and I am getting this error:

    mydomain-234xxxx345.us-east-1.elb.amazonaws.com uses an invalid security certificate.

    The certificate is only valid for the following names:
    mydomain.com, http://www.mydomain.com

    The only difference between your instructions and my deployment is that I got my Domain from google and not aws.
    In fact, the error actually makes sense to me – as when I try to go to my site, I get redirected to the AWS domain name(which I setup using subdomain forwarding in google domains console).
    Now since the certificate indeed only had mydomain.com, http://www.mydomain.com, it is kind of expected that this error will be returned.
    Did I miss a setting somewhere which is causing this behavior?
    Any help is greatly appreciated.