Using Amazon Cloudfront with Rails and Apache and https

Cloudfront is an easy way to cache assets from your Rails application. However there are several gotchas, so these are the steps I took.

Let’s say you have this website:

  • Your domain name is superidea.com
  • You have an SSL cert so it is running at https://www.superidea.com
  • You would like assets being served from /assets to be served from cloudfront
  1. Create a Web Distribution:
    Log into your Amazon AWS Console

2.  Distribution Settings

  • Origin Domain Name: This is the domain name of the assets you want to cache.   Since you want to cache assets (images, css, js) put in www.superidea.com
  • Origin Protocol Policy: if you know you are using SSL, you can select it here

  • Forward Headers: One of the things to avoid problems with CORS is to forward headers with ‘origin’.  What this will do is forward your ‘Access-Control-Origin’ to cloudfront

Afterwards you can click save

3) Edit Distribution

 

You will see that now your distribution is:

  • name: dnrjqjliq6rex.cloudfront.net
  • Status: In Progress

At this point you can continue, but all of your URLS will be dnrjqjliq6rex.cloudfront.net\assets\main.css

We want to make it look a little prettier, so click into the distribution, click general, then click ‘edit’

4) Custom SSL

Now let’s say we want things mapped from cloudfront.superidea.com to  dnrjqjliq6rex.cloudfront.net.  The first thing is we need an SSL Cert, and we can get one through AWS.  Click Request or Import a Certificate

  • Enter the domain name ‘cloudfront.superidea.com’.  What will happen is a series of validation steps to ensure you actually own it
  • Alternate Domain Names: Enter in cloudfront.superidea.com.  Later we will make a cname record for this
  • Custom SSL Certificate: Select the certificate
  • Custom SSL Client Support:  If you want to save money (like a LOT) then select the SNI support.  Most browsers support this anyways.

5) Create cname record

  • Create a cname record of cloudfront to –> dnrjqjliq6rex.cloudfront.net

6) Rails configuration
In production.rb set

config.action_controller.asset_host = “cloudfront.superidea.com”
And ensure your assets are using Rails helpers that point to the asset pipeline (like image_tag, etc).

7) Apache Vhost Configuration

If you don’t add any CORS configuration what will happen is that

www.superidea.com will access cloudfront.superidea.com and in your browser console, you will see a bunch of CORS problems.

With the setting you specified earlier, cloudfront will read one of your original assets such as

  • https://www.superidea.com/assets/main.css
  • Caches it, forwards the origin header
  • Then your rails site accesses it as https://cloudfront.superidea.com/assets/main.css

In your Apache vhost file add this setting

<VirtualHost *:443>
Header set Access-Control-Allow-Origin "https://www.superidea.com"

If you open chrome and check, the response headers for any request should be

Response Headers:
access-control-allow-origin:https://www.superidea.com

So when Cloudfront pulls in the asset, it will also pull in that header.    An alternative method is to use rack-cors

https://ricostacruz.com/til/rails-and-cloudfront

Restart apache

8) Finally wait until your distribution says ‘deployed’

Deploy the new code with the production config, and if all goes well, you should be distributing from Cloudfront!