The “Accelerate” book by Nicole Forsgren, Jez Humble and Gene Kim identifies 24 key practices and capabilities that characterize high performing teams and organizations. These are the direct result of the State of DevOps research that the authors have led over the past 6 years.
The capabilities are grouped into 5 dimensions:
- Continuous delivery
- Product and process
- Lean management and monitoring
In a previous post, we highlighted how Spinnaker helps support “version control (everything-as-code)” and “trunk-based development” capabilities.
In this post, we will discuss how Spinnaker helps high performing teams practicing:
- Loosely coupled architecture
- Deployment automation
Loosely coupled architecture
We found that high performance is possible with all kinds of systems, provided that systems—and the teams that build and maintain them—are loosely coupled. (chapter 5)
There are several conclusions packed in this single sentence. There’s the key idea that systems with loosely coupled architectures are more conductible to high performance delivery. But also that teams should be loosely coupled, aligned with the architecture. Finally, the authors are saying that the architecture design is a much stronger differentiator for performance than the actual technological stack:
“It’s possible to achieve these characteristics even with packaged software and ‘legacy’ mainframe systems.”
The future architecture is a product of the current team structures
These days we cannot talk about team organization without referring to Conway’s Law, which says that regardless of the desired (future) state of the software architecture, what will emerge is an architecture that mirrors the (present) teams structures (and the communication channels between them). Ruth Malan, an IT architect, puts it best:
“if the architecture of system and the architecture of the organization are at odds, the architecture of the organization wins”
This disconnect between intended architecture and the reality is often a result of designs dictated by enterprise architects that are too far removed from the everyday relationships between teams. There is a role to be played by them: leveraging Conway’s Law for the benefit of the organization, rather than blindly fighting it by focusing on technology choices and architecture designs that don’t take teams into consideration.
Many empirical studies have confirmed Conway’s Law and the research in the Accelerate book confirms once again that we need a more organic view of system architecture if we want to achieve high performance.
Fast and flexible pipeline setup
While a tool like Spinnaker can’t help you decide on your architecture and team structures — although forensic analysis of version control can provide a lot of useful insights on the reality of team interactions —, it can support a loosely coupled architecture in different ways.
As our architecture evolves and smaller, independent parts get created we will need deployment pipelines for them. We might be splitting a subsystem in two (without changing the technology stack) and thus essentially need to replace the existing pipeline with two very similar pipelines. Other times we might be creating a new service with new technology or a significantly different design from the rest of the system (perhaps applying the strangler pattern). We’ll also need a new pipeline that works for this new service. And in all cases, we will want to share some good practices across different pipelines and stacks.
Armory’s Pipelines as Code feature allows reusing stages (defined in module files) across multiple pipelines. When the module definition changes, all the dependent pipelines get updated, meaning that best practices can quickly be applied to multiple components without requiring error-prone manual copy/paste operations. We can also override values for variables used inside the module definition, supporting minor variations across components. In short, we are applying good coding practices like reusability and modularity to our pipeline definitions. We can even use common tools for comparing and merging modules and pipelines.
Part of Spinnaker’s raison d’être is to support multiple automated deployment strategies as a first class concept: highlander (new instances kicked off in parallel with existing ones, once up and healthy then delete old instances), red/black (similar to highlander but keeping new and old version in parallel - only one is active at any moment) or rolling push (gradually delete old instances as new ones get created successfully).
However, if we’re working with a single pipeline monolith, we need to choose a single deployment strategy for the whole system. With a modular architecture, made up of independently deployable parts (where microservices as the exponent), we can pick the most adequate strategy for each part, according to factors like cost, risk, or availability needs.
Further, if part of the monolith requires some downtime for upgrade (for example the database schema is changed), then we have to accept that the system will be unavailable during deployment. But with a truly decoupled architecture with independently evolving data storages, we can keep the system up and running even when one of its components is unavailable. Shipping service is down? Store the orders and process when service is back up.
In summary, breaking down a monolith requires strong technical and organizational awareness to succeed. It needs to be undertaken as a learning process, not as a big bang, multi-month project. The benefits will be reaped once independent parts of the architecture can evolve in parallel and flow autonomously to production with their own deployment pipeline and strategy.