DevOps - Deployment strategies
Tags: devops, sre
Published: 2022-01-04 11:48:13

In our current DevOps/Cloud world, we have a lot of powerful tools to deploy and expose our services to the world. But using a powerful without a proper way to use it, it can be a big loss *(money, time...)* for your team/enterprise.

So here are some Deployment strategies to help you to improve your deployments and/or capitalize on your tools.

---

## What is a Deployment strategy ?
A "**deployment strategy**" is a part of a pipeline where you define how you will deploy your applications/services.

You can have a simple deployment pipeline, where the strategy is for the whole pipeline.

But you can have a more complex pipeline *(like a CD [1] one)* where the strategy concerns only a part of it.

---

## Strategies
### Recreate
The **recreate** strategy is the simplest one and the less cost effective.

As evoked in the name, this strategy is composed with 2 steps
- delete the current version of the application in the server/cluster
- deploy the new version in the server/cluster

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sqadsruuybiv67pgpqzr.jpg)

#### >> Pros
- Simple and quick to do it
- Supported by a lot of pipeline tools 

#### >> Cons
- The service will be unavailable during a period of time. So if you have a high SLA *[2]*, it clearly won't be the best choice.
- The new version have to support all the existing features without breaking changes *(if you have some breaking changes, it can be a problem for your consumers)*.

---

### Rolling Deployment
This strategy will update progressively all the instances of an application with the new version.

Steps :
- Loop for each instance
   - Kill the existing instance
   - Deploy a new instance with the new version
   - Check if the new instance is started correctly, if yes go to the next instance


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d52qu261cyih2ln1efy1.jpg)

#### >> Pros
- Won't impact your availability
- Easy to use and setup with Kubernetes

#### >> Cons
- The new version have to support all the existing features without breaking changes *(if you have some breaking changes, it can be a problem for your consumers)*.


---

### Multiple versions
Simple and clear following its name, this strategy is to support multiple versions of your application in production.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/azy53t9xtlwnkiw54h80.jpg)

#### >> Pros
- Will let time to your customers to migrate to the new version
- Your application doesn't need to support the old features

But...

#### >> Cons
- Use it only when you have a breaking change. If you are doing it for each version without breaking changes, you will lose in productivity, especially about the support.
- More production versions to support. More versions you have in production, more versions you have to update/test... when a production issue happens.
- Take a lot of time. Using this strategy, you will have to setup a lot of things manually (pipeline, routing configs...).
- Must be thinked from the conception step to avoid to have a lot of breaking changes in the future.

This strategy can be really useful in a breaking change case. But as explained, you can have some surprises. 

So if you will use it, be aware of the cons and prepare a clear strategy to avoid to have 45 breaking changes a year and support 10 versions simultaniously. With these elements in mind, it should be ok.

---

### Blue/Green
This strategy is based on 2 production environments:
- a **Live** one where the services can be used
- a **Staging** one where we deploy the new versions of the services

When your staging environment is ready for the production *(after quality testing)*, you have to shift the traffic between the two environments.

If everything is OK on the staging environment, you can completly switch the traffic to this environment, which will become the new "live" environment.

If you have some issues, switch back all the traffic to the current version of the service.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4dqo548er3aztzbxfif6.jpg)

#### >> Pros
- Simple to understand
- Can be easy to set up with some tools
- Easy rollback

#### >> Cons
- Can be longer to set up with some tools which doesn't have natively this feature *(or if you are doing it manually)*
- Can be expensive. You will have to double at least the running instances of the service, so had all the available resources to be able to run them and redeploy them. *(May be more if you are using microservices)*
- Can be complex to set up, especially with microservices, even more if you are using something like Kafka or MQ. You will have to be sure that all the services are only communicating with "the other services in the same environment".

---

### Canary
This strategy is to migrate progressively your users to the new version.

> *How to do it?*

You will replace some of your current instances by the new version, and you will shift some of the traffic on it. Then you can check if everything is right for this group on the new version. 

If yes, you can grow the percentage of user using the new version and continue to replace the instances with the "old" version until all the instances are updated.

If no, you can easily rollback to the "old" version.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xg4a36fby49plpby7wu.jpg)

#### >> Pros
- Easier and cheaper to set up than a Blue/Green strategy
- Fast and safe solution to migrate in production

#### >> Cons
- Must have more preparation/set up/configs in place in case of a breaking change
- As the Blue/Green strategy, it can be complex to set up with microservices, especially if you are using a queue service like Kafka or MQ.
- A monitoring set up must be in place to see correctly what happens on both version.

---

### A/B Testing
The A/B resting is a strategy technically similar to the Canary strategy. You will deploy a new version on a limited number of instances and shift some traffic on it.

But, here the objective is to more to do some experimentations on multiples ideas and see which one works well.

I think it's a good deployment for frontend applications to see if the users are not bored or don't quit in a middle of the sequence to find/do something.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzw5tp8nb70rgdgnhtww.jpg)

#### >> Pros
- Really powerful to retrieve some real world impressions
- Easy and cheap to set up

#### >> Cons
- Experimental mindset. You will do tests and experimentations. Some elements can break the application, so depending the criticity of your application you must take some precautions
- As it's for experimentations, it can be long and/or complex to setup automated tests

---

## What is the best strategy?
There's no best strategy for each deployment. They all have their pros and cons.

> *So how to choose one?*

It will depend of several points. So be sure to take a look of the following points and ask you "depending of my answers, what does fit the most ?". 

### Criterias
- **Availability** : Does your application can be shut down during a period of time ?
- **Criticity** : Do you risk something if an issue happens during the deployment ? *(ex: database integrity)*
- **Breaking change** : Will you deploy a new version with a breaking change ?
- **Budget** : Do you have a big budget for your infra/deployment ?
- **Traffic management** : Do you have something to easily manage the traffic to your application ?

### My experience
With my experience, I saw that you won't have only one deployment strategy for a project. There is no magic. You won't manage the same way a version with and without a breaking change.

I generally saw :
- the **recreate strategy** for simple and not really used applications
- a **rolling deployment** for "simple updates"
- a **canary** *(when all the tools are here)* for a huge update without breaking changes or opening to a new big feature
- a **blue/green deployment** for infra migrations or rewrite of an application without changing the features
- the **multiple versions deployment** in a case of breaking change **with an anciliary strategy** to be sure that the number of differents versions won't grow up and all the consumer will do the update "quickly"
- the **A/B deployment** when you want to test some user interfaces and want to see which one is the most efficient.

---

To conclude, don't be afraid to do some tests on your non production environment or change your strategy even if you're already in production. 

Especially in IT, we don't know if something will do the job for the next 5-10 years. All these solutions can work for a long time, but maybe a new tool/strategy will have a best fit with your context, or your context can evolve! 

So don't engrave your choice in the stone and live with your solution, be aware of all the pros/cons of each and everything should be alright! 

---

I hope it will help you! 🍺

---

### Links
#### Other posts about Deployment Strategies
- https://harness.io/blog/blue-green-canary-deployment-strategies/
- https://cloud.google.com/architecture/application-deployment-and-testing-strategies
- https://docs.openshift.com/container-platform/3.7/dev_guide/deployments/deployment_strategies.html
- https://docs.aws.amazon.com/whitepapers/latest/introduction-devops-aws/deployment-strategies.html

### Acronyms
[1] CD : Continuous Deployment
[2] SLA : Service Level Agreement

*For their definition, go check the following post :*
{% post https://dev.to/adaendra/some-devops-terms-definitions-1h8o %}