The Feature
While working at Flightcontrol, I worked on a feature that lets users activate a Maintenance Mode on the services they deploy with us. In this mode, traffic is redirected to a static page instead of the user's app, providing a more straightforward way to perform maintenance or updates without disrupting the user experience.
Working on this project was interesting as I was still becoming familiar with the ins and outs of the architecture of the AWS services we help deploy. In particular, it was useful to understand the journey of a request, from the client asking for it to the delivery of the content.
Since we were using Cloudfront as the CDN for the services that serve content to their end-users, we decided to use its capabilities for implementing the feature.
The implementation
CloudFront Overview
Before getting to the configuration for this specific feature, it's useful to briefly mention a few concepts. When you configure CloudFront, you're setting up what AWS calls a Distribution. In the setup, you will need to indicate, among other things:
- The Origin: where to get the content from and
- Behavior: the rules for how the content should be served. As an example, a behavior would link a request path to an Origin and a Cache Policy (Cache Policy is a set of rules for how the requests and responses should be cached. It is configured separately from the Cloudfront distrubtion and can be reused across different ones.).
In the AWS Console, this is what a Behavior section looks like for an existing Cloudfront Distribution:
CloudFront's Cache Behaviors
There are many combinations of how you can configure a Behavior for a CloudFront Distribution - not only you can configure the paths to go different origins using different cache policies, but you can also associate a function (Lambda@Edge OR Cloudfront function) to different stages of the request/response.
In total, Cloudfront provides support for 4 types of events:
- When CloudFront receives a request from a viewer, called "Viewer request"
- Before CloudFront forwards a request to the origin, called "Origin request"
- When CloudFront receives a response from the origin, called "Origin response"
- Before CloudFront returns the response to the viewer, called "Viewer response"
The Implementation
Considering the feature, the very first event, which is a request from the client or "Viewer Request", is what we need: regardless of the request received, we want to send a response from a Lambda containing the "Maintenance Mode" response.
For that, we need to create a simple lambda that has a handler returning the correct response, something like:
exports.handler = (_event, _context, callback) => {
const response = {
status: '503',
statusDescription: 'Service Unavailable',
body: 'Maintenance Mode: Please try again later',
}
callback(null, response)
}
Once we have the Lambda with all the correct permission, we can enabled a "Maintenance Mode" by attaching a new Behavior with the Lambda as the Viewer Request's Lambda@Edge. (Interesting fact: Lambda@Edge can only be in us-east-1)
To disable the mode, we simply remove the Behavior and the Cloudfront distribution will go back to whatever is configured by default!