- Published on
Creating a Maintenance Mode with Cloudfront
The Challenge
While working at Flightcontrol, I developed a feature that allows users to activate a Maintenance Mode for their deployed services. This feature redirects all traffic to a static maintenance page instead of the user's application, providing a clean way to perform updates without disrupting the end-user experience.
This project was particularly interesting as it deepened my understanding of AWS architecture and request flow patterns. I needed to trace the entire journey of a request from client initiation to content delivery to implement an effective solution.
Understanding CloudFront
CloudFront serves as the CDN for our users' services, making it the perfect place to intercept and redirect traffic during maintenance periods.
Key CloudFront Components
When configuring CloudFront, you're setting up a Distribution that requires two primary elements:
- Origins: The source locations for your content (your application servers, S3 buckets, etc.)
- Behaviors: Rules defining how different types of requests should be handled
A behavior connects a request path pattern to an origin and applies specific caching policies. It's also where we can attach functions to modify requests or responses at different stages.
Here's what the Behaviors panel looks like in the AWS Console:

Request/Response Lifecycle Hooks
CloudFront provides four event hooks where we can intercept and modify the request/response cycle using Lambda@Edge or CloudFront Functions:
- Viewer Request: When CloudFront first receives a request from a client
- Origin Request: Before CloudFront forwards the request to your origin
- Origin Response: When CloudFront receives a response from your origin
- Viewer Response: Before CloudFront returns the response to the client
The Solution
For our maintenance mode feature, the Viewer Request event is ideal. By intercepting at this stage, we can completely bypass the origin server and return a custom maintenance page regardless of what the user requested.
Implementation Steps
- Create a Lambda@Edge Function
First, we build a simple Lambda function to return our maintenance page:
exports.handler = (_event, _context, callback) => {
const response = {
status: '503',
statusDescription: 'Service Unavailable',
headers: {
'content-type': [{ key: 'Content-Type', value: 'text/html' }],
'cache-control': [{ key: 'Cache-Control', value: 'max-age=30' }]
},
body: `
<!DOCTYPE html>
<html>
<head>
<title>Site Maintenance</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
h1 { color: #444; }
p { color: #666; }
</style>
</head>
<body>
<h1>We'll be back soon!</h1>
<p>We're currently performing scheduled maintenance. Please check back shortly.</p>
</body>
</html>
`
};
callback(null, response);
};
Note: Lambda@Edge functions must be created in the US East (N. Virginia) region (
us-east-1
).
- Configure CloudFront Behavior
To activate maintenance mode, we create a new behavior with:
- A path pattern of
*
to catch all requests - Highest precedence (position 0) to override all other behaviors
- The Lambda@Edge function attached to the Viewer Request event
- Toggle Maintenance Mode
- Enable: Deploy the behavior with the Lambda@Edge function attached
- Disable: Simply remove the behavior, letting requests fall through to the default behavior
Production Considerations
When implementing this in production, consider:
- Deployment Time: CloudFront distribution updates can take 5-10 minutes to propagate
- Targeted Maintenance: Create behaviors for specific paths if you only need to maintain certain parts of your application
- Custom Maintenance Pages: Store richer maintenance pages in S3 and have Lambda@Edge redirect to them
- Status Codes: The 503 status code indicates temporary unavailability and helps with SEO during maintenance periods
By leveraging CloudFront's behavior system and Lambda@Edge, we created a flexible maintenance mode that can be toggled without requiring changes to the origin application code.