This blog series explains how to engineer applications for DevOps.
Topics covered in this blog series:
• Factors to consider when deciding whether an application is a good candidate for DevOps.
• Best practices for engineering designs for DevOps.
• DevOps applied to enterprise apps and software services.
• DevOps applied to COTS systems.
• DevOps applied to manufactured (embedded) systems software.
• Five levels of application maturity.
This blog is part two, and covers best practices for engineering designs for DevOps. You can read part one here.
Poor design practices severely limit the potential for improvements provided by DevOps. As stated in my blog post Design for DevOps—Recommended Engineering Practices, “Without good design practices, a DevOps implementation has no hope of delivering on its promise of accelerating innovation with high quality and scale.”
Following DevOps-recommended engineering practices for application design is important for legacy, greenfield or brownfield products, platform projects, feature enhancements or repairs. It is important for enterprise three-tier applications or multilayer products. And it is true whether the developers are using Agile, waterfall or ITIL development processes. In every application design case, designers face tough challenges and are expected to balance conflicting goals.
Designers are expected to rapidly drive down the work backlog yet produce quality products that avoid costly rejections and rollbacks. In addition, there is pressure to increase the percentage of effort spent on creative content rather than corrective content and do so with limited time and resources. Balancing these conflicting goals is a tall order. If not supported by recommended engineering practices, the overall design experience is a cauldron of stress and a fast route to burnout.
Recommended Engineering Practices
The following recommended engineering practices improve the design experience and the products of that design in a way that is streamlined for the DevOps pipeline:
• Designers must thoroughly understand customer use cases.
• Usability, reliability, scaling, availability, testability and supportability are more important than individual features! Quality over quantity is recommended. Designs that anticipate actual customer use are the most successful.
• The culture needs to support designers.
• Leaders must support the designers with motivation, mentoring and training.
• No designer can be expected to know everything. It is OK for designers to make some mistakes if lessons are learned and improvement quickly follows. Continuous monitoring and quick remediation are examples of good DevOps practices that help minimize the impact of any mistakes.
Design Coding Practices
Design coding practices are critical in the following ways:
• Products are architected to support modular independent packaging, testing and releases. In other words, the product itself is partitioned into modules with minimal dependencies between modules. In this way, the modules can be built, tested and released without requiring the entire product to be built, tested and released all at once.
• Where possible, applications are architected as modular, immutable microservices ready for deployment in cloud infrastructure, in accordance with the tenets of twelve-factor immutable non-monolithic apps, rather than monolithic mutable architectures.
• Software code changes are pre-checked using peer code reviews prior to commit to the integration/trunk branch.
• Software changes are integrated in a private environment together with the most recent integration branch version and tested using functional testing prior to committing the software changes to the integration/trunk branch.
• Developers commit their code changes regularly—at least once per day.
Good Design Practices Support QA and Ops
Good DevOps design practices support QA in the following ways:
• Design practices consider and understand the QA process.
• Software code changes are pre-checked with unit tests prior to commit to the integration/trunk branch.
• Software source code changes are pre-checked with static analysis tools prior to commit to the integration branch. Static analysis tools are used to ensure the modified source code does not introduce critical software faults such as memory leaks, uninitialized variables, and array-boundary problems.
• Software code changes are pre-checked with dynamic analysis and regression tests prior to commit to the integration/trunk branch to ensure software performance has not degraded.
Good DevOps design practices support Ops in the following ways:
• Design practices consider and understand delivery and deployment pipeline processes.
• Software features are tagged with software switches (i.e., feature tags or toggles) during check-in to enable selective feature-level testing, promotion and reverts.
• Automated test cases are checked in to the integration branch when code changes are checked in. Evidence that the tests passed are included with the check-in.
• Tests are conducted in a pre-fight test environment that is a close facsimile of the production environment.
Supporting Tools
The following supporting tools are needed to realize design for DevOps best practices:
• Elastic infrastructure that can be easily orchestrated, created and released, as needed, to support designers’ tasks on-demand with minimal delay.
• Design, code management, monitoring and test tools are readily available and scalable with minimal delay.
• Monitoring tools that track application process performance and report the results to designers in easily consumable formats without delay.
Applications for Which DevOps Does Not Apply
“If you build it, they will come,” made for a great movie idea in Field of Dreams, but the reality is that many DevOps journeys led to nowhere despite the excellence of the people, processes and technology involved. As indicated above, applications that will not benefit from faster lead times, incur insufficient costs to justify investment in DevOps or that are too rigid to accept change are not good candidates for DevOps.
What This Means
This blog is part two of a series explaining how to engineer applications to be most suitable for DevOps. This blog series explains how to engineer applications for DevOps, and covers topics including:
• Factors used to decide whether an application is a good candidate for DevOps.
• Practices to engineer designs for DevOps.
• DevOps applied to enterprise apps and software services.
• DevOps applied to COTS systems.
• DevOps applied to manufactured (embedded) systems software.
• Five levels of application maturity.
This blog covered practices used to engineer designs for DevOps. You can read part one here.
For more information on how to engineer applications for DevOps, refer to my book Engineering DevOps.