AWS EC2, Elastic Load Balancers, and CloudFlare

This is a small rant and hopefully helpful series of tips on how to set up a personal website using WordPress, Amazon EC2 instances, Elastic Load Balancers, SSL Certificates, and CloudFlare.

Since I literally just finished this, I may as well go into some technical details about how my website is now setup. Below is my personal site setup and probably doesn’t reflect everything a technical operations engineer would like, but I think it is pretty close. So be warned, technical jargon ahead.

I first stood up my EC2 instance that I wanted to install my website on.

AWS gives you a vanilla public IP address like 52.x.x.x. I took the time to setup my website, install my themes, configure security, set up the shop, and everything I could think of to get it looking perfect. The problem was that my website only worked by going to my public IP like 52.x.x.x in my browser. Well this was no good, since I wanted it to be my domain, madisonbahmer.com.

In combination with the above, the new Shop integration with Paypal requires me to use an SSL certificate and conduct all transactions over https. I certainly wasn’t going to pay for my own from a random SSL Certificate website and try to figure out how to set it up on my machine, so instead I utilized the AWS Certificate Manager which is FREE when you use an AWS Elastic Load Balancers (ELB). I was just fine with that too.

So I go through the trials of setting up a Certificate for madisonbahmer.com (which by the way, I screwed up once) and now I have this crazy url that directs traffic to my personal EC2 instance.

Great, it listens to both http and https and then directs traffic to my EC2 instance’s website. Now, when I hit the crazy load balancer address like Website-LB-XXXXXXXX.us-west-1.elb.amazonaws.com, it redirects to my 52.x.x.x domain and you can see my website. First off, this was confusing to me because I expected the ELB’s address to remain in the browser url, not my raw instance IP address, and second, I was now stuck.

The reason I was stuck is that I had been trying to both configure my website to flip over the new https://madisonbahmer.com AND apply my CloudFlare updates at the same time. Within WordPress, when you change your site url over from 52.x.x.x to say https://madisonbahmer.com, I also needed to resolve my DNS resolution settings at the same time in CloudFlare. So I would flip the settings, my site would go down, and then I would be frantically trying to flip my DNS resolution settings over from my old website to this new one (which is ideally almost an instantaneous transition if I do it right). The problem was that in CloudFlare, an A type record requires an IP Address, where as my ELB only had a long url.

This had been driving me crazy for a couple of weeks. Nothing I seemed to do, read on Stack Overflow, google around, etc would get my darn site back working. So after the night was over, I would flip it back to my old site IP Address in CloudFlare and start fresh the next day, and repeat. My “new” website remained accessible only at its IP Address.

By some shear amount of luck or idiocy I fired my computer up again today and toyed around with the settings once again. I decided this time to convert my site to https://www.madisonbahmer.com (notice the new www), and I pointed my CNAME record in CloudFlare from www -> Website-LB-XXXXXXXX.us-west-1.elb.amazonaws.com. What do you know? When I went to https://www.madisonbahmer.com I got an SSL Certificate error (this is how I found out I had the wrong certificate on my load balancer, AND that I was finally hitting the ELB). Once I fixed that, cleared my browser cache, my site came up just fine. Note that I had originally requested my certificate to be valid for madisonbahmer.com ONLY, where as my new certificate I asked for *.madisonbahmer.com and the normal url. This fixed that issue.

Side note, this is the link to CloudFlare’s documentation on how to set up an ELB with your site. No where does it say the Name field should actually be your server domain name or prefix (like www). Maybe I just did’t understand, but I was thinking “elb” in their example was just a reference to my existing A name settings, which mapped from madisonbahmer.com -> my older website IP address.

At this point, I knew I had it on the run, but I could not figure out how to configure CloudFlare to redirect my older http based site to my new fancy https://www site. A quick google search brings up this or this, both of which actually don’t do what I expected. I wasted an hour’s worth of my time trying to 301 redirect http://madisonbahmer.com to https://madisonbahmer.com, then 301 redirect https://madisonbahmer.com to https://www.madisonbahmer.com…. nothing worked, except for the https://www site if I put it directly into the url.

Then, I realized that my CloudFlare DNS configuration might really be that simple. Just apply madisonbahmer.com as a CNAME to redirect to my Elastic Load Balancer. What do you know? it worked! At time of writing I can now do:

  • http://madisonbahmer.com
  • www.madisonbahmer.com
  • https://madisonbahmer.com
  • https://www.madisonbahmer.com

And all of them resolve to the proper destination! Finally! My final mini simplified architecture diagram looks like the following:

Hopefully this saves me the pain of when I have to do this again, and it saves some pain for others as well. While I am not an expert by any means, I ran into all of the above and now am at a happy place with my website.

