The Monolith: Penny Wise, Pound Foolish

I just arrived in Santa Clara for the 2016 Cloud Foundry Summit. I’ve been meaning to write this article for some time but for some reason haven’t found the time to do so. Although not typical nor preferable, I’m sitting in a hotel lobby with a beer and a burger with a bit of time on my hands before the Unconference begins later this afternoon. This must be the right time to get this off my mind and out into public to spark feedback and conversation.

The Monolith

So lets jump right in head first. I make it no secret that I’m a fan of the Microservices and Serverless architectural approaches, Continuous Delivery, Containers and Feature Teams which I deem as aspects of the Cloud Native development approach. This is not just theoretical admiration but rather hands on and experiential from years of applying and consulting with similar or direct use of these approaches and technologies. Over and over again I’ve seen that these have lead to more scalable, understandable and, most importantly, changeable systems. The alternative, developing a Monolith architecture approach, has, in my experience, tended in the other direction on all of these dimensions.

The Monolith seems easier to develop and understand for quite some time. Although it is well understood that “project size is easily the most significant determinant of effort, cost and schedule [for a software project]” as Steve McConnell pointed out in his book “Software Estimation: Demystifying the Black Art”. Lets break down some of the reasons why a Monolith approach usually turns into a Big Ball of Mud.

The Scalability Problem

When most people think of scaling they think of “web scale”, cluster size or problems only the largest companies have to deal with. Although these are areas where the Monolith architecture approach breaks down, there are situations that are much more common around scalability to deal with.

Have you ever tried to get two or more teams working on the same codebase? What problems start to emerge? How do we handle them? These are the questions that all software development organizations should ask themselves. Here are some of the problems that I’ve seen and how organizations attempted to solve them:

  • Trampling each others changes tends to lead towards complicated source control management, build and deployment approaches including:
    • Slow code review processes
    • Delayed merging of code
    • Reverse code trampling into developer environment
    • Not allowing multiple teams to work on sections of codebase
  • Breaking changes to dependent code leads to:
    • Processes for more up front design reviews
    • More comprehensive documentation of proposed changes

These problems seem to most as just the way software development works. As time passes on a system the unapologetic grip of legacy code takes hold. Unintended coupling between different parts of the system creep in and lead to additional cyclomatic complexity as McCabe defined in 1976. Later studies showed a positive correlation between complexity and lower cohesion and defect count in systems with higher cycolmatic complexity. Rather than responding with apathy and synacism about the onslaught of legacy code, this should scream at us there must be a better way.

The Understandability Problem

How long does it take for a brand, spanking new team member to get up to speed with your system or even an aspect of the system? Can a new team member be trusted to check in at least somewhat significant code on day 1 and not cause great amounts of harm? Do all of your existing team members all understand the system enough to make changes?

We’ve all been there. Downloading an existing codebase with tens or hundreds of thousands of lines of code. Taking a look at it to figure out how you should get started understanding it. Even the best intentioned and capable teams can find themselves in this dilemma of the Monolith architecture. Where did it all go wrong?

Requirements change. Business changes. Code changes. When developing in a Monolith architecture these new perspectives tend to result in leaky abstractions, muddled models, and broken boundary contexts. I believe this is due to the convenience allowed, as a type of moral hazard, to make changes that cross boundary contexts inside a single system. These changes are not done with ill intentions or even without forethought. As the great Gerald Weinberg said:

Things are the way they are because they got that way.

The Changeability Problem

Have you ever been in a situation where you’ve had to tell a product manager, stakeholder or customer that a seemingly simple change may take weeks or months because of technical debt? Were there ever situations where an architectural redesign of a component within the system was deemed as too risky with a significant and unknown duration to resolve? Are there components of the system that team members aren’t supposed to touch and instead there are wrappers around the component to interract with it from the outside?

I’ve seen all of these and have also been part of a team that has brought such codebases back to life. How did we do it? Break it apart into understandable, isolated, cohesive pieces through careful refactoring of the code and infrastructure over long periods of time. Why did we do it? Because we knew it would lead to accelerated delivery of improvements to those components. We could then scale up the number of teams developing on the system by creating feature teams around those components.

Changeability is one of the most important aspects of any software system. Smaller, cohesive components that are decoupled from other components allows the system to be malleable as the need for changes emerge. An application should not equal a single codebase. Instead, an application is the interactions of multiple components that provide the desired behavior and value to users. How can we get to this desired state?

Which Way Next?

It is my opinion that the Cloud Native development approach is going to change how we deliver software even more than most people think. The days of developing using monolithic software architectures are numbered. The platforms, organizational team structures and architectural patterns & practices that will support this change are maturing quickly. My upcoming articles will describe how I think some of this will play out in the industry. Make way for the Cloud Native way!

Managing Software Debt 2015 Predictions

