During deployments on OpsWorks, there is a brief but noticeable period when the application is unavailable. During this time your users will often get a 503 service unavailable response.
In this article we show you how to display a maintenance page instead that is automatically switched on and off as part of your deployment process.
The process defined for this approach to displaying a maintenance page was developed for a Chef 11.10 OpsWork stack using the Java Layer provided by AWS. However the concepts should be applicable to any OpsWorks deployment and fairly easy to integrate with other layers or your own Chef 12 OpsWorks recipes.
The basic scenario we want to support is this:
- Show the user a maintenance page when we begin the deployment process
- Run the deployment via the OpsWorks API to update the application
- Disable the maintenance page when the deployment is complete
All of the above should be fully automated and ideally initiated at the push of a button in our favourite build server e.g. Jenkins.
AWS CLI is your friend
The AWS Command Line Interface (CLI) is an excellent tool and a great way to integrate things like Jenkins with the AWS API. We used it to initiate all of the steps in this workflow to run our custom Chef recipes and run the deployment of the application via the OpsWorks API. We simply created small Bash shell scripts that called the AWS CLI with the correct arguments and had these scripts executed by Jenkins in a predefined order.
We strongly recommend learning to work with the AWS CLI as it makes your life much easier!
The algorithm for showing a maintenance page
We’re great believers in simplicity, so we wanted the algorithm for showing the maintenance page to be equally simple. After some thought, we came up with the following:
If a file called /maintenance/maintenance.on exists on the local filesystem, then show the maintenance page. Otherwise don’t.
Pretty simple and it means there are two parts to our story of showing a maintenance page:
- Getting the /maintenance/maintenance.on file on the filesystem
- Updating the Apache 2 reverse proxy config to show a maintenance page if this file exists.
Custom Chef recipe to create and delete the maintenance file
If you’re using OpsWorks then you must be comfortable with using Chef. So we have a pretty powerful tool in our hands for creating and deleting a file.
We created two recipes:
- One recipe that creates the /maintenance/maintenance.on file if it doesn’t exist.
- One recipe that deletes the /maintenance/maintenance.on file if it exists.
Once we had these two recipes it was simply a case of being able to run them when we wanted, before and after the deployment process.
OpsWorks allows you to run a custom recipe at any time you wish through its API. Even better is that this can be invoked with the AWS CLI, meaning that you can integrate it with your build server. So to create and delete the maintenance file, we simply need to instruct OpsWorks to run our custom recipe. We did that with the following AWS CLI command:
The above would run the enable-maintenance-page recipe across our entire stack, creating the /maintenance/maintenance.on file. When we want to delete the the file we use the exact same process, but run the disable-maintenance-page recipe instead.
The maintenance page HTML
Installing the HTML for the maintenance page is again simple with Chef. In our cookbook we created a “cookbook file” that was a simple static HTML file that should be served to the user when maintenance is enabled. The HTML is stored in Git along with the rest of the cookbook (this means that the designers could easily change it as required). To display changes to the maintenance page moving forwards, simply run the “Update custom cookbooks” command on your stack.
The recipe that enabled the maintenance page then simply had a cookbook_file resource that downloads and installs the maintenance page. Something like this:
Updating Apache 2 to serve the maintenance page
The final part of our puzzle was to update our Apache 2 configuration to serve the maintenance page if the /maintenance/maintenance.on file exists.
In the Java Layer, Apache 2 comes with the excellent mod_rewrite enabled. We will use this to redirect the user if the maintenance file exists. If mod_rewrite isn’t available as part of your stack, or you’re using another reverse proxy e.g. NGinx then you’ll need to install it or translate the following instructions to match your stack.
We added the following to our Apache 2 config for our virtual host:
The above very simply translates to:
If the /maintenance/maintenance.on file exists, then redirect all requests to /maintenance/index.html. Otherwise process the requests as before.
This gives us a very simple way of showing the maintenance page when we want.
Removing the maintenance page
As you can probably guess, removing the maintenance page is as simple as running our custom recipe to delete the /maintenance/maintenance.on file. We simply hooked this into Jenkins after the deployment of the application itself had finished.
What we’ve shown here is a very simple approach to showing a maintenance page during OpsWorks deployments. It helps you inform your users when a deployment is on-going and the entire process can be run with the click of a button by integrating the AWS CLI with your build server.