Element 84 Logo

Using Amazon CloudFront Functions to Facilitate Smooth Project Transitions with Conditional Redirects

09.27.2023

When a platform we’ve worked with for years goes through a brand transformation involving our work, we are proud and excited to aid in our clients’ transition. Our team went through this process with a long-time customer as they evolved their platform. In this situation, the original version of the platform contained a popular feature that allowed partners to embed a customized map of their data on their own website. In this blog, we detail our experience making this project transition possible for our client by implementing conditional redirects via Amazon CloudFront functions.

Developing a plan

As our development team worked to transition the client smoothly from one iteration of the platform to the next, this feature presented a distinct challenge. The front-end application uses the same components for both the full application and the embedded version, and the new platform included a significant redesign of the interface with a new set of components. We needed the ability to allow dozens of partners with custom maps embedded into their public websites to opt-in to these changes to the content of their high-profile sites without the development and maintenance burden of managing a legacy UI within the revised codebase.

Even in its earliest phases, our migration plan included a “soft launch” period. For a few weeks leading up to the launch, the website would enter a read-only mode, allowing us to migrate and update the database for the new platform and load new data so it was available on launch day. This strategy meant that we would be running both old and new versions of the platform simultaneously. On launch day, we had planned to redirect all requests coming from the old site over to the new one, but we were interested in determining the feasibility of implementing a conditional redirect. Could we set up a redirect such that requests for embedded maps would be served by the old platform, but all other requests would be served by the new platform?

Implementing a redirect 

A flow chart that reads: "start" into "does the request URL have an embed=1 query string parameter?" If you select yes, it reads "Allow the request to proceed to the old platform" which leads to finish. If you selected "No", It leads to "Does the URL path match a request for an embed view asset?". From here, if you select "yes" you're pointed to "Was the request made from a page loaded from the old platform?" if you select "No", you're pointed to "Return a 302 Found with the new platform URL". If you said yes to the space reading "Was the request made from a page loaded from the old platform?" then you get pointed to "Allow the request to proceed to the old platform" which finishes. If you said "No" to that space you end up back at "Return a 302 Found with the new platform URL" which also brings you to "finish".

Code in both the backend and frontend looks for an embed query string parameter and, when it is present, alters the API data returned and UI controls rendered respectively. We determined that the same query string parameter could be used to build a conditional redirect. 

Since our Django-based backend was already changing behavior in embed mode, the first conditional redirect design we considered was one based on custom middleware, a pattern we have used previously for other features of the platform. Exploring this idea quickly revealed some notable downsides. All request traffic would pass through the Django backend of both deployed applications, and enabling and revising the behavior of the redirection would require a deployment of the legacy application. Because we only needed to examine the request itself to make the decision to redirect we were free to look for alternate methods of generating a response before the request reached our Django application.

Amazon CloudFront as a redirect solution

Because the application was already deployed behind an Amazon CloudFront distribution, the development team looked at additional features offered by that service and found CloudFront Functions to be a perfect fit for our needs. This allowed us to write custom Javascript to inspect the details of a request and conditionally return a redirect. 

The AWS Management Console provides an editor with a built-in test UI for developing and exercising the code. The resulting code can be tested in its deployed state before being attached to the distribution as a behavior. This allows us to build confidence in the configuration before it is active and to make the activation simple, fast, and easily reversible if a problem is discovered.

A screenshot depicting the built-in function testing tool in AWS console.
AWS Management Console features a built-in function testing tool

The final version of the redirect function ended up being a bit more complex than just looking for the presence of a query string argument. In addition, we also needed to allow the embedded page to make static asset and API requests that did not include the query string parameter. We were able to handle this by creating a whitelist of resources requested by the embedded page and incorporating the value of the referer header into our redirection decision.

Takeaways

In addition to learning about a new-to-us AWS feature, the process the team went through to arrive at the final implementation reinforced some good platform design and development practices. Pausing early and often to reflect on whether a potential solution is the best option is crucial. 

The cost of a workable, but less than ideal, implementation increases dramatically the further it moves down the path from whiteboard to production deployment. It is also important to have dedicated staging environments to test platform changes so that complexities can be handled and bugs squashed before a high-profile production release and to prefer architectural changes that can be transitioned quickly and reversed just as quickly if a problem is discovered.

Have questions about how our team might be able to implement a solution like this for your brand transition? Get in touch

Justin Walgran

Justin Walgran

Senior Software Engineer