Friday, June 14, 2019

DevOps in detail, Introduction


This is the first in a series of posts explaining in detail what DevOps is and providing tips for its implementation in a SW development organization.

These posts won't deal with the organizative aspects of DevOps, e.g. how to change your company's culture to embrace DevOps or what adaptations your company structure needs to effectively leverage the benefits of DevOps. You can find multiple books and other sources analyzing those subjects.

Why DevOps?

Before embarking in the DevOps journey you probably want to know what is the purpose of such journey, right?.

Look at your SW business and craft a wish list of improvements you'd like to achieve. I'm pretty sure that many (perhaps all) of the following wishes will be on your list:
  • low risk releases
  • faster TTM
  • higher quality
  • lower costs
  • better products
  • happier teams
The DevOps paradigm, if applied correctly and thoroughly, can bring your business all those benefits. Have a look at the Continuous Delivery web site for more detailed reasoning about how that is possible. In these posts we'll focus on the technical details of a DevOps machinery for automated SW production.

Make it easy on you

Whatever your organization's current status in adopting DevOps is, there are two aspects in SW products that can make much easier the transition to a pure DevOps environment. These aspects are:
  1. Frequent releases. This aspect is more related to how your organization manages products than it is to the products' technical details. Think about some of the products your organization makes; how often do they publish a release? Once a month? Once a week? Every day? The more frequent your releases are, the easier will be on your organization to fully enable  Continuous Delivery, where basically every approved commit is released into production.
  2. Micro-service architecture. This aspect is concerned with how the different parts of a SW product are structured, coded, and deployed. Again, think of products you make or work with. Can you safely and easily replace a running version with a new/old one? Can you replace some part(s) of that product, leaving the rest untouched?. If you can, it's very likely the product in case is made as a set of micro-services (small, simple constituent parts with little coupling to each other).
If you're on the infrequent releases side (say, one release a month), think twice before start adopting DevOps principles. The no-return point of publishing a release imposes a strict (and expensive) discipline of thorough testing and verification across multiple stages until you're confident the product is production-quality, and you can't squeeze that process down indefinitely. Moreover, you'd spend a huge amount of money in doing so. Instead, remove barriers and speed up your process. Some things you might try are:
  • Design-For-Failure (DFF): introduce that discipline to your development teams. Assume the SW will fail from the very first moment. If will fail continuously and in the most exhuberant ways. Have your teams interiorize that assumption and work according to it. Check page 11 in AWS Best Practices for further information;
  • Simplify start-up&shut-down: remove as many steps as you can from your SW start-up and shut-down stages. Move somewhere else or schedule for later those you can't remove. Your SW must be able to come up and be removed in a snap;
  • Test often, test early: speed up your tests and move them as closer to the developer desktop as you can. Do your performance tests run fast? Run them on every commit then. You have mocks for most components of the system? Run integration tests instead of component tests. Can you capture real inputs to deployed systems? Apply them to systems in development to verify how they would perform in the real world.
Similarly, being on the monolith (as opposed to miro-services) side jeopardizes your organization's ability to run DevOps by the book. Sytems characterized by a regular number of complex parts tightly coupled to each other, all running in localized computing resources in order to achieve the highest throughput-per-square-meter give place to many-to-many heterogeneous interactions between mutually dependent parts, which in combination with late integration testing leads to butterfly effects and never-ending verification and fault slip-through. Instead, try to move gradually to a micro-services architecture for your product(s). Check this InfoQ post for more details. Things you might try are:
  • Start stripping away non-critical parts of your system. Instead of breaking up your system's core, start with those parts representing a lower risk to the product's success. With the knowledge and experience gained in doing so, you'll be better prepared to undertake the split of the more valuable parts;
  • Stop adding new features to existing parts. For every new functionality you want to add to the existing system, evaluate the possibility to craft it as a separate, loosely-coupled process, using network interfaces instead of IPC or dynamic linking;
  • Fight technical debt. Wrong decisions taken due to time constraits will slow you down in shifting to a micro-services architecture. Follow the good practice of devoting one sprint now and then to remove technical debt. Look carefully into technical debt warnings from your development teams and try to give them the time and tools to prevent it.

Conclusion

In the next post, we'll describe the main premises a DevOps environment should follow. Make sure your organization and products are in the right shape to adopt those premises before sinking hard-earned money in implementing them in your organization.

Go middlewares for object-oriented programmers Go language (Golang, http://golang.org ) is a very simple procedural programming language of ...