Zohaib Khan

6 minute read

Containers Rewrite Applications

Not surprisingly, the most popular way to experiment with containers and experience the full cycle of development and delivery with them is to write an application or two and experiment. However, a lot of developers get trapped in this dichotomy and only want to pursue this path to adopt containers and not consider other options. Maybe because it is much easier to get started this way and perhaps they get an empty canvas to create the next masterpiece. Who doesn’t want to start from scratch and not bring the baggage from the legacy. Well, there is a sweet spot to start this way, but I hope I’ve made some valid arguments earlier in this series that allow you to consider that there might be other options worth looking into.

When Rewriting Applications Is a Reasonable Option?

So when does it makes sense to start from scratch? It does when:

  • Mindshare does not exist in the company anymore that built the current/legacy application. This type of applications are typically around for 15 - 20 years or more.
  • Current application is built on a very old technology that is not supported by the vendor anymore, its way out or the skill set has long been phased out. Mainframe applications written in Cobol come to mind here.
  • Access to source code, configuration, data sources and/or integration points is not available. For example, when you have a managed solution from a 3rd party that locks you out of looking under the hood to make changes or the system resides on very old technology that cannot be run natively anymore (e.g. older operating systems) etc.
  • It is not easy to make significant changes to the existing application to accommodate new business needs. Either due to tight coupling, lack of test coverage and/or bad system design.

Container Adoption via Complete Rewrite

Figure 1: Container Adoption via Complete Rewrite

Undertaking a rewrite involves a lot activity upfront, including planning, inventory of existing features and their prioritization. It is also unlikely that the new application will implement all the features verbatim as the older application. Reason is, the older application evolved over a period of time and became what it is as a result of business requirements piled on to it over time. A lot of refactoring probably went into it from the original design. But when you rewrite something, you can take advantage of optimizing the data structures, break down features into reusable service, eliminate bloat and take advantage of newer formats and integration options.

When will you consider a rewrite to be complete?

Honestly, the new application might not implement all the older features, just only the important ones and have some new ones too. A better yardstick to measure progress is to compare feature parity. For example, if older application provided a way to create user accounts, update their profile, save user information and update it, then the newer one can do all of them and more with a set of new features using microservices.

Make sure that when you get a chance to completely rewrite an application on a modern micro services architecture, you incorporate some these common sense principles (not an exhaustive list):

  • Implement single business purpose services. Do not overload them by making them do more than one business function, even if the underlying legacy database and/or data structures are common.
  • Implement services that share nothing . This approach allows you to scale by just adding new nodes and provide virtually infinite scalability.
  • Separate deployment of services into individual deployment units. This affords you independent release cycles for each component. Do NOT bundle more than one service in a single WAR, EAR or JAR file. I would extend it to NOT deploy them all in a single JVM either. If you have to release more than one service at once, you can always do that. But if you lock them all or few into a single JVM or binary, then it’ll force you to combine release cycles unnecessarily.
  • Incorporate some kind of service registry that’ll allow you to discover services programmatically.

How do the containerization options all compare?

Based on my experience, the graphic below compares the migration approaches on a cost and timeline scale.

Container Adoption via Complete Rewrite

Figure 2: Comparing Container Migration Approaches

  • Lift and Shift efforts are generally cut and dry and have a finite end than Augmenting or Complete Rewite. Reason being, you deal with an existing code base and configuration and do not create anything new.
  • Most Lift and Shift are generally cheaper than Augmenting and Complete Rewrites. This may be a surprise, but when you are dealing with finite code, configuration and data, it is easier to time box the effort and beef up the resources to do a lot of work concurrently sometimes.
  • Augmenting approach allows for incremental rollout of capability, without disrupting the status quo. They are much quicker to show the results than Complete Rewrites.
  • Complete Rewrite usually requires significant time and cost commitment than Lift and Shift and Augment. You have to be really disciplined to catalog all the existing features, dig into the legacy code to learn what’s going on and deal with its complexity and write good test coverage to figure feature parity from legacy to modern system. There is also this temptation of being able to write and release new features that were not there before, which ends up in a feature roulette. This could be true when business cannot wait long or you have failed to meet earlier timelines of delivery or show progress and have to revise delivery dates, only at the cost of adding new features.

Dealing with Large and Monolith Applications

While the three approaches (Lift and Shift, Augment and Rewrite) may look like exclusive options, chances are that you may end up with a hybrid approach for a large application. Some applications may require their parts Lift and Shifted into containers, while some other parts have to be Augmented with integration and have to be migrated incrementally. Heck, you may have to rewrite portions of an application too.

Small and medium sized applications will fit into one or the other approach, due to their limited scope. The takeaway here is to be able to draw the line and choose an appropriate starting point, knowing your options and the tradeoffs of each approach. The task of modernizing applications to any new technology is a daunting one, but when you have a decision making framework available, it makes it easy to set expectations and take the journey.

In the next part we will discuss approaches to get started with a large portfolio of applications, create a roadmap and take a systematic and disciplined approach to modernization.

Containerizing Workloads Series

  1. Migrating Existing Workloads to Containers at Stackworld 2016
  2. Containerizing Workloads: Why Migrate Workloads to Containers?
  3. Containerizing Workloads: Patterns of Migrating Workloads to Containers
  4. Containerizing Workloads: Augment with New Layers Container Adoption
  5. Containerizing Workloads: Adopting Containers by Completely Rewriting Applications
comments powered by Disqus