Migrating your Jekyll Website to AWS

In my previous post I discussed how to setup a simple, static site and host it through Github Pages. In this post we’ll be looking to take things one step further by setting your site up on AWS and distributing it around the world using AWS Cloudfront. I’ll assume that you have already a purchased a domain, if not this can also be done through Route 53.

What is AWS?

AWS (Amazon Web Services) is Amazon’s cloud services platform, where they offer everything from cloud computing to database storage to data analytics and even game development. They’ve got pretty much everything covered but we’ll only be looking at three of their services: Route 53, S3 and Cloudfront. Route 53 handles routing and DNS whilst S3 is a simple cloud storage solution. Cloudfront is a service that speeds up the distribution of your static and dynamic web content to your users across the world, I’ll explain more on this later.

Setting up your website on AWS S3

In order to use AWS and all of it’s features, you need to sign up and provide payment information, don’t worry everything is pretty much free, unless you choose to register a domain. If you’re unsure at anytime what you’re being charged for, head over to your billing dashboard for a comprehensive breakdown of your outgoings.

So you’re signed up and ready to go! First things first, head over to S3. You can do this by clicking the ‘Services’ button and searching for ‘S3’ or by finding it from the drop down menu.

This is what you should be greeted with (minus the buckets, obviously).

AWS S3 Home Page

You’re going to want to click ‘Create Bucket’, be sure to select the region closest to where you are based. You should also use a unique name, I chose the name of my website, but anything unique would work. The next bit is optional, but if you want to track traffic and other website activity, repeat the process and create another bucket with the same name, but include the prefix ‘logs’ so you can distinguish between the two.

Next, click the ‘properties’ button and then choose ‘permissions’ option, here we will need to allow the contents of the bucket to be public. To do this click ‘edit bucket policy’, copy and paste the code snippet below and hit save.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOURBUCKETNAME/*"
}
]
}

Below the ‘permissions’ tab, there is another drop down option called ‘static website hosting’. Click ‘Enable website hosting’ and enter your landing page for the index document (usually index.html) and, if you have one, the error page for the error document. You’ll notice there’s a URL, which is called the ‘End point’, this is the public URL of your bucket and will display your website once the content has been uploaded. Don’t worry though, this isn’t the actual URL of your website!

Deploying Your Website

Now you’re ready to upload your website to your S3 bucket. There’s a few different ways to do this, I used the S3_website gem to deploy my site and it really does make the process quite easy and straight-forward if you follow their step by step guide, with everything being done from the command line. If you don’t want to use S3_website you can run ‘jekyll build’ and upload the contents of the _site directory directly to the bucket using the browser. If you do choose to use the S3_website gem please do not upload your private access keys and use environment variables instead when inputting information in the s3_website.yml file. If you need a quick brush up on environment variables, I did a quick post on this subject a short while ago, which you can find here.

Whichever way you choose to proceed, your bucket should look something like this.

At this point, if you click the ‘End point’ link, you’ll see your website, as it’s displaying the contents of your bucket.

What is Cloudfront?

Earlier I briefly explained that Cloudfront speeds up the distribution of your content to users. Here’s a basic example of how Cloudfront works. At the moment your content is hosted on a server in one region, in my case London. If a user in Singapore visits your site, they have to retrieve content from the London server, which, geographically, is quite far. This slows the website down and creates a different user experience depending on where you are in the world. Cloudfront addresses this issue by distributing your content across all of it’s servers worldwide. Now, if a user in Singapore viewed your website or application, the content would be served from Amazon’s server in Singapore, which would make loading times much better and improve the overall user experience for everyone.

Setting up Cloudfront

Now you’re ready to distribute your site through Cloudfront. If you used S3_website to deploy, you may have chosen yes when prompted if you wanted to setup a distribution, if so that’s absolutely fine. Instead of creating a distribution, you would go and edit that distribution. If you have no idea what I’m talking about, that’s also fine, head over to Cloudfront from the AWS Services tab.

If you have a distribution live, you’ll see it, if not you’re going to need to click ‘Create Distribution’. This will bring a pop-up box, choose the web option and continue to the next page, this is what you should be looking at now. For those of you who already have a distribution (through S3_website), select it, click ‘distribution settings’ and hit edit, this will bring you to a similar page.

If you’re ever unsure about what each field refers to, Amazon have included little information buttons on the right, so if what I’m saying doesn’t make sense, click one of those and it’ll explain what each field means.

Firstly, fill in ‘origin domain name’ with your S3 bucket that contains your website, there will be a dropdown if you can’t remember the exact name or link. The rest of the options can remain as their default values, out of preference I changed the Viewer Protocol Policy to ‘HTTPS Only’, but I’ll leave that up to you.

If you have a registered domain name, through Route 53 or another provider, enter that in the Alternate Domain Names text box. Next, you’re going to want to choose ‘Custom SSL Certificate’, this will give you the option to request or import a certificate from ACM (Amazon Certificate Manager). It’s fairly simple and straight-forward, after entering your domain name you’ll get an email, to which you’ll need to approve the request. Once this is done, you’ll be able to choose your certificate from the drop down list.

The ‘Default Root Object’ should be your landing page, index.html. If you’ve chosen to setup logging, choose the bucket that you setup earlier.

Once this is all done you’re ready to ‘Create Distribution’! At this point I’d suggest taking a break, browsing reddit, brewing a cup of coffee, or whatever it is that you do as it’ll take Cloudfront around 20 minutes to create your distribution.

Once completed, your distribution would have gone from ‘In progress’ to ‘Deployed.’ At this stage everything is pretty much ready to go, we just need to setup some routing in Route 53.

Finishing up with Route 53

Head over to Route 53 on Amazon’s services tab, here you’re going to want to ‘Create a Hosted Zone’. Once this is done, copy the NS (Name Servers) over to your domain registrars admin for ‘Name Servers’. Once this is done, Route 53 will handle the configuration of the domain.

Next, select your hosted zone and click ‘Create Record Set’. Here we are looking to connect up our domain and Cloudfront distribution. Make sure it’s an ‘A’ record (IPv4 Address) and that you have ‘Alias’ checked to ‘Yes’. This will prompt you enter an ‘Alias Target’, which will be your Cloudfront URL and will look something like the picture below. It’s located under the ‘Domain Name’ heading on the Cloudfront Dashboard.

Save the record set and boom, you’re done! As before, it may take sometime to kick in, but be patient!

Setting up a redirect for WWW URL’s

Assuming at this point your site is secure and up and running, you may want to consider redirecting the www.yourdomainname.com to yourdomainname.com. At present, if you try and type www.yourdomainname.com you should see an error, this is because we haven’t setup any routing for it, good thing it’s quick and easy!

It’s pretty much similar to whole process we’ve just done, with a few minor adjustments. When creating a bucket, you’ll want to prepend it with ‘www’ and when clicking on the ‘Static Website Hosting’ tab, you’ll want to choose the ‘Redirect’ option and set the redirection to yourdomainname.com.

Once this is done, setup a separate Cloudfront distribution that links to your ‘www’ bucket. Next, add another ‘A’ Record in Route 53 and set the Alias Target to your new Cloudfront URL and boom, you’re done! If you type www.yourdomainname.com it should redirect to yourdomainname.com.

Summary

Hopefully what I’ve written above worked for you, this post was describing my process that worked for me. I’m aware there’s a lot of different ways to do things and some of the above may not work for you. A lot of the above was through trial and error and trawling through Amazon’s extensive documentation. For those who are interested, you can view my website here. If for whatever reason something doesn’t work or you’d like to ask a question about anything, feel free to drop me a message and I’d be happy to help in any way that I can!