Geo-Location Redirects With AWS CloudFront

In the age of global digital services, geo-location-based content is critical for improving user experience and engagement, especially if you implement any shops or subscription services that should be adopted by the local market. 

AWS CloudFront is one of the most widely used content delivery network (CDN) systems. It includes certain necessary features to implement geo-location-based redirection out of the box, but not in a single click.

Geo-Location Redirects With AWS CloudFront

This article explores how to set up geo-location-based redirection with AWS CloudFront and provides a comprehensive guide to using it effectively.

Understanding AWS CloudFront Geo-Location

AWS CloudFront is a CDN that distributes content across a global network of edge locations, reducing latency and improving load times for users. It caches content near to the user's location which improves performance. One of CloudFront's features is geo-location-based content delivery, which allows you to modify content depending on the user's geographical location via a variety of approaches, including geo-location headers.

To determine user device type, IP address, or geographic location in an AWS-based project with CloudFront, no commercial API (such as Google API) is required. All of this can be configured on CloudFront using particular HTTP headers for requests received from viewers and forwarded to our origin, allowing us to obtain the necessary user information.

At the CloudFront level, the following headers can be set to determine the viewer's location. They are determined based on the viewer's IP address:

CloudFront is undoubtedly capable of providing many more informative headers that can be utilized to determine the user's device or other parameters. For a complete list of location headers, check the official AWS documentation. 

Setting Up Geo-Location Based Redirects

First of all, we have to create an AWS infrastructure. Typically, users do it with any kind of automation tools like OpenTofu, Terraform, Pulumi, or SDK, but in the scope of this article, we’ll avoid it for simplicity.

Create a CloudFront Distribution

  1. Log in to the AWS Management Console: Open the AWS Management Console and click on the CloudFront service.
  2. Create a new distribution: Click "Create Distribution" and select the Web option. This allows you to set the distribution for both HTTP and HTTPS traffic.
  3. Configure origin settings: Set the origin parameters for your distribution. The origin could be an S3 bucket, an EC2 instance, or another source of content (in my case, an ECS Fargate instance with NLB).
  4. Set up default cache behavior: Configure the default cache behavior parameters, such as the viewer protocol policy and the allowed HTTP methods. Don’t forget to enable “All” Headers settings.
    Geo-Location Redirects With AWS CloudFront
  5. Configure distribution settings: Provide a distribution name and configure other settings such as logging and pricing class.
  6. Create distribution: Review your settings and click on “Create Distribution” to deploy it.

Create Geo-Location Based Redirects Function

AWS CloudFront provides two powerful options for running code at the edge: CloudFront Functions and Lambda@Edge. Each has its own strengths and is suited for different use cases.

Lambda@Edge

Lambda@Edge offers extensive functionality, making it ideal for more complex edge processing needs. Key benefits include:

CloudFront Functions

CloudFront Functions are designed to handle lightweight tasks efficiently with near-instant execution (sub-millisecond). They are ideal for scenarios that require minimal processing, such as:

The key distinction is that CloudFront Functions can only be triggered on Viewer Request and Viewer Response events, making them a great choice for low-latency tasks that don't require origin interaction or deep processing logic. 

Moreover, these functions are targeted for speed and cost, they scale easily to handle high-volume, real-time data. Additionally, they offer the following key benefits:

In summary, while Lambda@Edge offers more power and flexibility, it comes with slightly higher latency and cost compared to CloudFront Functions, which are designed for ultra-lightweight tasks like simple header modifications, redirects, or URL rewrites.

Create a CloudFront Redirect Function

