You set up everything and are ready to kick your website off globally. A few days after you publish your website, users from various locations complain about long loading times.
Are you concerned about losing your users and don't know what to do? Don't worry, this is when Amazon CloudFront changes the game!
Amazon CloudFront is a content delivery network (CDN) web service that you can use to improve the performance of your website by securely delivering static and dynamic web content such as .html, .css, .js, image files, applications, and APIs to customers globally with low latency and high transfer speeds.
Amazon CloudFront has a global network of edge locations and technology to deliver content to users across the world from the location that is closest to them or has the best performance. When a user requests content that you're serving with Amazon CloudFront, the request is routed to the edge location that provides the lowest latency, so that content is delivered with the best possible performance.
Today we will learn customizing at the edge with functions. Let's get started!
You can write your code to modify how your Amazon CloudFront distributions handle HTTP requests and responses. The code runs close to your users to minimize latency and you don't need to worry about managing servers or any other infrastructure. These codes are called edge functions and there are two ways to write and attach them, however, we will only focus on Amazon CloudFront functions.
Amazon CloudFront Functions are lightweight Javascript functions for high-scale, latency-sensitive customizations. It provides submillisecond startup times and handles millions of requests in a second. Amazon CloudFront Functions is a built-in feature of Amazon CloudFront, and it enables you to write, test, and deploy your code directly inside of Amazon CloudFront. To better understand capabilities of Amazon CloudFront Functions and distinguish it from Lambda@Edge, you can check it in the table below.
Amazon CloudFront Functions | Lambda@Edge | |
---|---|---|
Programming Languages | JavaScript (ECMAScript 5.1 compilant) | Node.js and Python |
Event Sources |
|
|
Scale | 10,000,000 requests per second or more | Up to 10,000 requests per second per region |
Function Duration | Submillisecond | Up to 5 seconds (viewer request and viewer reponse) |
Maximum Memory | 2 MB | 128 - 3,0008 MB |
Maximum size of the function code and included libraries | 10 KB | 1 MB (viewer request and viewer response) |
Network Access | No | Yes |
File System Access | No | Yes |
Access to the request body | No | Yes |
Access to geolocation and device data | Yes | No (viewer request) |
Can build and test entirely within Amazon CloudFront | Yes | No |
Function logging and metrics | Yes | Yes |
Pricing | Free tier available; charged per request | No free tier; charged per request and function duration |
Amazon CloudFront functions are ideal for lightweight short-running, typical use cases are:
HTTP header manipulation:
HTTP headers can be added, changed, or deleted in a request or response. For example, you can add Acces-Control-Allow-Origin response header if it’s not present.
URL rewrites and redirects:
You can redirect the visitor to a specific country URL when the request comes from within a particular country by using the CloudFront-Viewer-Country header
Access Authorization:
You can validate user-generated tokens, such as JWT and HMAC tokens. If the token is not valid the function generates an error response.
Cache key manipulation:
You can transform HTTP request attributes (headers, query strings, cookies) to create an optimal cache key, which can increase your cache hit ratio.
We talked enough about Amazon CloudFront Functions. We will look at how to redirect users' requests based on their countries, let's get started!
Assume that we have an e-commerce website and sell our products worldwide. Customers from different countries visit your website and see the same default page with prices listed in US dollars. It can cause confusion to customers who don't use US dollars and people generally want to see their currency's prices for better understanding.
Following is a step-by-step guide to redirect users to country-specific URLs using AWS Amazon CloudFront functions:
To create a distribution you must have an origin server. An origin is the location where you store the original version of your content and It can be. When your distribution gets a request, it goes to the origin to get the requested files. You can use any combination of Amazon S3 buckets and HTTP servers as your origin servers, it is up to you.
In my case, I will use an Amazon S3 bucket that has static website hosting enabled. To create the distribution you must create a distribution config file distribution.json. Here is an example of a config file.
{
"CallerReference": "cf-cli-distribution",
"Comment": "myownbucketforblogpost",
"Origins": {
"Quantity": 1,
"Items": [
{
"Id": "myownbucketforblogpost",
"DomainName": "http://myownbucketforblogpost.s3-website-eu-west-1.amazonaws.com",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
},
"DefaultCacheBehavior": {
"TargetOriginId": "myownbucketforblogpost",
"ViewerProtocolPolicy": "redirect-to-https",
"TrustedSigners": {
"Quantity": 0,
"Enabled": false
},
"ForwardedValues": {
"Cookies": {
"Forward": "all"
},
"Headers": {
"Quantity": 0
},
"QueryString": false,
"QueryStringCacheKeys": {
"Quantity": 0
}
},
"DefaultTTL": 86400,
"MinTTL": 3600
},
"Enabled": true
}
aws CloudFront create-distribution —-distribution-config file://distribution.json
Here’s an example function that redirects users to a country-specific URL based on their location:
aws CloudFront create-distribution —-distribution-config file://distribution.json
First, create a file named function.js using the above example. After that, use this command to create a new function.
aws CloudFront create-function \
--name http-header-manipulation \
--function-config Comment="Http Header Manipulation",Runtime="CloudFront-js-1.0" \
--function-code fileb://function.js
If everything goes well, you'll get an output describing the function that you just created.
This function checks the CloudFront-viewer-country header in the requests that come from users and determines their countries. If the user is from Turkey, they will be redirected to https://"host"/tr/index.html URL or if they're from the USA, they'll be redirected to https://"host"/us/index.html URL. If the user is from another country they'll see the default index page. You can add more countries as you want.
Firstly you should publish the newly created function to LIVE stage, if you don't publish it, you won't be able to associate the function with your distribution. To do this you can use the following command in the AWS CLI.
aws CloudFront publish-function \ --name ExampleFunction \ --if-match ETVXYZEXAMPLE
--name is the name of the function that you are publishing.
--if-match is the ETag value of the function that you're publishing.
You can use the aws CloudFront describe-function command to get the value.
After you successfully publish your function, you will be able to associate your function with an existing cache behavior. To associate the function, you first must get the distribution configuration for the distribution you want to associate with. You can use the following command.
aws CloudFront get-distribution-config \ --id DistributionID \ --output yaml > dist-config.yaml
--id is the distribution's ID that you want to associate with your function.
After you run this command, it doesn’t return an output instead it writes the output to a file named dist-config.yaml Open the file named dist-config.yaml you just created. make the following changes:
You can find the function ARN using this command aws CloudFront list-functions
After these changes, save the file.
You can use the following command to update the distribution.
aws CloudFront update-distribution \ --id DistributionID \ --cli-input-yaml file://dist-config.yaml
After you successfully run the command, you will see the output that describes the distribution that was just updated.
aws CloudFront test-function --if-match EXXXXXXXXXXXX --name your-function-name --event-object fileb://test-object.json
--if-match is the current version (ETag value) of the function you are testing.
--name The name of the function that you are testing.
--event-object is the event object to test the function with.
{
"version": "1.0",
"context": {
"eventType": "viewer-request"
},
"viewer": {
"ip": "0.0.0.0"
},
"request": {
"method": "GET",
"uri": "/index.html",
"querystring": {
"test": { "value": "true" },
"arg": { "value": "val1", "multivalue": [ { "value": "val1" }, { "value": "val2" } ] }
},
"headers": {
"host": { "value": "www.example.com" },
"accept": { "value": "text/html", "multivalue": [ { "value": "text/html" }, { "value": "application/xhtml+xml" } ] },
"CloudFront-viewer-country": { "value": "US" }
},
"cookies": {
"id": { "value": "CookeIdValue" },
"loggedIn": { "value": "false" }
}
}
}
{
"TestResult": {
"FunctionSummary": {
"Name": "redirect-based-on-country",
"Status": "DEPLOYED",
"FunctionConfig": {
"Comment": "",
"Runtime": "CloudFront-js-1.0"
},
"FunctionMetadata": {
"FunctionARN": "arn:aws:CloudFront::511186633739:function/redirect-based-on-country",
"Stage": "DEVELOPMENT",
"CreatedTime": "2023-06-25T15:23:36.004000+00:00",
"LastModifiedTime": "2023-06-25T15:23:51.059000+00:00"
}
},
"ComputeUtilization": "28",
"FunctionExecutionLogs": [],
"FunctionErrorMessage": "",
"FunctionOutput": "{\"response\":{\"headers\":{\"location\":{\"value\":\"https://www.example.com/us/index.html\"}},\"statusDescription\":\"Found\",\"cookies\":{},\"statusCode\":302}}"
}
}
As you see the URL is located in the FunctionOutput JSON object. We have learned about Amazon CloudFront Functions and don't forget to try it on your own!
Mert is an AWS certified developer and cloud enthusiast. He has a passion for computer science and leverages cutting-edge technologies to bring innovative solutions.
Subscribe to Our Newsletter
Our Service
Specialties
Copyright © 2018-2024 Sufle
We use cookies to offer you a better experience with personalized content.
Cookies are small files that are sent to and stored in your computer by the websites you visit. Next time you visit the site, your browser will read the cookie and relay the information back to the website or element that originally set the cookie.
Cookies allow us to recognize you automatically whenever you visit our site so that we can personalize your experience and provide you with better service.