Static website hosting with AWS
This post will show you how to setup and use Amazon Web Services to host a static website. Using four of the available services (S3, CloudFront, Route53 and Certificate Manager), you can have secure, scalable, reliable and performant hosting for just a few dollars per year!
Getting started
Amazon Web Services is the most popular cloud computing platform, and is used by some of the largest companies out there. What's great about AWS is that you only pay for the computing power you use, which makes for a very inexpensive solution for static site hosting.
In order to get started, you'll need a domain name for your website. Personally, I prefer managing domains with Hover for it's simplicity and fantastic customer service, but there are many other options available.
Of course, you can't host a website that doesn't exist, so you'll need to actually build it first! There are many solutions out there for creating static websites. I built and use a generator called Fire Starter, a lightweight asset pipeline that uses modern tools like Grunt, SASS and Pug, but there are many other options available! Check out StaticGen for a list of top open-source static site generators.
Create and setup an AWS account
For this tutorial, we'll keep things simple and assume you already have an AWS user account setup with permissions that allow you to use these four services (S3, CloudFront, Route53 and Certificate Manager).
If you'd like to learn more about IAM and setting up policy permissions, check out these helpful guides: Create an IAM user and What is IAM.
Create an S3 bucket for file uploads
In order to have somewhere to put your website files, you're going to need to setup an S3 bucket and configure it for static site hosting. First, go to the S3 management page and click Create Bucket.
For the bucket name, you want it to match your domain name (this is important), but don't include the www, we'll get to that later. You can choose whatever you'd like for the region, I've gone with US East.
Don't worry about anything on the Set properties page, just click Next to advance.
On the Set permissions page you'll want to make sure both Read boxes are checked for the Everyone group in public permissions.
Check to make sure your bucket name matches your domain name and that you've selected the region you want. If everything looks good, click Create bucket.
Now that the bucket is created, you'll need to make sure it's setup to serve static assets. Click the bucket name to open it, navigate to the Properties tab, then click the Static website hosting panel.
Here you'll need to specify filenames for the index and error documents. I've chosen to use 404.html
for the error document, but you can use whatever names you'd like.
Congrats, you just created your first bucket! (Unless stuff like this is in your job description, in which case you've just created one of many. Woo!)
Now you can upload your static website files into the new bucket. Once that's done you should be able to access your site via the bucket endpoint, which you can find in the Static website hosting panel.
Create a CloudFront distribution
The next step is to setup CloudFront, Amazon's Content Delivery Network service. This will make your website load really fast from anywhere in the world, and allow you to use HTTPS.
First, you'll need to create a CloudFront Distribution.
Click the Get Started button in the Web section.
Next, you'll see a pretty long form for setting up your Distribution. Don't worry, most of these options can be left at their default values.
The first field is the Origin Domain Name, and it's a bit misleading: the URL suggested for you in the dropdown is not the one you should be using. That's actually the REST API endpoint for the S3 bucket instead of the one that is set up as a static website. Your S3 website endpoint is the one from the Static website hosting panel, and looks something like this: http://leadnative.com.s3-website-us-east-1.amazonaws.com
. Go ahead and paste yours in that field, and you'll see the Origin ID field automatically gets filled out.
Now scroll down until you see Compress Objects Automatically and switch it to Yes. Below that, put the domain of your website into the Alternative Domain Names field, and make sure it is the same as the one you used for your S3 bucket name.
Finally, scroll to the bottom of the form, find the Default Root Object field and type in index.html. Then click Create Distribution.
It will take AWS some time to create a distribution. Once the process is complete, you can find your CloudFront URL by clicking on your newly created Distribution from the list and looking for the Domain Name field. It will look something like this: d2k7kmoyvncwgp.cloudfront.net
Point your Domain to CloudFront
Now that you have your website up and running, it's time to connect your website Domain to the CloudFront Distribution using Route53. Click the Create Hosted Zone button to get started.
Enter your domain name into the field and click Create.
Now that your Hosted Zone is created, click Create Record Set.
Leave the Name field empty (without the www.) and make sure Alias is set to Yes. In the Alias Target dropdown, select your CloudFront Distribution, then click Create.
You'll also want to add a record for IPv6, since it's enabled by default with CloudFront. That can be done the same way except with an AAAA type.
The last step here is to take the name servers (NS) AWS provides and update your domain name servers with your domain registrar. This will allow you to view the contents of your CloudFront Distribution on your website domain. Here is a guide for how to do that with Hover and another for Namecheap
Whenever you make changes to DNS, those changes don't apply immediately. DNS uses a technique called caching which means it can take a little while for the system to notice changes. When you make a DNS record change, it can take anywhere from 5 minutes to 1 hour for it to apply.
Add www redirection
Your website is now live and working, but not when you add www in front of the url. This is because we've only setup the bare domain, and in order for the www version to work as well, you'll need to setup some redirection.
First, create another S3 bucket for the www version of your domain. The only thing that matters here is the name; you can leave all other settings at their defaults.
Now go into the Properties of the new bucket and click on the Static website hosting. Select the Redirect requests option and add the website Domain you've been using so far.
Also, make sure to copy the Endpoint since you'll be needing it later.
Next we’ll create a new CloudFront Distribution to point to this S3 redirection Bucket. Again, make sure you're using the URL you copied from the last step for Origin Domain Name and not the one it suggests.
Now scroll down until you see the Alternative Domain Names field, and add your www Domain here. That's all that needs to be done for this distribution so you can go ahead and create it.
Head over to your Domain in Route 53 and hit Create Record Set. This time fill in www
as the Name, and pick your new CloudFront Distribution from the Alias Target dropdown. Afterwards, create another record set the same way, except with the AAAA type for IPv6.
That's it! Just give it some time for the DNS to propagate and if you visit your www version of your domain, it should redirect you to your non-www version.
Set up HTTPS
Now that you have a working website over insecure HTTP, you're ready to setup HTTPS, which is something every website should be using. In order to do this, we're going to use Certificate Manager to request a certificate for use with CloudFront.
Type your Domain name in the field then click Add name to this certificate and add the www version of your domain as well. Hit Review and request once you are done.
Review and confirm the certificate request and then AWS will attempt to send you an email for validation. You can click on the arrow next to the domain name to see which email addresses AWS will attempt to send it to. This is probably the hardest step since you need to ensure you can get email. In our case, we have an account setup at admin@leadnative.com, and that's where we approved the request.
Since you're setting up a certificate for two Domains (the non-www and www versions), you’ll be receiving two emails with a link to verify that you own the Domains. Clicking the approval link in the email will send you to this page. Make sure to click the I Approve button for both Domains.
Now that you have a certificate, you'll need to attach it to both of your CloudFront Distributions.
Pick one of your Distributions and click on the Distribution ID to see detailed view of information, then click the Edit button at the top of the page to modify those details. You should see a field called SSL Certificate, which is set to Default Cloudfront Certificate by default. Switch that to Custom SSL Certificate instead, and select the certificate you just created from the dropdown menu. Then scroll down to the bottom of the page and click Yes, Edit to save your changes.
Next, click on the Behaviors tab, select the only item in the list of behaviors by checking the checkbox at the far left, and then click the Edit button.
Find the Viewer Protocol Policy field, and change it from HTTP and HTTPS to Redirect HTTP to HTTPS. Then scroll down to the bottom of the page and click Yes, Edit to save your changes.
For the second Distribution (www), you will want to attach the certificate as before, but you can skip the edits to the Behaviors tab. Leaving the Viewer Protocol Policy as HTTP and HTTPS is important for the www distribution because we want our users to go straight to the HTTPS version of our non-www Domain. As opposed to redirecting to the HTTPS version of our www Domain before redirecting again.
The S3 Redirect Bucket that you created for the www version of your Domain is redirecting to the HTTP version of our non-www Domain. You should switch this to the HTTPS version to prevent the extra redirect. Open up the S3 Redirect Bucket, head to the Properties tab and select Static website hosting. There you want to make sure the Protocol field is set to https
. Click Save once that's done.
Party 🎉
You're all done! Thanks for reading and congrats on making it this far. Now you have secure, fast, reliable static site hosting that costs next to nothing.