In this post, we use the CloudFront function instead of Lambda@Edge's because it is much simpler in the case of redirects. To create it, do the following steps:

  1. Open CloudFront Functions Console: Navigate to CloudFront Functions in the AWS Management Console.
  2. Create a new function: Click Create Function and provide a name, such as GeoRedirectFunction.
  3. Write the function code: AWS CloudFront Functions use JavaScript (ECMAScript 5.1). Below is a sample code snippet that uses the CloudFront-Viewer-Countryheader to redirect users based on their country code:
    JavaScript
     
    // code snippet 1.1
    
    function handler(event) {
        var request = event.request;
        var headers = request.headers;
        var uri = request.uri;
    
        // Extract the 'CloudFront-Viewer-Country' header provided by CloudFront
        var countryHeader = headers['cloudfront-viewer-country'] ? headers['cloudfront-viewer-country'].value : null;
    
        // Check if the URI already starts with a two-character country code
        function hasCountryCode(uri) {
            // Split the URI into segments
            var segments = uri.split('/');
            // The first meaningful segment (after initial "/") should have two characters for a country code
            if (segments.length > 1 && segments[1].length === 2) {
                return true;
            }
            return false;
        }
    
        // If the URI already starts with a valid two-character country code, return the request unmodified
        if (hasCountryCode(uri)) {
            return request;
        }
    
        // If the CloudFront-Viewer-Country header is present
        if (countryHeader) {
            // Build the new URI by adding the country code as the first segment
            var newUri = '/' + countryHeader + uri;
    
            // Perform a 302 redirect to the new URI
            return {
                statusCode: 302,
                statusDescription: 'Found',
                headers: {
                    'location': { value: newUri }
                }
            };
        }
    
        // If no country code header is available, just forward the request unmodified
        return request;
    }
    

  4. Deploy the function: After writing your function code, click Deploy to push the code to the edge locations.

Geo-Location Redirects With AWS CloudFront

Highlights Related to the CloudFront Function Code

As demonstrated in code snippet 1.1, I used the simplest scenario for this post, the code does redirect from <url>/<path> to <url>/<country_code>/<path>. It is not a recommendation because the mechanism for redirecting or sending the country code is dependent on your own implementation. Changing code snippet 1.1 allows you to provide <country_code> via URI parameters like <url>/<path>?location=<country_code> or do additional changes.

Another common use case is to return the CloudFront header in pure or modified format to the browser or client, rather than as a pure redirect. It can be constructed using the "Viewer Response".

Geo-Location Redirects With AWS CloudFront

The basic function will look like this:

JavaScript
 
// code snippet 1.2

function handler(event) {
   var request = event.request;
   var response = event.response;
   if (request.headers['cloudfront-viewer-country']) {
      response.headers['x-country'] = request.headers['cloudfront-viewer-country'];
   }
   return response;
}


You may certainly change it, but in its most basic form, code snippet 1.2 simply returns the cloudfront-viewer-country heading to the client as the x-country header.

Best Practices for CloudFront Functions

Associate the CloudFront Function With the Distribution

  1. Select your distribution: Navigate to the CloudFront distribution you previously generated.
  2. Edit cache behavior: In the distribution settings, select the default cache behavior and click on "Edit".
  3. Add CloudFront function to viewer request event: Under the Function Associations section, add your newly created CloudFront function to the Viewer Request event. This ensures that the function is executed whenever a user requests content from CloudFront.
  4. Save changes: Make the necessary changes and deploy the new cache behavior.

Geo-Location Redirects With AWS CloudFront

Testing and Monitoring

1. Test the Redirects

To ensure that your geolocation-based redirects work properly, use a VPN or online resources to simulate queries from other regions. Users should be sent to the proper domain or page based on their current location.

2. Monitor the Distribution

Use AWS CloudFront's built-in monitoring tools to keep track of function performance, error rates, and request logs. You can also establish CloudWatch alarms to check for unexpected activity or high latencies.

Geo-Location Redirects With AWS CloudFront

Conclusion

Using CloudFront Functions for geo-location-based redirection or location determination is a fast, low-latency, and cost-effective way to deliver localized content. In a few steps, you can set up a CloudFront distribution, deploy a CloudFront function or Lambda@Edge, and begin routing users to region-specific content based on their location.

With these techniques, you can provide a more personalized and responsive digital experience to consumers around the world, which is critical for modern web apps.

Please let me know if you'd want to see the article with Lambda@Edge examples instead of CloudFront Functions.

References

 

 

 

 

Top