Location Based Content with AWS Cloudfront Part II
In the first article, we finished our S3 bucket for storing content and the Lamda function for URL rewriting.
Then comes on our important service to serve our Content.
First create our Cloudfront Service with default root object as index.html and server it whole world (price_class as “PriceClass_All”). There are a few others price_class if you want to reduce cost and your users are not distributed to whole world. You can check them here with their price.
Then we need to create and origin access identity.
I named it as s3_bucket_one. We need to update our S3 bucket policy to allow this identity access resources in S3.
Lets continue with our origins.
We have just one bucket but we will use it with two origin (primary and failover).
While we define our origins, we pass some custom headers that will help identify which request will be send to which origin.
So far, we have create two origin definitions, but we haven’t told to cloudfront how to failover between these two origins.
If you want to use Cloudfront failover feature you need to define a origin group.
If Cloudfront gets any response with 400, 403, 404 and 503 response status codes. Then it will send same request to failover origin.
Then, we need to define where to forward the user requests in CloudFront. This is define in the Behavior section.
We will use only default_cache_behavior in this example but you can define your custom behaviors. In this behavior we tell them to forward our requests to target_origin_group which is our origin group we have defined it a few minutes ago.
Another feature for cloudfront caching, you need to define your cache_key, by default this it is requested path. But you can extend it with Request Headers, Query Strings and Cookies. In our example we will use only CloudFront-Viewer-Country header. Since July 2020, AWS has added geolocation headers to cloudfront. You can use a few extra geolocation headers. Please check for the full list of geolocation headers.
We implement our lambda function but connect it with cloudfront.
There are 4 types of Lambda@Edge functions you can assign to cloudfront to use on edge locations.
- viewer-request: The function executes when CloudFront receives a request from a viewer and before it checks to see whether the requested object is in the edge cache.
- origin-request: The function executes only when CloudFront sends a request to your origin. When the requested object is in the edge cache, the function doesn’t execute.
- origin-response: The function executes after CloudFront receives a response from the origin and before it caches the object in the response. When the requested object is in the edge cache, the function doesn’t execute.
- viewer-response: The function executes before CloudFront returns the requested object to the viewer. The function executes regardless of whether the object was already in the edge cache. [2]
In our case, we just need to use only origin-request and we exclude body from function. We just need to request URI and headers. If you need request body in your case you need to enable include_body property as true.
Get Mehmet Güngören’s stories in your inbox
Join Medium for free to get updates from this writer.
Last attribute is viewer certificate, in this case we will go with Cloudfront default certificate and domain. If you need to use your custom domain you need to bring your certificate and store it on ACM or purchase one from AWS ACM.
After we’ve covered everything, let’s showcase our cloudfront module as a whole.
Terraform will create 19 different resource in your AWS account.
Now that all the steps are completed, let’s look at the terraform output.
We have a specific banner for Turkey. I am from Turkey. When I visit distribution_url
I have tested url from some different locations. I used a service testlocally. If you want to check your website from different locations. You can test it with testlocally.
I select 9 different location (Ottawa-Canada, Osaka-Japan, Almathy-Kazakhstan, Nairobi-Kenya, Seoul-South Korea, Valencia-Spain, Istanbul-Turkey, London-United Kingdom, San Jose-USA)
We are expecting to get custom results for Ottawa, Osaka, Valencia, Istanbul and San Jose. Other locations should get default banner.
Source code is uploaded on my github
Cleanup
After you tested and want to avoid further costs. Run
terrafrom destroy -auto-approveConclusion
In this article we used only CloudFront-Viewer-Country with Cloudfront failover feature. If you want your website to be more personalized you can you use CloudFront-Viewer-Country-Region(only work for US), CloudFront-Viewer-City, CloudFront-Viewer-Postal-Code, CloudFront-Viewer-Time-Zone, CloudFront-Viewer-Latitude and CloudFront-Viewer-Longitude headers in your architecture.
I hope you found this article interesting and useful. ✋
References:
1 — https://aws.amazon.com/cloudfront/faqs/
2- https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_LambdaFunctionAssociation.html

