OpsWorks Blue/Green deployments now with ALB!

In Green/Blue deploy on Amazon OpsWorks I presented a simple way to obtain the green/blue deployment with OpsWorks by switching ELBs (Elastic Load Balancers) between layers. But what if you need ALB ( Application Load Balancer )?

The problems

ALB doesn’t work out of the box with OpsWorks instances and ALB cannot be attached to a layer with AWS Console or SDK, it’s just doesn’t work like that.

Solution

First you must configure OpsWorks instances to start using ALB. See Amazon blog for complete step-by-step tutorial: https://aws.amazon.com/blogs/mt/use-application-load-balancers-with-your-aws-opsworks-chef-12-stacks

In brief after enabling all IAM policies, copying recipes and so, this manual boils down to two simple actions:

# register ec2 to ALB target group. Runs after all setup recipes
client.register_targets(target_to_attach)

and

# deregister ec2 from ALB target group. Runs on shutdown
client.deregister_targets(target_to_detach)

As you must know ALB works with listeners which in theirs turns work with target groups to which you actually register/deregister your ec2 instances.

After attaching ALB to your instances you can go back to the B/G Deployment. In my previous note on the OpsWorks B/G I did switching between stacks by detach ELB from Green and reattach it with the Blue layer:

But as I mentioned it can’t be done same way with ALB, if you want to make it work you have two options:

Brute ec2 one-by-one register/deregister. I’m sure this will bring some shamanic dance around register/deregister ec2 instances on green stack launching ( you can look on detaching recipes to to start sweating ), I don’t want to dig this up, cause it’ seems quite painful to implement.

Run different listeners for Green and Blue stack on different ports and just switch ports.

It can be done in two simple steps:

  1. Start green listener in parallel on some dynamic ephemeral port from range of 49152–65535.
  2. Instead of calling
owc.detach_elastic_load_balancer( elastic_load_balancer_name: ENV[‘ELB_NAME’], layer_id: ENV[‘SWITCH_ELB_FROM’] )
owc.attach_elastic_load_balancer( elastic_load_balancer_name: ENV[‘ELB_NAME’], layer_id: ENV[‘SWITCH_ELB_TO’] )

you just call now:

# move blue listener from application ports 
client.modify_listener({
listener_arn: ENV['SWITCH_FROM_LISTENER'],
port: ENV['LISTENER_HIDDEN_PORT']
})
# move green listener to application ports
client.modify_listener({
listener_arn: ENV['SWITCH_TO_LISTENER'],
port: 80
})

As a final result AWS brings same smooth switching as it was with attaching/detaching layers. You will get a couple of seconds the blue version of application, and after that goes the green.

PS don’t forget to add respective ENV to application and modify ec2 policy from amazon tutor by adding

“elasticloadbalancing:ModifyListener”

to allowed actions.