We began exploring the concept of basing good architecture upon cloud native patterns with “A Timeless Way of Building a Cloud Native System?”. Key takeaways were that every pattern fits into a larger scheme and that the set of patterns behind a cloud native architecture can form a clear way to describe the system.
Cloud native patterns, thus, could become the much-needed shared language allowing us to name -- and, of course, implement -- context-specific best practices in this rapidly evolving technology.
We also talked about how every pattern is context dependent. In architecture, there is rarely a “silver bullet” - one approach that will work in any and every circumstance. Instead, the right choice almost always depends on where you are now and where you want to be. This is as true in designing, say, Distributed System architecture as it is in designing a townhouse.
Which is why it is vitally important that, before selecting which cloud native patterns to implement, enterprises first understand the current context for their organizational needs and aspirations as well as identifying the proper target context.
So why do we care so much about context for patterns in a cloud native migration? Let’s look at an example. One effective and popular cloud native pattern is dynamic scheduling: the use of a container orchestrator like Kubernetes to manage the deployment and live management of applications on your physical infrastructure.
But, as we pointed out in When Is the Wrong Time to Use Kubernetes?, while dynamic scheduling is great in some contexts, it can be disastrous in others.
So, then, how to assess context? Over the past three years, using lessons learned in guiding companies into the cloud, we have developed the Container Solutions Cloud Native Maturity Matrix. This is an assessment tool for helping enterprises understand where they are now vs. where they want to be: their existing vs. desired contexts.
It is important to note that not all cloud native patterns and contexts are technology related. Migrations are not just about software, and -- as the Maturity Matrix shows -- also include psychological and social aspects within the organization.
So things like an organization’s management Process, Team structure, and internal Culture, all constituent axes on the Maturity Matrix, are areas for assessing context before assigning patterns. These human-centered context areas are equally as important as tech-centered ones like Infrastructure and Maintenance/Automation.
A follow up article, The Cloud Native Maturity Matrix in the Real World, digs into case studies from a variety of enterprises who have undergone successful cloud migrations. From these case studies we can pull real-world examples demonstrating how “the right pattern” can only be the right pattern in the right context.
An example of a high-level pattern that seems to nearly always apply in the cloud native context is Continuous Integration. Within any developer’s codebase, the more it diverges from the main branch, the harder it becomes to merge working changes back into the mainline. Or the merge may even become impossible.
Obviously this slows a system’s ability to react, and reduces its stability and availability. Continuous Integration calls for putting in place tooling that makes it very easy for devs to merge their changes back into the main codebase, on a daily if not even more frequent basis, while simultaneously checking that no bugs have been introduced.
A context where CI would be less useful would be where there is a single developer and a single codebase. An automatic merging tool in that context provides less value. Another time where CI would be not only useless but actively bad as a pattern is a situation with no automated testing. If everyone is merging insufficiently tested changes into the main codebase you soon end up in a mess.
Continuous Integration and Continuous Delivery use automation to ensure that new application code is always tested, secure and ready for deployment. The automation and stability provided by CI/CD are so essential to Cloud Native architecture that few, if any, Enterprise cloud migrations would not adopt this pattern - as long as their existing technological context includes thorough automated tests.
There is, however, another non-technological prerequisite for CI/CD to be adopted successfully, and that is executive commitment. As we saw at the Financial Times and others in The Cloud Native Maturity Matrix in the Real World, these projects are difficult and expensive. If you try to implement them in an enterprise without the cultural context of senior-level support you are likely to run out of corporate patience and budget.
So Continuous Integration and Continuous Delivery are both key cloud native patterns that vitally depend on context. No matter how fundamental to the architecture, if they are executed in the wrong circumstances, they will fail.
People don’t all apply the same pattern -- they apply the pattern that is appropriate to where they are and where they want to be.
In our CI pattern example, while nearly every migration would utilize this high-level pattern to reach cloud native, this pattern’s implementation - in terms of the collection of interactive sub-patterns selected to fulfill it - would look very different every time. This is because each enterprise comes to CI/CD with its own pre-existing context, and sub-patterns are one way to customize to context.
Dynamic scheduling is another area we can look at for context examples. For some, their context may be that they are low ops, having a very small or even no internal ops team. For them, implementing an ops-heavy scheduler like Kubernetes on their own would be a terrible idea, given that its complex tooling requires dedicated staff to implement and maintain.
Those in a low-ops context, then, might want to go to EKS or some other hosted solution: that is the good pattern for the cloud native context you want to achieve.
Conversely, say you are an enterprise that already has an ops team, and you want to keep your ops team. Given the resources at hand, you may not want to move to managed hosting and so roll-your-own dynamic scheduling, in the form of Kubernetes, is the correct pattern for you.
Evaluating context using the Maturity Matrix is how we know, in fact, to do K8s in some circumstances but not others.
The ideal is to deliver the context of being more cloud native and having dynamic scheduling (patterns). But if your current context is Monolith, then, again, you will get much less value from implementing Kubernetes at that point -- because you are not yet in the right context for that pattern to be useful for you.
When the right patterns are applied in the proper context, the results can be powerful. Time is saved. Money is saved. People get to work in cloud implementations that feel “right” -- for both the enterprise’s business mission, and the human hands that execute it.
Read more about our work in The Cloud Native Attitude.