Hosting Static Content with SSL in S3

I have been generally very happy with using AWS S3 in concert with static site generators (I'm currently focused on the Python-powered Pelican). But AWS is a bit arcane, and SSL is pretty arcane, too, so the combination was a little rough, but I've finally figured it out. I got initial help from this post by Sebastian Buckpesch, but that didn't totally work for me. I ended up doing things somewhat differently (and there were missing pieces in that post.)

First, set up your S3 bucket for hosting

  • I outlined this in an earlier post. It's fairly straightforward:
  • Add a new S3 bucket, named for the domain you wish to host
  • Add a landing page, index.html for testing
  • Enable "Static Website Hosting". And also go to "Permissions" make sure that the public has read access. (Also check "Block Public Access" and make sure that's all turned off.)
  • Create a new hosted zone in Amazon Route 53. Add the nameserver values in that new hosted zone into your domain registrar's entries for nameservers.
  • Add a new "A" record, and choose "Alias" and you should see the S3 target available.
  • Wait a few hours (to a day - depends on your ISP, mostly.)
  • Check to make sure you can see everything at the url http://yoursite.com

Then, set up a Cloudfront Distribution

  • Add a new cloudfront distribution.
  • Choose from the S3 buckets in "Origin Domain Name"
  • You can keep the default "Cache Behavior Settings" unless you know you want a specific change
  • You can also keep the default "Distribution Settings" except for:
  • Add 'index.html' (or whatever your index file is set to) as the "Default Root Object"
  • Click "Create Distribution'. You will wait, but you can do other steps while you are waiting

Set up a Certificate for your domain

  • Go to "Certificate Manager" to request a certificate. Click on "Request a certificate"
  • Choose "Request a public certificate", then add the domain name you are using
  • Use "DNS Validation" - since you are already using Route 53, it's easier and works well.
  • In the "Validation" screen that's shows next, open up the domain (it will say "Pending Validation")
  • You'll see a CNAME record to add - just click "Create record in Routh 53", then "Create" at the popup
  • If "Success" with a green box comes up, then it's just time to wait, it will take a bit to validate.

Then, wait, and go back and edit CloudFront

  • Wait until the validation is complete, and also make sure the CloudFront distribution is enabled and working. (Check on this by copy-pasting the CloudFront domain, and checking to make sure your website appears.)
  • CloudFront is notorious for taking a long time for deployment - you might wait as long as an hour.
  • Make sure to do a shift-refresh of the CloudFront managment page (I found that some old settings got cached that were problematic.)
  • Then, edit the CloudFront distribution, and change the certificate from "Default CloudFront Certificate" to "Custom SSL Certificate. In the space for the certificate, your certificate you just made before should appear as an option.
  • Also add your domain to the "Alternate Domain (CNAMEs) box. Click "Yes, Edit".
  • Wait again.
  • Test by again copy-pasting the CloudFront Domain into your browser. Your site should show up, and be secure.

Last but not least, connect Route 53 up

  • Go back to Route53, choose the hosted zone for your domain
  • Click on the A record. Turn off and back on "Alias". That will blank out the "Alias Target" field.
  • Select the CloudFront Distribution for the domain you edited.
  • Click on "Save Record Set" (I did not choose to "Evaluate Target Health")
  • You are done. You should be able to go to your domain, and have it redirect to SSL, and show up as secure.

That should do the trick. One other thing if you are using Pelican - make sure in your "publishconf.py" you use the https:// domain rather than http:// - that way all of your static content will be delivered correctly.

links

social