2015 is fast approaching and for the first time I felt the urge to make public predictions on what the new year will bring through the lens of Managing Software Debt. Interestingly enough, many of these predictions revolve around topics this blog was constructed to discuss. This blog has been a long time coming for me since my last official blog post prior to November was in 2012 so let me take a slight diversion to describe my reflections on how this blog came into being.

My last blog gettingagile.com had run its course after 178 posts from 2005 to 2012 and it seemed to me that we were Beyond Agile and I needed a different focus. After publishing Managing Software Debt: Building for Inevitable Change in 2010, a reference on 5 types of software debt and how they can be managed and monitored, it seemed that focusing on leading change through Continuous Delivery and reducing Configuration Management Debt had the best results in my consulting experience. Since that time, the DevOps movement has hit a full stride and embodies this approach for leading change in organizations. I think we are on the precipice of our next industry revolution to reduce the cost of change for software as cloud has become a common enterprise platform of choice. With that, here are areas of the software development, deployment and operations ecosystem that I think are going to see significant interest in 2015.

  • PaaS (Platform as a Service)
  • Twelve-Factor Apps and Microservices
  • Feature Teams around Business Capabilities
  • Deployment Orchestration

PaaS

OK, OK. I know that my new role is Product Owner for PaaS at CenturyLink Cloud but there is a good reason I took this role in November (time to note my disclaimer that the views expressed on this blog are mine alone). In my last few roles the impact of infrastructure development enabling deployment foo applications and services to cloud platforms was significant enough to cause me pause. It seemed that the problems being solved were similar across development efforts: load balancing apps & services, event publishing & processing, service discovery, continuous delivery pipelining, blue/green deployments and infrastructure provisioning just to name a few. We had looked at multiple vendor offerings but what we saw prior to 2014 had been, in our opinion, immature. As 2014 progressed, the popularity of containers kicked off a valuable conversation about separation of concerns for deployment and infrastructure. Containers provided a piece of the solution that allowed infrastructure and application/service development to execute within their own life cycles beyond what Puppet and Chef had done for configuration management.

After I heard about the Product Owner role here at CenturyLink Cloud, where I’d be working with a team to deliver PaaS based on Cloud Foundry, I updated my knowledge of the PaaS space. I had already been playing with Docker and worked with others who implemented a build pipeline for our services based on Docker containers. Through this process it was clear that there were still significant problems to solve beyond the ease of development story that Docker was just an introductory chapter to. While researching Cloud Foundry again, after trying it out back in 2012 and deciding not to use it, I was pleasantly surprised how far the platform had come. Immediately I took notice of an aspect of Cloud Foundry called Warden which manages isolated, ephemeral, and resource-controlled environments (aka containers). It been around since November 2011 and had the full Cloud Foundry ecosystem surrounding it which looked to help solve more of the problems in the infrastructure and application/service deployment space than other alternatives available today.

As more enterprise developers see the benefits of PaaS, such as ease of development and deployment with low overhead for configuration management and operations involvement, there will be a large upswing in its adoption. Also, folks in operations will further benefit and enable the DevOps culture as PaaS continues to mature allowing for more self-service provisioning and deployment while still getting the visibility needed to support service level agreements and control operating costs. Look for more on PaaS in this blog as we learn more about how customers innovate and deliver on our upcoming PaaS offering.

Twelve-Factor Apps and Microservices

My last post on The Imminent Acceleration of the Twelve-Factor Apps Approach already discussed why I think The Twelve-Factor App and Microservices will be big in 2015. Some folks in our industry are already realizing the benefits of these approaches. It is probably not surprising that this realization was found mostly outside of the monolithic ESB and SOA tool vendor offerings. Instead, the rise of SPAs (single page apps), RESTful APIs, OpenID/OAuth, cloud computing, open source and many other emergent approaches from the community have been the potion for increased adoption of service-oriented architectures. Look for significant changes in enterprise application development to support The Twelve-Factor Apps approach and implementation of Microservices (or at least less monolithic) as 2015 progresses.

Feature Teams around Business Capabilities

As the chapter “Platform Experience Debt” from the Managing Software Debt book explained, organizations are more flexible when there is clearer alignment of teams to business capabilities and ultimately to their users. The rise of DevOps has brought the cultural changes needed to be more adaptive (and dare I say “agile”) to light and ignited a follow on movement from the software development centric agile movement to incorporating production operations as an aspect of team responsibility. This has made it even more apparent that the Feature Teams collaborative team configuration helps drive alignment of business capabilities with user needs along. Not only that, this organizational alignment creates less brittle boundaries between teams than component (or functional) team configurations do. DevOps has definitely made its mark with Gene Kim’s book The Phoenix Project and the outbreak of DevOps oriented conferences around the world. Look for the DevOps movement to accelerate as more real world change stories are shared in the new year.

