29

My understanding of Elastic Beanstalk is that when you deploy a new version of your app, that it deploys it to the Amazon EC2 instances one at a time (if you have more than one). However, even with a minimum of two instances, my application incurs a short amount of downtime when I upload a new .war when it is deploying it, as if it is updating them both simultaneously. Is there a way I can ensure there is no downtime and that one instance is fully updated and accepting requests before the next starts: Here is how the events look. Note this is with zero load on the app, so it will only get worse with production traffic.

INFO
Environment update completed successfully.

INFO
New application version was deployed to running EC2 instances.

ERROR
The application did not respond at the health check URL.

INFO
Waiting for 8 seconds while EC2 instances download the updated application version.

INFO
Deploying version SomethingMore to 2 instance(s).
Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
Peter
  • 29,498
  • 21
  • 89
  • 122

2 Answers2

22

To achieve this goal in Elastic Beanstalk, you'll need to expand your deployment procedure to facilitate multiple Environments (see AWS Elastic Beanstalk Components):

An environment is a version that is deployed onto AWS resources. Each environment runs only a single version, however you can run the same version or different versions in many environments at the same time. [...] For more information about the environment and the resources that are created, see Architectural Overview. [emphasis mine]

This feature is useful for testing/debugging separate versions already, but specifically this enables hot swapping of environments as well, see Deploying Versions With Zero Downtime for a respective walkthrough:

Since AWS Elastic Beanstalk performs an in-place update when you update your application versions, you will experience some downtime. However, it is possible to avoid this downtime by swapping the CNAMEs for your environments. This section walks you through how to perform a CNAME swap using the AWS Management Console, the command line interface, or APIs. [emphasis mine]

Steffen Opel
  • 63,899
  • 11
  • 192
  • 211
  • Thanks, the environment CNAME swapping is exactly what I was looking for. – Peter Jul 17 '12 at 23:09
  • 6
    I tried this out on my production app and observed that even after swapping CNAMEs and waiting for the DNS TTLs to expire, a sizeable portion of traffic was still going to the old beanstalk environment. I suspect this is because clients are holding on to the DNS cache longer than they should. If clients cannot be relied on to obey the TTLs, then this CNAME-swapping technique does not appear to be a reliable way to do ZDD deployments with Beanstalk. – Aaron Iba Jan 18 '14 at 22:30
  • @AaronIba That's a very good observation. Did you come up with some alternative way? I'm thinking of simply overwriting the existing application version and shutting down existing instances manually (ASG should ramp up new ones and pull the updated application version). But that's manual/slow/cumbersome process and feels like a hack. – Tuukka Mustonen Aug 28 '14 at 15:29
  • 1
    Yes, I ended up running an HAProxy instance with a static IP address that forwards to one of two beanstalk backends. When we do a ZDD, we update the beanstalk backend that is not currently in use, wait for that update to complete, and then switch the HAProxy instances to point to the other backend. It works pretty well. In the meantime, Amazon released a "rolling updates" feature that you might want to look into: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.rollingupdates.html – Aaron Iba Sep 04 '14 at 15:55
10

I know this is an old question, but for people googling (like me), Elastic Beanstalk released rolling application version deployments today (11/2/2014).

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.rolling-version-deploy.html?sc_ichannel=em&sc_icountry=global&sc_icampaigntype=launch&sc_icampaign=em_125873140&sc_idetail=em_14124901705&ref_=pe_411040_125873140_8

This allows you to update part of your fleet with your new application at a time, ensuring that there's always hosts available to take traffic.

zongweil
  • 2,031
  • 2
  • 21
  • 30
  • Does this only work if you're running multiple instances behind a load balancer? From how it's described, it seems like a single instance will still go down. – Jonathan Tran Dec 12 '14 at 23:42
  • 1
    Yup, you need more than one instance in your Elastic Beanstalk environment to avoid downtime. This is true everywhere though; if you're serving traffic from one host and you update the host (even if it's in-place), you risk some downtime. – zongweil Dec 13 '14 at 00:10
  • The above statement is simply not true. I've done zero downtime deploys on a single host with nginx. (Not on elastic beanstalk.) – Jonathan Tran Dec 13 '14 at 00:23
  • 1
    The new "Rolling with additional batch" deployment policy should presumably solve the downtime issue for single-instance configurations. – jamix Feb 13 '17 at 14:21
  • The "Rolling with additional batch" tip was perfect for me. Note that there are now several options available, check the [AWS announcement](https://forums.aws.amazon.com/ann.jspa?annID=3675) for a brief explanation and/or go to the [latest documentation](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.rolling-version-deploy.html) for an in-depth information. – leovrf May 09 '17 at 17:20
  • Yeah but it doesn't work. Single-instance environments still have downtime when using rolling deployments. – tar Jun 01 '18 at 13:15