Setting Up an HTTPS Static Site Using Amazon AWS S3 and Cloudfront
For many years I have been paying a cloud server provider to host my personal site. At some point I had a blog, but lately, with blog communities like Medium, it had been reduced to a one page index.html.
But the cost of having one cloud server, even if it’s the tiniest one, ends up costing around $15 month, which if you add up in months and years, can become a good chunk of money.
So at the beginning of this year, I decided to look at two technologies that can help me with this, cost-wise. One is a static site generator and the second is Amazon’s AWS service which allows you to host static websites with HTTPS on S3 and CloudFront.
The amazing thing about using S3 to host your site is that it costs literally a few cents per day. Here’s a chart of what I’ve paid for hosting my personal static site for half of the month of February 2016.
I will write more about static site generators in another post, but for this post, I will concentrate on how to setup Amazon AWS to host your secure static site.
Why is it important to have your own domain?
With Medium and Facebook and Wordpress and Tumblr people still think it’s not important to have your own URL and your own site. I personally think that it’s very important to brand yourself with your own URL and furthermore to have your own email address (not hotmail.com, gmail.com, etc.) and start building your mailing list. Social websites and platforms come and go, but your domain can be with you forever and you can still use the social platforms and duplicate content there, but always using your own website as the place where the post originally appeared.
Even if you’re a full time employee I think you should always think about branding yourself. You never know what will happen in the future and you’ll be in a better position if you have a loyal group of followers that know the services you provide.
Step 1: Register a Domain
The first thing you need to do is register your domain with a registrar. I won’t be guiding you on that part, but make sure you have access to the DNS setup and that you receive emails from that domain’s administrative contact (like webmaster@). You will need this for the HTTPS certificate registration part.
I also recommend setting up your email services using Google’s G Suite. At the time of this writing they had a basic plan for $5/month which more than covers what you’d use for productivity tools.
Whatever email provider you use, make sure you have access to webmaster@ by sending a test email to that address and making sure you receive it.
Step 2: Create the static S3 buckets
If you haven’t done so, you’ll need an AWS account, so go there and sign up.
After you’re set up, go to the Services menu and click on S3. Next, you will create a bucket withe the same domain name you will use as our final destination.
But before you click on the Create bucket button, here’s a little disclaimer. You need to choose if you want to use a www before your domain or not.
WWW vs non-WWW
You need to choose now if you’ll use a www in front of your domain or not.
Why is that important? For SEO purposes you want to have only one version of your website, otherwise your posts can appear on both the non-www and www versions and you will lose rank on all the search engine’s databases.
I tend to favor non-www. To me the www is not really applicable these days (it stands for world wide web) because almost every domain created today is for web serving — plus it’s less characters to type everywhere.
If you want to make the www version of your site the default one, you will need to inverse whenever I talk about www to non-www and vice versa. That’ll make sense as you follow along.
So, back to our program. Click on the Create bucket button. Here’s what the next dialog looks like:
Click on Next and skip that Set properties screen with another click on Next.
On Permissions you want to click on Read the Objects for Everyone like so:
Click on Next and then click on Create Bucket on the bottom right.
Now look for the bucket you just created on the S3 home page and click on it. Click on the Properties tab.
Click on the Static website hosting and select Use this bucket to host a website. Leave the other options as they are. Notice that S3 assumes your main page will be index.html. If for some reason you’re not gonna use that, change it there.
Click on the Save button.
Ok, now go back and create another bucket, this time it will be the www version of the domain. Make sure to select the same Region you had on the other bucket.
Click on Next twice and select the same permissions — Everyone set to Read for objects, and save the bucket.
Now look for it on the list, click on it, click on Properties tab, select Static website hosting and this time you will select Redirect requests. On the Target bucket or domain field enter your non-www bucket like so:
Click on Save.
Step 3: Test the index.html on your main bucket
So that we know things are working out, create an index.html with just a simple welcome message and upload it to the main bucket.
When you upload, make sure to also set the permissions as Everyone and Public.
Select the defaults for other stuff. Now you should see your index.html file in the Objects list. To see if you can get to it, click on the file and on the Overview tab, you should see the URL for the file. Copy the URL.
Now open an incognito window and paste the URL. You should see the index.html rendered.
Step 5: Request a certificate
Go to the Services menu and look for the Certificate Manager service.
On the top you’ll see a Request Certificate button. Click on it.
On the Domain name box, enter the main name for your site and click on Review and request, and then click on Confirm and request.
This is where you’ll need access to the domain name’s webmaster email or administrative email.
You will get an email like this one:
Click on the approval link and click on the I approve button.
Now if you go back to the Certificate Manager service home page, you should see your brand new certificate.
Step 6: Create the CloudFront Distribution
The best way to serve static content is by using a Content Delivery Network or CDN. You can research more about it on the web, but the gist of it is that your static content will be copied to hundreds of servers around the world so that users that request your website will be served by the closest Amazon server. Amazon’s CDN is called CloudFront.
Even if you don’t want to use CloudFront, this is the only way currently to be able to use the free Amazon HTTPS certificate you just created.
So click on Create Distribution and select Get Started under the Web section (we are not going to be using RTMP).
On Origin Domain Name enter the non-www bucket from the pull down selector. Leave Origin Path empty. This is only if you want a sub-directory to be the root path. Leave the rest as is.
Default Cache Behavior Settings
On Viewer Protocol Policy select Redirect HTTP to HTTPS. Leave the rest as is.
On Alternate Domain Names (CNAMEs), put both your non-www and www domain names.
On SSL Certificate, select Custom SSL Certificate, and on the pull down below select the certificate you created earlier.
Finally on the Default Root Object enter index.html.
We’re all done. Click on the Create Distribution button.
Now you’ll see your new distribution created and a little spinner there. It takes a long, long, long time for this to be created. I think I waited for a couple of hours and 24 hours is not crazy, so don’t fret if you see this for hours.
Step 7: DNS setup
Now we need to move the Name servers from your domain registrar to Amazon’s Route 53 DNS service. Don’t worry, it’s almost free (nothing is totally free with Amazon, but for most sites you’re pay cents per month).
Why do you need to do this? I made myself the same question and was almost annoyed that after all this I had to do a Name server move. But it makes total sense.
The issue is that the @ record on your domain registrar needs to point to an IP address. You can not use a CNAME, like the CloudFront domain name we’re provided. So it’s impossible to use a non-www domain (like example.com) without moving the Name servers to AWS. Additionally, even if you only use the www version, the HTTPS certificate won’t be valid. I think this has to do with the termination of the request on the CloudFront server.
The good thing is that the setup is really easy and transfers happen in a few minutes.
So go the AWS Services and look for Route 53. Once on the home page, select the Get started now on the DNS management section.
Now click on Create Hosted Zone and on the Domain name box enter your domain name and then click on Create.
Now you will see some entries on DNS record. The first one says NS type (or name servers). You need to go to your domain registrar and replace the ones you have (for example the GoDaddy NS servers) with these ones. Make sure to copy them, as you’ll need the name servers for the next step.
So I’ll show you what I did on my GoDaddy account, but it should be something similar on your registrar.
Important note: if you have enabled the G Suite or other external email service, make sure to copy the MX records somewhere as you will need these when you setup the Route 53 settings. This is what mine looks like:
On the domain list select your domain and then select the Nameserver icon and select Set Nameservers.
Then select Custom and click Add Nameserver.
Now enter one by one the servers from the AWS Route 53 Name Servers, one for each line. Remember, this is on GoDaddy. Your setup might be different. Notice that you don’t enter the last dot on the server URLs.
Press OK to save the changes. You will have a final change to review the changes and press Save.
Now go back to Route 53 and click on Create Record Set, to create the domain’s A record, as follows.
Leave the Name record empty, and on Type leave A — IPv4 address.
Now on the Alias field, select Yes and when you click on the Alias Target field, select the CloudFront Distribution that corresponds to your domain, and then click on Create.
Now we need to create the www record. So click on Create Record Set, enter www in the Name field, and once again, select your CloudFront distribution from the pull down.
The last step is to create your MX records for your email service. Click again on Create Record Set, leave the Name field empty and select Type of MX — Mail Exchange.
Now on the value, enter the values that you copied from your existing MX records. Notice that you enter the priority number, then space, then the domain. Enter all of them in the same text box field.
And then click on Create.
That’s it! In a few minutes or hours, depending on your registrar, you should now go to you domain in your browser and get an HTTPS enabled home page.
The first time you go through this process, it might seem a bit long, but after you do it a couple of times, it all makes sense and becomes more second nature.
By the way, if you are looking for help setting up your web or engineering infrastructure, feel free reach out to me. I am the founder of MVP Lean, a consulting firm to help startups navigate the choppy waters to success.