Zero downtime deployment -- i.e., making sure your application can be deployed without negative impact to your customers -- is something most of us strive for. It is a prerequisite for successful continuous delivery, so you’re able to deploy at any time and never fear pushing a new release.
ElasticBeanstalk, the Platform as a Service component of AWS, has great support for zero downtime deployment. After building an integration with it a while ago at Codeship, we’ve seen many teams using Elastic Beanstalk together with Codeship. As a result, we’d like to give you more insights into their features and how easy it is to get started.
All of the following configuration works by default with the built-in Elastic Beanstalk deployment in Codeship.
You can read more about our deployment integration in our ElasticBeanstalk documentation page.
Elastic Beanstalk has rolled out a couple of features over the last year that make zero-downtime deployment safe and easy. By setting up batches and health checks, your application will automatically deploy to a subset of servers in use so your customers don’t see any negative impact.
Elastic Beanstalk is made up of applications that have a collection of environments which contain server instances. To read more about these components, you can check out their introduction documentation.
Batch Deployment Configuration
Batch deployment configuration allows you to deploy to an environment’s servers in batches. Thus you can always have a predefined amount of resources to fulfill requests while the rest gets updated. Through automated health checks, the system will make sure that the deployment has worked successfully.
As shown in the following screenshot, you have the ability to do percentage-based batch deployment or define fixed batch sizes.
Especially when using auto-scaling, a percentage-based approach seems to be the better solution. Otherwise you might define batches that are too large or small depending on the number of servers in your environment.
Make sure you have enough capacity though for the deployment; some servers will be actively moved out of rotation for a while which lowers your overall capacity. In case removing some of your instances from production while they’re being updated is not an option for you, try creating an additional environment and deploy by swapping the CNAME on the environments or increase capacity right before running your deployment.
Of course, this now means that two versions of your application are running at the same time. You need to make sure you have zero-downtime deployment built into your changes so your application works for your customers during the transition.
How it deploys
When you trigger a new deployment, Elastic Beanstalk will first start draining connections from a batch of servers matching your configuration if you configured connection draining.
Connection draining
You can set up connection draining in the network tier of your environment configuration. Set the timeout to forcibly close connections if they aren’t closed in that time. By default, the timeout is 20 seconds; any request that is started and doesn’t finish within 20 seconds will be cut off. No new requests will be sent to the batch of servers currently being updated.
As soon as no open connections exist to the set of servers in the current batch, the new version of your application will be deployed.
Deployment health checks
After the deployment on an instance is finished, ElasticBeanstalk checks the application for health. If the health check fails for a while and the deployment timeout per machine is reached, the deployment will still be continued on other servers.
As with connection draining, those health checks can be configured in the network tier:
By default, EB will send an HTTP request on port 80 of your machine, but you can define a different path or even different port/protocol. The health check expects a return of HTTP Status 200. You can read more about the details in their health check documentation.
Rolling Configuration Updates -> Health Update
Another important configuration is rolling configuration updates. While not specific to deployment, this can have a large impact on your application uptime.
Whenever you want to change any configuration on your instances or AWS needs to replace a server in your environment, they will go forward according to this configuration.
Rolling configuration updates let you configure how many instances will be updated at once and if there should be a health check at the end of that update. You can also do a time-based update; it won’t wait for a successful health check but rather for a specific amount of time between updating different batches of your servers.
The health check used is the same health check used during deployment and as a general check of your infrastructure.
While not directly responsible for deployments, it is definitely an important configuration that you should check very carefully so as not to be surprised by a downtime caused by a configuration update on your servers.
Conclusions
Elastic Beanstalk batch deployments are a very simple yet powerful way to have zero-downtime deployment on AWS. Because it’s reusing existing infrastructure, it's fast, much faster than standing up a new environment and switching CNAMEs.
With all those features, Elastic Beanstalk is a very interesting service to run your applications in. Their support for Docker containers and integration with Elastic Container Service provide a great way to start building applications on AWS.
You should give it a try and see how easy it makes getting started on AWS. Let us know in the comments about your experience with AWS Elastic Beanstalk, as well as their batch deployment and zero downtime deployment.