Rollback and Microservices

Is it even possible to roll microservices back?


When thinking about a deployment strategy for microservices-based systems, it is natural to consider a rollback. Before looking for a technical solution, let's discuss this idea conceptually.

Microservices

One of a plenty definitions of a microservice is an independently deployable component. This says actually a pretty lot. To understand this definition we have to go back to the very first motivation for the microservices design pattern: We want to deliver our product as soon as possible. A microservice could be in hands of one team and have a completely different and unsynchronous delivery process. A team developing service A doesn't want to be bothered by waiting for the next release of a service B if it doen't need its new functionality. Service A could be deployed into the production once a day and the service B once a month.

For all this to be possible we have to follow a few basic principles, especially the most important one in our context: No Breaking Changes. We may find the same principle under different names like "APIs are forever" etc., but the idea is the same.

No Breaking Changes

How does this principle makes the microservices deployment independent? Let's consider two services, A and B. B is calling A via A's API. In the time of development of a version v1 of the service B, there is a released API of service A in the version v1. So the service B v1 makes its call against the service A v1:

Service Bv1 calls Av1

During the development of service B v1 a new version of service A - v2 - was released. An additional endpoint was added, but it's okay for the service B because A's API was not broken (in other words, A v2 is compatible with A v1). Actually, so far there are no breaking changes the service B doesn't care which newly realeased version of the service A is talking to:

Service Bv1 calls Av2

What about Rollbacks?

Now consider that the service B in some future version (let's say v2) is using an endpoint of the service A added in its release v2:

Service Bv2 calls Av2

After some time the developers of service A find an error in the v2. They decide to rollback to the previous version (v1). What happens to the system? Service B stops working because it keeps calling the endpoint of service A v2 which doesn't exist anymore. The rollback to a previous version is a potential breaking change:

Service Bv2 calls Av1

Because it can introduce a breaking change as the rest of the system depends on the current API a rollback should be avoided in microservices-based systems.

Conclusion

As long as we can't rollback microservices, we have to find a confident way how to deploy them into production. There are a lot of good practices like separated deployment stages (development, testing, QA, ...), testing in a production-like environment, blue-green and canary deployment, and so on.

It's also very important to resist the temptation of hot fixing a bug directly in the production environment. We alywas have to adapt the continuous-delivery principles: Every change, bug-fixes included, must be properly built and tested thru the standard deployment process (delivery pipeline).

Microservices are living organisms and should be treated like that.

Happy deploying!