06 Oct 2018

Website hosting on AWS, using S3, CloudFront and ACM

Easy, cheap and secure website hosting on AWS. This can be achieved using S3, CloudFront and ACM.

Before you can start with website hosting on AWS, you should register a domain. After domain is registered you can proceed with website hosting.

Website will be deployed in four parts:

  • S3 to hold the website files;
  • CloudFront to serve those files;
  • ACM to generate certificate to serve those files over secure connection;
  • Route 53 to point domain to CloudFront so that website is accessible through domain;

Create an S3 Bucket

S3 is AWS service for storing files. In case of website, it will hold all html, css, javascript and other files needed for website to work and to be displayed properly.

To access S3, go to your AWS console. Click on the “Services” in the top left corner of the page. In the search box on top, type “S” and click on “S3”.

When S3 page is displayed, click on the “Create bucket” button.

S3 will ask you to pick a name for your bucket. You must name your bucket with the exact domain name that you want your site to be available at. For example, if you own the domain my-sample-website.com and want your website to be available at my-sample-website.com, then the bucket must be named my-sample-website.com.

You will also need to select a region for your bucket. For the region I recommend that you select “US East (N. Virginia)” because it’s the cheapest option. Click the “Create” button, and S3 will create your bucket.

Click on the row of the bucket you have just created, and the details pane will open on the right side of the page. Then click on the “Properties” section.

To enable website hosting click on the “Static Website Hosting” section:

Select “Use this bucket to host a website”, enter name of your index document and click “Save”.

Also at the top of the form, you can see “Endpoint” url with value like http://my-sample-website.com.s3-website-us-east-1.amazonaws.com. You have to save this URL for the later use.

Next, you need to change the permissions on this bucket so that all the files in this bucket can be viewed by anyone. To do this, we’re going to use something called a “bucket policy”, which tells S3 how you want it to treat the contents of the bucket. This bucket policy is written in a special JSON-based format, and how it works can be found in the AWS documentation. To open bucket permissions click on the “Permissions” tab.

Next step is to click on the “Bucket Policy” button.

You’ll see a big text box, marked “Bucket policy editor”. Copy-paste this text into the bucket policy editor:

{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "Allow Public Access to All Objects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-sample-website.com/*"
        }
    ]
}

In the line that starts with “Resource”, you’ll need to replace my-sample-website.com with the name of your bucket. Then click on the “Save” button.

Spacing and formatting of bucket policy does not matter.

At this point your S3 bucket is all set to host a website. People can access to your website by opening “Endpoint” url inside their browser. As this url is so ugly, you will have to make it accessible via domain name. But first, put some content into your bucket.

You can upload content by clicking on the “Overview” tab and then clicking the “Upload” button. Drag and drop all your website content into displayed dialog and click “Upload”. Your content should now be uploaded into bucket and website will be visible when URL is open in browser.

Make a CloudFront Distribution

Next step is to configure the CloudFront Distribution. CloudFront is Amazon’s Content Delivery Network (CDN) service. It will be used for two things: to make your website load fast anywhere in the world, and to allow you to use HTTPS. To open CloudFront, go to the Services, search for CloudFront and open CloudFront when found.

You should see “CloudFront Distributions” page. Click on the “Create Distribution”.

Select a web delivery method by clicking “Get Started” under the “Web” section.