Deployment Orchestration

With the rise of PaaS, The Twelve-Factor App and Microservices, the need for more effective deployment orchestration tools and processes will grow. Enterprise Operations groups will need strategies for dealing with the increased frequency of deployment, proliferation of environments and running processes, and hybrid models with internal data centers and cloud architectures used in conjunction with public cloud provider offerings. Continuous Integration servers and access to server instances are not enough. The number of deployment models, platforms, and network topologies will make governance a mess. In 2015 we will need to start finding solutions to orchestrating deployments from build to validation to deployment and to governance. There is a lot of room to innovate and make a significant impact in Deployment Orchestration. I’m excited to see what is coming to solve Deployment Orchestration challenges in the new year.

This is my first attempt at a predictions blog. Let me know how I did on Twitter (@csterwa). I’m always looking for feedback.

Have a Happy New Year 2015!

The Imminent Acceleration of the Twelve-Factor Apps Approach

Software that takes advantage of what the cloud has to offer must take on a new shape. Applications deployed to the cloud need to show resilience in the face of VMs or server instances going down or not behaving as expected. Applications deployed to cloud infrastructures also tend to need to scale temporarily to keep costs reasonable and automatic based on patterns of usage. Learning faster than your competition is of utmost importance to many who deploy software into a cloud therefore deploying updates on a continuous basis becomes critical. There is an approach to developing and deploying applications into the cloud, The Twelve-Factor App.

The Twelve Factors of this approach are:

I. Codebase – One codebase tracked in revision control, many deploys
II. Dependencies – Explicitly declare and isolate dependencies
III. Config – Store config in the environment
IV. Backing Services – Treat backing services as attached resources
V. Build, release, run – Strictly separate build and run stages
VI. Processes – Execute the app as one or more stateless processes
VII. Port binding – Export services via port binding
VIII. Concurrency – Scale out via the process model
IX. Disposability – Maximize robustness with fast startup and graceful shutdown
X. Dev/prod parity – Keep development, staging, and production as similar as possible
XI. Logs – Treat logs as event streams
XII. Admin processes – Run admin/management tasks as one-off processes

These factors tend to drive highly cohesive applications and services that also exhibit low coupling with their dependencies. Each application or service should be in a single repository that can be built and deployed on its own. Rather than branching or forking to create multiple deployable versions of the application, we should externalize configuration so that the maintenance costs are not exponentially growing to support all versions of the application. These applications should also have understandable boundaries and implement a single concept or responsibility to increase their disposability. Creating stateless applications and services enables horizontal scaling and redundancy across multiple nodes in a cloud. Deploying multiple instances of an application or service results in multiple ports that can load balanced and registered for use by others.

Some of these factors are no brainers for many experienced developers and some are not as easy to implement due to access restrictions to configuration management and flexible operating platforms. For those of us fortunate enough to use “real” cloud infrastructure, today’s cloud vendors are starting to provide services that enable Twelve-Factor Apps. The Cloud Foundry Foundation officially launched this week as part of the Linux Foundation Collaborative Projects. Cloud Foundry is the most robust and mature open source Platform-as-a-Service (PaaS) offering in the market. With Cloud Foundry it has become much easier to apply The Twelve-Factor App approach to applications and services. Buildpacks enable the use of polyglot software development across applications and services yet still deploy into a single PaaS. Software can be deployed using a single command to a PaaS: `cf push <appname>`. Zero scheduled downtime deployments can be performed using a Blue/Green Deployment approach, described well by Martin Fowler here, that keeps existing versions of the software (Blue) up while deploying and testing new versions (Green) that can run alongside or replace the old version (Blue) when validated as ready. And binding to dependent services, such as DB clusters and message queues, can be simplified to create a named service deployment with `cf create-service mongodb cluster my-mongo-cluster` and then binding it to your application with `cf bind-service my-app-1 my-mongo-cluster`. It is incredible how Cloud Foundry can make creating and continuously delivering a Twelve-Factor App orders of magnitude easier than constructing and managing your own infrastructure or in an Infrastructure-as-a-Service (IaaS) platform. When you need to optimize the deployment environment you can always take a single application or service and adjust it to deploy into your own data center or an IaaS platform but since they take The Twelve-Factor Approach you don’t have to do it for all of your applications and services.

I hope this article provides awareness around The Twelve-Factor App approach and how a PaaS, such as Cloud Foundry, can enable effective use of the approach. I recommend clicking the links provided in this article to read more details about the approach and how to take advantage of what Cloud Foundry has to offer. It is imminent that in the next few years that Twelve-Factor Apps will become more the norm in software development shops and PaaS will be a common deployment platform. Take the time to read and experiment with Cloud Foundry to get a leg up on this imminent acceleration of PaaS and The Twelve-Factor Apps approach.