Add Amazon Cloudfront as CDN from S3 Storage

I have a small app that was serving file attachments directly from S3. Although I wasn’t doing any processing, it’s still preferred to deliver those over some type of CDN. Here I’ll lay out how I added an Amazon Cloudfront CDN so now my S3 assets are served from there instead of directly from S3.

I’m assuming you already have S3 setup to store your attachment files. This post will talk about the setup using the Paperclip gem, but you can use others like Shrine or Cloudinary.

So first you need to setup an Amazon Cloudfront distribution that will be linked to your S3 bucket.

Go to your Amazon AWS console and create a new Cloudfront distribution. There are loads of settings, and most of them I just left as the default. For the first one “Origin domain name”, click in the box and it will give you the list of all the S3 buckets in your account. Select the one you want. It will auto-fill the Origin-ID box. You can leave the Origin Path blank, or fill it in with a specific folder in your bucket that you want to use. For Protocol Policy, I switched it to redirect HTTP to HTTPS to ensure everything is using HTTPS. Everything else I left as the default. You can change them later. Your distribution is now created. It will take a few minutes to be deployed.

Note that your file needs to be set to public access.

To test it, go to your Amazon S3 bucket, and get the link to a file. It will look like s3.amazonaws.com/bucketname/path/to/filename.jpg. Open it in the browser. Now go to your cloudfront distribution, and replace “s3.amazonaws.com/bucketname/” with your cloudfront url, “xxxx.cloudfront.net”. You should be able to load the file in the browser from the cloudfront url.

What was not obvious to me is that when using the cloudfront url, you don’t need the bucket name. So for the S3 URL of

https://s3.amazonaws.com/bucketname/path/to/filename.jpg

the Cloudfront url is

https://xxxx.cloudfront.net/path/to/filename.jpg

No we can go to our Rails app and setup Paperclip to deliver the attachments from Cloudfront. In config/environments/production.rb

config.paperclip_defaults = {
:storage => :s3,
:url => ':s3_alias_url',
:s3_host_alias => "d30l9ueliue92c.cloudfront.net",
:path => '/:class/:attachment/:id_partition/:style/:filename',
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
},
:s3_region => ENV['AWS_REGION'],
:endpoint => ENV['AWS_ENDPOINT'],
:s3_protocol => 'https',
}

With the key being the :s3_host_alias and :url and :path settings.

And you’re all set! You can also set up Cloudfront to deliver your actual Rails app assets (javascript and css), but I’ll do that in a later post.

credit here

Ghostery extension blocking Google Analytics

I fought for a long time trying to get Google Analytics set up. I tried using the Google Tag Assistant Chrome extension, which was very helpful. I wasn’t getting any errors, I was just not getting any hits, even when I would load the site myself. So I finally figured out what was happening by checking the console – my Ghostery extension was blocking the Google Analytics script from sending its data.

So if you’re having errors with your Analytics data, be sure to turn off any privacy Chrome extensions that may be blocking your scripts. Hope this helps save you some time!