Customising Content Delivery with AWS CloudFront: Routing with Origin Request Policies and CloudFront Functions
Grit Coding
Posted on April 18, 2024
While studying for the AWS SysOps Administrator certification exam, I discovered an interesting feature in AWS CloudFront that allows serving different objects based on cookies or HTTP request headers specified through the origin request policy. This concept intrigued me, but it didn’t truly resonate until I began experimenting with it myself. In today’s blog post, I will share a step-by-step guide on how to set this up by forwarding the value of request headers. To enhance clarity, I'll conclude with a visual demonstration directly from the AWS console.
This post is intended for readers with existing knowledge of AWS.
Prerequisites
- Knowledge of S3 Buckets & Policies
- Understanding of how to set up a CloudFront Distribution with S3
By creating a CloudFront distribution as shown above, you can access https://d3h4a6v5efbkjq.cloud.net/index.html
directly, leads you to index.html
without any prefix.
We will forward the Accept-Language header, and the CloudFront function will then redirect based on this value. For example, if the Accept-Language
value is English, the user will be redirected to /en/index.html
.
Create S3 Bucket and Upload Files
Navigate to S3 from the AWS console and create a new bucket.
Set up your project files as follows:
Root directory: index.html
Korean version: /kr/index.html
English version: /en/index.html
<!-- Root index.html -->
<!DOCTYPE html>
<html>
<head>
<title>gritcoding</title>
<meta charset="UTF-8">
</head>
<body>
<h1>gritcoding</h1>
</body>
</html>
<!-- /kr/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>한국어</title>
<meta charset="UTF-8">
</head>
<body>
<h1>안녕</h1>
</body>
</html>
<!-- /en/index.html -->
<!DOCTYPE html>
<html>
<head>
<title>English</title>
<meta charset="UTF-8">
</head>
<body>
<h1>hi</h1>
</body>
</html>
Once uploaded, you will be able see index.html
, /en/index.html
, /kr/index.html
objects in the bucket.
Create CloudFront Function and Deploy
Navigate to CloudFront and crate a new function.
Update the function using the code below.
function handler(event) {
const request = event.request;
const headers = request.headers;
// Check for English language in Accept-Language header
const langHeader = headers['accept-language'];
if (langHeader && langHeader.value.indexOf('en') !== -1) {
// Route to English version of the content
request.uri = '/en' + request.uri;
} else {
// Route to Korean version of the content
request.uri = '/kr' + request.uri;
}
return request;
}
Now, you can test this function in the test tab. Use the following steps to simulate a request.
- Scroll down to the
Add header
button and click it. - Enter
accept-language
as the header key. - Add
en-GB
as the header value. - Click the
Test function
button located above. If the test is successful, you should see that it returns/en/index.html
as shown in the screenshot below.
Create CloudFront Origin Request Policy
Navigate to CloudFront/Policies/Origin request as shown in the screenshot below.
Name the policy, select include the following headers
in the Headers dropdown, and choose the Accept-Language
header.
Once the origin request policy is created, proceed to create a distribution.
Create CloudFront Distribution
Navigate to CloudFront and click the create distribution
button. Select the bucket you created as the Origin domain.
Then, scroll down to the Cache key and origin requests
section, select the origin request policy you created, and set the viewer request function type
to CloudFront functions to select the function we created.
Update S3 Bucket Policy
Navigate back to your S3 bucket and update the bucket policy.
Use the following JSON code to update it, ensuring you replace S3 bucket name
, Your AWS Account Number
, and CloudFront distribution ID
with the actual values specific to your setup.
{
"Version": "2012-10-17",
"Statement": {
"Sid": "AllowCloudFrontServicePrincipalReadWrite",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<S3 bucket name>/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::<Your AWS Account Number>:distribution/<CloudFront distribution ID>"
}
}
}
}
After updating the policy, copy the CloudFront distribution domain name and paste it into your web browser followed by /index.html
. Depending on the Accept-Language header in your request, this setup will either direct you to /en/index.html
if English is detected, or /kr/index.html
for all other languages.
In this setup, direct access to the index.html
with the gritcoding
message is not available, as the CloudFront distribution has been configured to redirect based on language settings.
Learn more:
Watch the step-by-step video guide on setting up and testing this configuration on our YouTube channel linked below.
Thanks for reading. :)
Posted on April 18, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.