3

I'm running an application on Elastic Beanstalk, an whenever I need to deploy a new version, I need to:

  • deploy the version on Elastic Beanstalk, which takes a minute or so
  • patch the database with any SQL patches that come with the new version, which takes a few extra seconds

During that time, I'd like the ELB to stop redirecting traffic to the EC2 instances, and only bring back the traffic to them when it's safe to do so (when the software & database versions match).

Is it possible to temporarily redirect the traffic of the ELB somewhere else? Either performing an HTTP redirect to an S3 bucket for example, or reading from this bucket instead of an EC2 instance?

I know I could do this with DNS changes, but these would take extra time to propagate, and even with a low TTL, I still can't guarantee that clients will properly obey the TTL and reach the correct server as soon as I make the update.

So ideally, the DNS should always point to the ELB, and the ELB should then switch the traffic in real time to somewhere else just for the time of the upgrade.

BenMorel
  • 4,507
  • 10
  • 57
  • 85
  • Why not to design a maintenance page and put it on any if the server and point your ELB to that server till the time you wrap with your deployement. – Abhishek Anand Amralkar Sep 18 '13 at 12:16
  • This is an idea, but the problem is, I can't really interfere with Elastic Beanstalk managing my instances and my ELB: I think that if I remove all the instances being upgraded from the ELB, the Elastic Beanstalk container will complain? Will need to check this though. – BenMorel Sep 18 '13 at 14:46
  • Also what you can do is to stop web server(apache ,Nginx) on all the machines except any any one machine , deploy ur new code on the machines where you have stopped we server start the web server and you can follow the same step on the server where we have not stopped the apache or nginx. – Abhishek Anand Amralkar Sep 19 '13 at 02:37

3 Answers3

3

AFAIK, there is no way to do it this way.

However, I found an alternative solution that checks all the boxes for me.

I updated my app's front controller to read an environment variable, APP_MAINTENANCE, and return a 503 Service Unavailable response if this variable is TRUE.

The database patching is run via container_commands and is automatic during deployment.

Now the deployment procedure is the following, using the Elastic Beanstalk API:

  • Use UpdateEnvironment to set APP_MAINTENANCE to TRUE
  • Wait until the environment is Ready (using DescribeEnvironments)
  • Use UpdateEnvironment to deploy the new application version
  • Wait until the environment is Ready
  • Use UpdateEnvironment to set APP_MAINTENANCE to FALSE.

This way, I can be sure that nothing is using the database during the database upgrade. During this timeframe (around 3 minutes), the application is unavailable and any request is returned a 503 response, which is acceptable in my use case.

Any client receiving this response is invited to try again in a few minutes, be it a real person (a friendly message will invite to do so), or an API consumer (HTTP suggests that this is a temporary failure, and that the client should retry later).

BenMorel
  • 4,507
  • 10
  • 57
  • 85
3

You could use swapping environmnent urls, described here:

http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.CNAMESwap.html

Load new version to second beanstalk and swap urls or deploy a maintenance site to second beanstalk and swap to it - all traffic gets redirected to new environment.

Matze
  • 31
  • 2
  • I've considered this option, but as it is based on DNS, changes are not instant, and unfortunately not suitable to my use case! – BenMorel Jan 05 '14 at 14:48
1

You can also set the security group on the load balancer to block public access temporarily. Not elegant but it works.

CommaToast
  • 147
  • 5