5 thoughts on “AWS EC2, Elastic Load Balancers, and CloudFlare

  1. Bruno Alexandre says:

    Hi,

    First of all, amazing article and thank you for adding it, it does save a ton of time! 🙂

    Regarding the HTTP -> HTTPS redirect, did you try adding a page rule that says:

    from: http://*.madisonbahmer.com
    rule: Always use HTTPS

    it should work without hassle…

    Now, my issues

    I’m in your step where https://www.domain.com works but not http://www.domain.com (note https) and I still have the certificate error as the certificate is being set as shared CF certificate and not the one I created in AWS Certificate Manager (with wildcard and without)…

    You didn’t specify the entire image on your domain, but I’m assuming the cloud icon is GRAY and not ORANGE for both entries, right?

    What am I missing from the certificate, why am I getting CF “ssl387235.cloudflaressl.com” cerficate and not the one attached to the LB?

    1. Madison Bahmer says:

      So I have a bunch of legacy rules within CloudFlare’s page rules, given that I did not fully trust the transition internally within WordPress from a non-https site to an https based site. My 3 free page rules are set up as follows:

      http://domain.com/* -> https://www.domain.com
      http://*domain.com/* -> https://www.domain.com
      https://domain.com/* -> https://www.domain.com

      All with 301 redirects. The cloud icon’s on the DNS page are both completely orange, not grey.

      I can tell you my ‘Crypto’ section under SSL is set to “Full”, and I have 1 Edge Certificate that CloudFlare appears to have automatically configured for me. Also, if you go to a SSL Cert checker for my domain, it returns the CloudFlare SSL Cert instead of my ELB Cert, but that has only been a problem when AWS automatically tries to renew my SSL Cert within the certificate manager (once a year).

      If you do figure that out (and can propagate the ELB cert without too much hassle to CloudFlare) please leave a comment because that would be nice to have.

      My setup may not be completely correct – I certainly don’t think it is perfect. However after struggle for a while I decided to make this post in hopes that if would help someone else out.

  2. Bruno Alexandre says:

    Hey,

    This is my setup, and I still can’t reach the server on https:

    https://stage.sitecampaign.com/

    works fine on http://stage.sitecampaign.com/

    🙁

    CF DNS: https://s6.postimg.org/jpojh71y9/screenshot_28.png
    CF Crypto: https://s6.postimg.org/iyvtbezkx/screenshot_27.png

    AWS: https://s6.postimg.org/7cbpaac9t/screenshot_29.png

    I’m sure I’m must be forgetting something really easy :/

    can you please check your configuration and see if something is out of place?

    Thank you so much 🙂

  3. Bruno Alexandre says:

    Hey;

    Thanks for your response, but I still can’t wrap my head on this, this is my setup:

    CF DNS: https://s6.postimg.org/xwr994vq9/screenshot_452.png
    CF Crypto: https://s6.postimg.org/uef9cquu9/screenshot_453.png

    AWS: https://s6.postimg.org/wx0ydfgkh/screenshot_454.png

    BTW I’m using AWS EB, upload from Git (CodeCommit -> CodePipeline -> Deploy to EB) (just so you know I’m using EB in front of EC2)

    HTTP: http://stage.sitecampaign.com –> GOOD

    HTTPS: https://stage.sitecampaign.com –> Can’t connect

    and before you see no connection page, the certificate is actually cloudflaressl.com shared name…

    if you open in Firefox, you can even see all certificates names in the warning page.

    Can you re-check your settings and see if I’m missing something?

    Thank you.

  4. Madison Bahmer says:

    So perhaps the difference here is that I am forcing https AND www across my site, preventing http connections from being made at all via a redirect. While I am not familiar with your code flow for deployment, I know that I had to add an extra plugina integration for WordPress + CloudFlare in order to prevent that same SSL certificate error from occurring. Perhaps there is some magic going on there that is out of my scope that ensures my site operates the way it does, but I definitely see in your use case the CloudFlare cert does not match the sitecampaign https connection.

    While the SSL cert inspection for my own website shows CloudFlare, I have not had an issue with the cert rejection in Chrome/Firefox. Within CLoudFlare, I do see that I have `Full (Strict)` instead of just Full compared to your setup. Under the DNS section everything looks the same besides the full domain name, I have `www` and `madisonbahmer.com`.

    Within the AWS section I have an ‘application’ load balancer with both a security policy and SSL cert, and am forwarding both 80 and 443 to my website. Appears to be the same as yours

    I agree it is frustrating – hence why I wrote this post! The only difference otherwise is that I have a CloudFlare WordPress plugin (https://wordpress.org/plugins/cloudflare/) that may be assisting my setup, and am not using the code flow you are working with.

Leave a Reply

Your email address will not be published. Required fields are marked *