Sometimes you need to be sure you show relevant content to visitors in different countries. Let's see how it can be done using Amazon Web Services.
Prerequisites
In this tutorial, we will implement location-based redirects for an app distributed via Amazon CloudFront. I will store specific files on Amazon S3 but it could be any storage or web server. Finally, we will use AWS Lambda service to check country codes and return an appropriate response.
I added three files to the S3 bucket. Each of them is responsible for a particular locale:
Each file from the bucket has its own CloudFront distribution with the WEB distribution method. It might not make sense while they point to the same S3 bucket but in a real-world app each distribution would point to a different domain.
Setting Up Lambda Function
Open up Lambda service, select the region you need and hit Create function. Now we need to configure a function and name it:
The only thing that worth to be mentioned is the function's execution role. If this is your first Lambda function for CloudFront, you need to create a new role. Select Basic Lambda@Edge permissions (for CloudFront trigger) from the Policy templates dropdown and insert a role name for future usages. I named it cloudfront_basic but it might be any name. The role is required to let Lambda know what service is going to use the function. Go ahead and save your function.
It's time to get your hands dirty! Put the following code into the editor:
exports.handler = async (event) => {
const getCustomResponseWithUrl = url => ({
status: '302',
statusDescription: '302 Found',
headers: {
location: [{
key: 'Location',
value: url,
}],
},
});
const request = event.Records[0].cf.request;
const headers = request.headers;
let response = request;
if (headers['cloudfront-viewer-country']) {
const countryCode = headers['cloudfront-viewer-country'][0].value;
switch (countryCode) {
case 'GB': {
// generate a redirect response to the United Kingdom distribution
response = getCustomResponseWithUrl('https://d1zywwhn3ytw4t.cloudfront.net');
break;
}
case 'US': {
// generate a redirect response to the United States distribution
response = getCustomResponseWithUrl('https://d3gf6cz8gf6db6.cloudfront.net');
break;
}
default: {
// don't change the incoming request
break;
}
}
}
return response;
};
All we need to do is to check if the country from the cloudfront-viewer-country
header fits any of our conditions. If so, we need to generate a redirect response with a URL of the CloudFront distribution we want to redirect to. If not, just need to return the incoming request from the event
object that is passed as the first argument to the handler function. Dead simple!
To make the function visible to CloudFront distributions we need to save it and publish a new version from the actions dropdown. Copy the function's ARN, it will be available in the top right corner. We'll need it a moment later.
Adding Lambda Function to CloudFront distributions
Now it's time to make CloudFront distributions use the function. Go to CloudFront and open the distribution we created for requests that don't meet any condition(not from UK or US in our case). Open the behaviors tab and click Create behavior. Put *
into the path to make it work for each path for simplicity. For the real-world app, you can add a more complex path pattern.
Next, select Whitelist for the Cache Based on Selected Request Headers
setting. In the Whitelist Headers input, add CloudFront-Viewer-Country to the whitelisted headers list. It will make CloudFront add the cloudfront-viewer-country
header that we use in the Lambda function.
Finally, put the ARN of the Lambda function we copied and associate it with the Origin Request event:
We're all set! Save the behavior we created. Wait for the distribution to deploy and that's it:
Further reading
CloudFront x Lamda examples
CloudFront x Lamda requirements and restrictions
Lamda function logging
Create aliases for different lambda environments or setups
NOTE: Lambda aliases and environment variables are not supported by CloudFront
Top comments (0)