The next page will be a long form where you can specify many different options for your distribution. Don’t worry, you can leave most of these options at their defaults, but there are few that need to be changed. The first one is the “Origin Domain Name” — it’s the the very first field in the form. Click on it, and Amazon will show a dropdown menu with your S3 buckets listed. Instead of selecting S3 bucket from the list, paste S3 bucket endpoint url, with the scheme (http://) part omitted: my-sample-website.com.s3-website-us-east-1.amazonaws.com.

Next, scroll to the “Compress Objects Automatically” and set it to “Yes”. Slightly below, a field named “Alternate Domain Names (CNAMEs)” can be found. Put the name of your domain into this field, eg. “my-sample-website.com”. Value should be same as the name of the S3 bucket you’re using. Last field to change is “Default Root Object”. It should contain value of the default page that will be open as your website. Enter “index.html” in case it is index.html.

Click “Create Distribution” to create distribution.

It will take few minutes until AWS creates your CloudFront distribution.

Point Domain to CloudFront

To point a domain to the CloudFront, open the Route 53 service. It is the same service where domain was registered.

Click on the “Hosted zones” and “Create Hosted Zone” if your domain’s hosted zone does not exist. For domain enter your domain name, eg. “my-sample-website.com”.

If hosted zone already exists, just open it by clicking on the hosted zone name.

On the displayed screen, you need to add a new record set to point your domain to the CloudFront distribution. Click on the “Create Record Set”, leave the “Name” field empty and select “A – IPv4 address” for the “Type” field. Just beneath that, there’s an “Alias” field with two options: select “Yes”, which will cause the “Alias Target” field to appear. When you click on the “Alias Target” field, Amazon will show another helpful dropdown menu, with entries for both S3 and CloudFront. Select the CloudFront distribution you have just created, not the S3 bucket. Then click the “Create” button.

It will take some time until these changes are visible and until your website is accessible through the web browser.

Redirect WWW to the Bare Domain

At this point, your website will not work if you include “www.” as domain prefix. What you have to do is to redirect the domain with www to the bare domain, so when someone opens “www.my-sample-website.com”, he will be automatically redirected to “my-sample-website.com”. Steps to configure this are pretty similar to everything you already have done for the bare domain.

Go to the S3 service. Make a new S3 bucket named after your domain with the www. If your domain is my-sample-website.com, then the bucket should be named www.my-sample-website.com. Click on this newly created S3 bucket to open the details pane, click on the “Properties” section, and then click on the “Static Website Hosting” section on the bucket properties page. In the static website hosting form, select the “Redirect requests” option. For the “Target bucket or domain” field, type in the name of your other S3 bucket, that does not have the www in there. Then click the Save button to save your changes.

Next, you need to create a CloudFront distribution for this redirect bucket. Go back to the AWS Console and click on the CloudFront. Create a new CloudFront distribution just like before, but this time, put the URL for your domain with www S3 bucket in the “Origin Domain Name” field. Remember, the dropdown menu for this field is misleading: copy and paste the website endpoint URL from the static website hosting form, instead of selecting the S3 bucket from the dropdown menu. You should also put domain with www prefix in the “Alternate Domain Names (CNAMEs)” field. Everything else is the same: still a web distribution rather than RTMP, and you can still leave most of the fields at their default values.

Finally, you need to add entry into hosted zones for this CloudFront distribution. Go to the Route 53 service. Add a new record set for your domain, but this time, enter www for the name. This is how Route 53 knows the record should apply to the domain with “www” prefix. Just as before, the record should be of type “A – IPv4 address”, with “Alias” set to “Yes”. Select the CloudFront distribution that you have just made for the domain, and then click “Create”.

Once again, it will take some time until your website is accessible.

Setup HTTPS

Now, when you have a working website over insecure HTTP, you are able to set up a secure HTTPS for your website. To do this, you are going to use the next AWS service, called Certificate Manager, or ACM. HTTPS relies on something called “certificate”, which used to be very difficult and expensive to get before ACM came along. Now, all you need to do to get an HTTPS certificate, is to indicate which domain (or domains) you want HTTPS on, and verify that you own these domains. Once you have your certificate, you can give it to CloudFront, and then CloudFront can handle HTTPS.

Go to the “Certificate Manager” AWS service by searching its name. Then click on the “Request a certificate” or “Get started” button. On the next page select “Request a public certificate” and click the “Request a certificate” button.

You’ll be asked to add domain names that you want the certificate to apply on. Type your domain name twice: once with the “www”, and once without it. You’ll need to click on the “Add another name to this certificate” button to get a second line to show up. Click on the “Next” button.

On the next page select “DNS validation” option as a validation option. Click on the “Review” button.

Click on the “Confirm and request” button.

At the “Validation” page expand each domain and click on the “Create record in Route 53”. Click on the “Continue” button after.

Once you’ve got your certificate, and it is in issued status (not in Pending validation status), you need to give it to the CloudFront so it can use it. Go to the CloudFront service. You have two distributions, one for the bare domain and one for “www”: you’ll need to make the same change for both.

Pick one of your distributions and click on the distribution ID to get a detail view of the information for that distribution. Then click the “Edit” button at the top of the page to modify those details. You should see the 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 on the very 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.

Don’t forget to make these edits to both CloudFront distributions!

You’re all done! You should now have a working static website, hosted on AWS, which uses HTTPS for all connections.