Much has been written recently about the role of microservices in reducing technical debt and as an approach to modernizing legacy applications, not least in this excellent article by Gene Hughson. My overwhelming question is how many different ways can you put lipstick on a pig?
This post explains microservices (briefly), how they relate to containers, how they can be used to reduce technical debt and ‘modernize legacy applications’. Assuming the legacy application in question is not to be decommissioned then, as Edmond Lau pointed out, the challenge is to get your application “as quickly as possible to a state where you’re again making incremental improvement”. We explain why any wrapping technology (containers, microservices etc.) is not the best option to get you to that state, and what is.
Let’s Get Going…
Recently, we wrote on the possibilities of using containers for managing legacy applications.
While containerization isn’t a long-term solution for modernization, it’s a common approach that has been around for many years.
Containers do offer a range of benefits such as improvements in flexibility, speed, and portability that tend to reduce dependence on virtual machines. Containerization is one of several viable alternatives for temporarily extending the life of the legacy application, and it can be especially attractive if the app will be decommissioned soon.
Microservice architecture presents another option for modernizing many legacy applications. In this approach, applications are built with small, independent processes that communicate with one another through a set of REST APIs (or SOAP web services). Though it can be daunting with older legacy apps, decomposing a legacy app into its most elemental functions and wrapping each function with a microservice API is—in essence—service-oriented computing. The result is a set of services that are accessible to other parts of the app or to other applications.
There are several reasons why microservices have been explored for ‘modernizing’ legacy monolithic applications:
- Separate service deployment increases resilience. If you deploy each service independently, then you improve the odds that an outage in a one module/component of an application won’t crash the entire application. If some of the services go down, many users won’t notice, and the team can work to pinpoint the problem.
- Components can scale independently. With microservices, you have the flexibility to to focus on the functional bottlenecks, scale the components that are having performance problems, and install hardware that best fits the service requirements.
- Phased implementation can help divide and conquer the monolithic application. With microservice architecture, you can isolate a small part of your existing app and expose it with a microservice. If you can identify clearly any definable elements that can be extracted and exposed as microservices then they can replaced/rewritten/modernized individually.
The question is, is it possible to break up your legacy monolith application? Do you know what’s in there? Has the intellectual capital that developed that app already walked out the door? Is it documented fully? If you don’t have a full understanding then breaking up the app in order to apply a microservices architecture is going to be a long, probably fruitless process.
One other touted benefit of microservices-based modernization is the flexibility to access and consume remote services that provide additional functionality that can enhance the legacy application. In turn, this can be a way to partially extract yourself from the tedium of maintaining services that can be found elsewhere. [As an aside, this is a routine feature of the Morphis approach].
On the flip side, the defects of a terrible legacy architecture will translate through to the microservice layer. Wrapping a poorly built monolith with microservices is very much like putting lipstick on a pig.
Containers and Microservices
We can think of containers as wrappers for entire applications. By contrast, microservices expose specific features or functions of a legacy application, and provide a modern interface to that functionality. But neither containers or microservices make any enduring improvements to the core of the legacy application. As we’ve said, there are benefits to each approach, but you won’t realize nearly the same benefits that would accrue if it were possible for you to fully decompose the monolithic legacy app and expose it with microservices. But as we already discussed, unless you’re 100% sure of what the app does and how it does it, this can be an impossible pursuit wasting valuable time and resources.
Much like containers, wrapping with microservices has limitations. The legacy app is merely put into a different type of isolation, so it will retain all the inherent functionality, UI, and security issues that present a threat to the business. Again, we must conclude that microservices aren’t a durable, long-term solution for modernization.
So What’s The Answer?
Clearly rewriting the application is not a good option, particularly where time, cost and project risk are factors.
Wrapping technologies can offer some short term benefits but are not a long term solution for an application a) in need of modernizing, b) with longevity and c) adding value to the business.
The fastest, lowest cost, lowest risk method to get your legacy application modernized to a cloud-ready architecture (based on .NET or Java) and that will get you “as quickly as possible to a state where you’re again making incremental improvements” is to use the Morphis modernization platform — that inherently supports both containerization and microservices development.
We’re routinely modernizing and enhancing software applications (c500K LOC) in 6 months or less. With Morphis you can implement a comprehensive and transformative approach that results in a genuinely modernized application that uses modern technologies. Contact us to find out how we can get your legacy application modernized (not quarantined) and have your developers making those incremental improvements in a .NET or Java environment. Without lipstick!