Getting Cloudflare, CloudFront + S3 to cooperate over (strict) SSL

Spoiler alert: you do NOT need to provision a custom certificate

Sam Becker
Dec 3, 2018 · 3 min read

Recently I found myself serving a dynamic Heroku app (app.mydomain.com) and a static S3 website (www.mydomain.com) from the same domain, which I manage through CloudFlare. Getting these services to cooperate over (free) SSL proved more difficult than anticipated.

Some background

Typically, I configure S3-based sites to use Cloudflare'sFlexible SSL, because Amazon doesn’t automatically provide HTTPS access to statically hosted buckets. However, the secure login pattern of my Heroku app required Cloudflare’s SSL to be set toFull (seemingly a requirement of the Rails gem Devise—another story for another time).

In order for S3-based sites to be compatible with Cloudflare’s Full SSL setting it seemed necessary to deliver them through another Amazon service: CloudFront. CloudFront is best know as a CDN but it also provides a single point of entry and configuration for a web asset, providing built-in certificate management.

I found this approach surprisingly complicated and poorly documented, so I’m posting the steps I believe are required in order to get this setup working properly.

This approach assumes a custom domain connected to Cloudflare as well as a bucket on S3 configured for static website hosting.

How I got it to work

  1. At this point, you should also have a bucket on S3 named after the custom domain you are using, something like www.mydomain.com. My bucket was setup for Static Website Hosting though that may not be a requirement.

That should be all you need for Full (strict) SSL access to your statically hosted S3 files on a custom Cloudflare domain.

Another approach (which I could not get to work)

I have a hunch that there’s a simpler, more standard and secure way to achieve a similar result. I would still like to get the following approach to work:

  1. Use a standard S3 bucket not set to publicly host files.

I tried some combination of those steps and couldn’t get it to work, though I can’t help but think that something close to that strategy would work.

Feedback welcome

This approach took a lot of trial and error. I’m pretty sure getting this to work desirably required all of the above settings, but some may be incorrect if not superfluous. I would love feedback on better ways to achieve this result. Please reach out with any builds or criticisms.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store