Use CloudFront Distribution Service and Route53 for My Website Served from S3
I realize there are many service provider offers good deal on full web hosting service with a pretty designer’s website template, cname purchase, SSL certificate, and a decent price lower than 10 bucks per month. However, here I have much more to think about before making just a website.
In addition to a simple static website, I might want to keep a tracking records on the incoming traffic for analytical purpose that may benefit future business direction decisions for the company. This is certainly achievable by embedding link tracking code in my javascript that can be further aggregated in a visualization tool on Flurry or even something like Firebase. This way I can still benefit from using Wordpress. But it also means more coding in order to plant link tracking code. Furthermore, in order to compile a presentable visualization on Flurry or Firebase, a careful plan needs to be drawn out prior to the deployment of the website.
The purchase of a cname can be a big thing for a company. In addition to company website hosting, a cloud service can be attached to the purchased cname. If I have an http://www.ephodtech.com that leads audience to the content of the company website, I might want to get a https://product.ephodtech.com that directs audience to a web service provided by ephodtech.com. I am pretty sure service like Wordpress would not be able to support advance web application and multiple cname relate re-routing behavior. One might argue, cname management, ssl certification, and re-routing can be hosted on different service providers but I find it more manageable if all internet related works lie with the same cloud service provider.
CloudFront is a content delivery service by Amazon which hosts many edge locations, i.e. facilities around the world to serve content. CloudFront is easy to set up and fast propagate. There are three price classes representing different propagation methods. If you choose the option to propagate to all edge locations, AWS propagates content to all edge location around the world periodically. The trick here is that propagation does not seem to happen real-time with each updates on the content. From my experience, content propagation on all edge locations usually happens within hours. AWS has servers in Asia, Europe, South America, North America, Africa, and Australia. The other two options do not propagate content to South America and Australia regions. However, content propagation does not mean increase of the price you pay. AWS does not charge by the regions the data is propagating to. CloudFront is charged by the amount of data transfer out into the internet.
When a CloudFront Distribution is created, the url CloudFront Distribution service generated is not a memorable one. Usually for commercial site usage, we want a meaningful url such as www.facebook.com or www.google.com. This is not within the scope of CloudFront service. In order to adapt a meaningful cname, we need some help from Route53.
Here is a tutorial to create a static website with content stored on S3, distributed thru CloudFront, and redirected through Route53. A simple static website with meaningful cname looks something like this,
So let’s start.
We would go thru the following steps to create our static website.
- Prepare a “Hello, world.” website on S3
- Create a CloudFront distribution
- Create Route53 Zone
Prepare a “Hello, world.” Website on S3.
Because this is a static site, i.e. the site is aiming to present content without complicated real-time updates. A “Hello World” site is suffice. Simply create an empty text file with the name of index.html and type in
<html>Hello World.</html>
Create a bucket on S3 named it static.website and upload index.html to the bucket.
Create CloudFront Distribution
Navigate to CloudFront service by type in “CloudFront” on top search textbox. Click on the button on the right hand side that says “Create a CloudFront distribution” that will redirect to CloudFront creation page. There are four sections on the page to go through,
- Origin
Origin section defines where to find the content for the website. Since it is a static website with content stored in S3, click on textbox for original domain, S3 url on the dropdown list. There is no need to specify origin path in this case. If for any reason you have all website files stored in a folder in the bucket, this is the place to tell CloudFront where to start looking for website content. The tricky part of this section is the OAI setting. S3 by itself can be a web service. Once public access is enabled on S3 bucket, the bucket is automatically a web service. This is not what we intend to do for this tutorial. Using S3 as a web service does not grant a cname and a cache layer that prevents DDoS attack. In addition, S3 does not have world-wide distribution which may result in long response time if the requester is in different region from S3 bucket region. Hence CloudFront is recommended for website hosting. Of course if this is the scenario where a temporary website is needed with few predictable accesses, there is no need to put CloudFront in the front of S3 bucket. Because CloudFront will be used, we would set use OAI with “update bucket policy” option checked so we do not need to worry about S3 not being given enough permission for CloudFront to access. If for some reason “update bucket policy” is not available, two S3 policies are needed for this setting to work.
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity <Cloudfront Distribution ID>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<S3 bucket name>/*"
},
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<S3 bucket name>/*"
}
]
}
2. Default cache behavior
CloudFront provides cache layer and distribution around the world. If nothing is set, CloudFront default in “*” for path pattern. This forces all traffic for the specified domain to be handled by this CloudFront distribution. Keep “Compress objects automatically” to “Yes” that allows content to be compressed. For a simple website, keep all values unchanged in “Viewer” section. However, if CloudFront distribution is created for an API service, “GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE” methods should be allowed instead of just “GET, HEAD”. If website is restricted to specific users, check “Yes” option for “Restrict viewer access”. Leave Cache key and origin requests untouched for the same reason above. Finally there is an option that allows real-time logs. Real-time logs are a bit different from standard logs. Obviously it is aiming fast delivery of the logs. To enable real-time logging, a log configuration needs to be set with corresponding kinesis data stream created ready to receive the logs. After Kinesis data stream receives data from CloudFront real-time logging, there needs to be some other services required to digest log data to make it useful. This is beyond the scope of this article so we could keep real-time log disable for now.
3. Function association
If any additional manipulation is required, we could facilitate this requirement with a lambda handler function. Lambda is light weight function but it has 15-minute execution time with a limitation on concurrent executions and computer memory resource usage. We do not need any additional handling at this moment so leave function association as it is for now.
4. Settings
Settings section is where aforementioned edge location propagation settings. The best and most recommended solution would be “Use all edge location”. I could not fathom any reason why not to at this moment since propagation does not incur any additional charge. In this section we would also need to specify an “Alternate domain names” and a “Custom SSL certificate”. Alternate domain name is the cname purchased either on AWS or other vendors. As aforementioned, if your registered domain is managed on AWS, SSL certificate could be a lot easier. It took less than a day to receive a SSL certificate. To issue a SSL certificate, navigate to AWS Certificate Manager > Certificates. Type in your domain name on the certificate application page. Submit the request and wait for a day to check if the certificate is issued. Once the qualified domain and SSL are all set, we would need to let CloudFront know the root page for the website. Usually it is something like index.html which is the case here. Turn on “Standard logging” by checking the textbox with a new S3 bucket name. Log bucket needs to be created prior to CloudFront distribution creation. Set off for “Cookie logging” since there is no special needs for cookie information in this scenario. Now click on “Create Distribution” button at the bottom and CloudFront distribution is all set.
Because CloudFront propagates to all edge locations, updating website content on S3 does not mean your website is updated at a predictable time. If there is time is an issue here, try to “invalidate” the content by switching to “Invalidation” tab on CloudFront Distribution page. This usually propagates result within an hour or so. Furthermore, versioning on css, javascript, and html files is always a good practice in preventing showing of old content.
Create Route53 Zone
Navigate to Route53 > Hosted zones and click on “Create hosted zone” to create a zone for the registered domain. Creating hosted zone is easy, the only information AWS needs is a domain name. However a zone does not do anything for you. There are distinct types of record that helps to redirect traffic to the correct recipient. After a zone is created, create a Type “A” record which allows Route53 to redirect requests according to “Record name” to “Value”. Leaving Record name empty means this record redirects all traffic for <domain> to where “Value” specifies. Here we would put CloudFront distribution domain name which can be found on CloudFront distribution page on the “Details” section on “General” tab in “Value” textbox. Remember to turn “Alias” switch on so that you can easily select CloudFront distribution from a selection list. There are cases where “Alias” switch is on and CloudFront distribution domain name is no where to be found on the dropdown list. No worries, copy and paste always work in this case. Click on copy button on CloudFront distribution page for its domain name and paste over should do the work. Leave “Routing policy” to “Simple routing”. We are done setting up Route53.
Pricing
For data transfer within AWS Cloud, the pricing is either free or with big discount. In our case where a user makes a request to CloudFront. CloudFront then forwards request to S3. S3 sends content to CloudFront. CloudFront then sends the content back to the user. The only data transfer charged is the part where CloudFront send the content over to the original requester. Price for purchasing a cname varies according to the popularity of the domain name. Apart from domain pricing, CloudFront gives a pretty good deal as well as S3. This setting generates close to zero cost for the few months from the beginning of our website with extensibility later on when other web service that is to come in the future.