Hosting a static website with S3 and CloudFront

The Simple Storage Service (S3) is a great option to host a static website because it gives us the following benefits:

  • Hosts every file with a 99.999999999% durability [DONE]
  • High availability with an SLA of 99.99%
  • Low cost for usage calculated for every 1,000 requests, plus storage, and data transfer fees

Our first step is to provision a bucket where we will be hosting our website; for DNS resolution, our bucket name must have the same name as the domain name; for this purpose, I have registered the domain s3websitehosting using Route 53.

Latency is an important aspect, so we need to choose a region closer to our end users so we can measure response times for HTTP endpoints using cloudping.info:

We will choose California because it makes sense from my current location:

Once we have created our bucket, let's create our web app locally. An excellent choice is to use a generator to bootstrap the web application; personally, I like yeoman.io. Install the dependencies required by the project (Node.js and NPM). For this app, I will use the Angular JS generator:

npm install -g grunt-cli bower yo generator-karma generator-angular

Now, let's create the project directory:

mkdir webApp && cd $_

Lastly, specify the project name:

yo angular static_website

You must receive a message output such as done, without errors; if not the case, fix any dependencies issues regularly associated with dependencies or versions not being upgraded. After this, try again. You could choose other generators such as JQuery.

Let's execute grunt server to run the web application locally, and grunt-only to prepare the distribution of the web app running all the pipeline tasks configured for this generator.

A great advantage of using these kinds of frameworks is the ability to use workflows that maximize our productivity, because multiple tasks are performed with our code, such as compression and minification of the files and images. When we use CloudFront to accelerate our website, using Edge Locations is essential to have a strategy that allows us to invalidate previous versions of our application; a very efficient way is to version every file that needs to be changed, so CloudFront can identify when a change has been made and put the latest version in the cache:

Now, let's proceed to upload our website to the created S3 bucket (use the webApp/dist directory as our productive version):

aws s3 sync . s3://s3websitehosting --acl public-read

The previous command finds any differences between origin and destination to perform synchronization; in this case, the origin is the actual work directory, and the destination is the bucket s3websitehosting.

Now, let's update the bucket configuration to enable static website hosting:

aws s3 website s3://s3websitehosting.com — index-document index.html — error-document 404.html

We can make sure these changes have been applied (this can be done via the console too):

It is available as a low-level CLI called S3-API client and is much more robust at making S3 API calls where you can; for example, specifying redirect rules such as HTTP to HTTPS traffic redirection.

We now have a published website searchable from the following URL: https://s3-us-west-1.amazonaws.com/s3websitehosting.com/index.html#!/.

Now that we have uploaded our files, it is a good idea to make a performance benchmark; in my case, I have 743 ms as the response time from my current location:

To establish routing rules on our website and be able to redirect requests from http://www.s3websitehosting.com to http://s3websitehosting.com, we will need two buckets. Only one of them will host our website, and the other will act as an alias to the origin:

In this case, the www prefixed bucket will point to https://www.domain.com/:


Proceed to create alias registries so we can associate our domain name to the static website in the S3 bucket; in Route 53, we must edit the public-hosted zone file so we can create an alias registry:

Route 53 DNS propagation is pretty fast, and, in just a matter of seconds, the database records must be propagated and the service will be able to solve the domain; let's check in a web browser by querying the name:

However, if I look up www.s3websitehosting.com we will have an error:

This can be resolved very easily by establishing another alias record, but this time by adding the www prefix (repeat the previous process, but now use www as the Name value):

If we filter the alias registries, they must have alike entries but with their domain name:

This will generate an automatic redirect for queries to www for the APEX of the hosted zone. Now, it is time to accelerate our website by using a CloudFront web distribution in front of it to our web page that will be copied to multiple Edge Locations and improve the user experience dramatically.

Choose CloudFront from the Services console option, then Create Distribution, and for delivery method, select Web. Use the following values:

Wait until the distribution status has changed to Deployed:

Copy the DNS-generated domain name and test it in your web browser; it must have a structure similar to XXXXXXXXXXXX.cloudfront.net.

Ready! Now that you have your website cached in multiple Edge Locations around the world when a DNS query arrives, the service will determine the best location candidate to serve this request. Think of CloudFront as a global network load balancer.

This image shows a benchmark between the origin (S3 bucket) versus the web distribution (CloudFront):

Now we need to associate a new alias record in the hosted zone, but this time to the CNAME of the CloudFront web distribution and not the S3 bucket name:

Proceed to validate the alias registries updated with the CNAME:

Performing a new test, we can check the developer tools in our web browser to see that the web app content is being served by the cache servers:

X-Cache: Hit from cloudfront
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.37.38