Maintenance Pages Made Easy with AWS

Don Spidell
3 min readFeb 5, 2023

--

While well-architected applications allow for many kinds of infrastructure maintenance without requiring application downtime, there are certain activities that may require an outage. Those activities could be upgrading a database, making a major infrastructure change, or coping with an outage of a third-party system. If you are running your web application on AWS and leveraging CloudFront, putting up and taking down a maintenance page is an easy task.

Photo by Matthew Hamilton on Unsplash

Creating the maintenance page

Since the maintenance page content will be served up on every request from every visitor, it is important that it is lightweight and static. S3 is the perfect spot to host a maintenance page, so start by creating a bucket which matches the domain name you’re using for your web app. Next, create a single HTML file that contains your maintenance page content, even images. CSS and JavaScript can be your friend here. Enable static website hosting on the bucket, specifying index.html as the index document.

Configure CloudFront

Once the maintenance page is created in S3, it’s time to configure CloudFront. Presumably you have an existing origin, such as an EKS cluster or an Elastic Beanstalk, for your web app. Add a second origin for the maintenance page. Specify the S3 Bucket website endpoint as the origin. Next, configure a behavior with the precedence set to 0. Set the path pattern to a path that is not in use by your application, such as /zzzzzzzz.

Using your maintenance page

By default, your maintenance page won’t be visible to users due to the CloudFront behavior that you set. However, when it is time to turn on your maintenance page, simply change the CloudFront path pattern to * so that every request hits it. Once your CloudFront distribution deploys, all visitors will see your maintenance page for each and every request to your domain, no matter that the path is. to disable your maintenance page, just change the path pattern back to /zzzzzzzz.

Enhancement for handling multiple subdomains

Perhaps your web app uses multiple subdomains, such as in a multi-tenant situation where there could be a unique subdomain per tenant. How would that be handled? One way is to add a Lambda@Edge function into the mix. First create a Lambda function in the us-east-1 region. You can use this Node.js code:

'use strict';

exports.handler = (event, context, callback) => {
const remove_suffix = '.your-domain.com';
const request = event.Records[0].cf.request;
const headers = request.headers;
const host_header = headers.host[0].value;
const origin_hostname = request.origin.custom.customHeaders["x-subdomain"][0].value + 'your-domain.com.s3-website-us-east-1.amazonaws.com';

if(host_header.endsWith(remove_suffix))
{
request.uri = '/index.html';
}

headers.host[0].value = origin_hostname;

return callback(null,request);
};

Just sub in your app’s domain and your maintenance page bucket’s website endpoint. Locate your maintenance page CloudFront behavior and configure a Function Association for Origin Request. Specify “Lambda@Edge” as the function type and the ARN of your Lambda for Function ARN. This will make sure that all requests, regardless of subdomain, will return the maintenance page content.

Add Automation

It works fine to turn the maintenance page on and off in the AWS Console, but you can automate the process if you are using Infrastructure as Code. One way to do this is if you’re using Terraform. You can configure a Boolean variable such as “maintenance_mode” to “true” or “false”. Using conditional logic in your Terraform, you can change the path pattern to * or /zzzzzzzz depending on the value of the variable.

Enjoy!

--

--

Don Spidell

Cloud Architect Lead at Summit Technology Group. Long-time AWS user highlighting interesting use cases and solutions built on AWS.