Developers vs. DevOps: Cloud-native architectures have separated the roles of developers and DevOps. Is this the right way to go or should developers seize control of their code?
With the introduction of container orchestration frameworks like Kubernetes, the adoption of cloud-native technologies, and the transition to microservices architectures, engineering organizations were empowered to build scalable and complex applications. DevOps engineers have had an indispensable role in this revolution, enabling and supporting these processes.
As part of this process, DevOps roles have evolved, shifting their focus from traditional network and IT needs to managing cloud infrastructure, CI/CD pipelines, virtual environments, and more. DevOps has become its own thriving culture.
It is quite common to see that, as a result, organizations have crudely separated developers’ responsibilities from those of DevOps. Everything that has to do with code and core-logic development, is the role of developers. Going beyond the local machine, however, is often DevOps’ turf. This includes anything from CI/CD, cloud deployments, and even basic network access to remote resources.
The New Challenge with Cloud-Native Architectures
While microservices provide dev teams with many advantages, simplicity and order are not among them. Even though each service is (in theory) simple in itself, it doesn’t mean the system as a whole became simpler – the complexity pattern has changed. In cloud-native architectures, unlike monoliths, your code runs in many different deployments – in microservices (deployed in Kubernetes, or other container orchestration framworks), serverless functions, big data pipelines and notebooks, legacy cloud instances, and more. This means that the distance between the code developers write and how it actually runs has grown, and continues to grow – it is no longer trivial, and often quite hard, to understand how your code would behave in its actual deployment environment. Code in your IDE (“at rest”, so to speak) and code in your cloud environment (“in transit”) are growing further and further from each other.
It gets worse – even if you’re able to make sense of how things are working today, things may not be working tomorrow, for a variety of different reasons: code changes in your repo, of course, but also code change in repos of other microservices, infrastructure changes, configuration updates, 3rd party updates and more.
This is frustrating since it renders developers with less and less control over how their code performs. Many developers leave this to DevOps, expecting them to figure out how to ensure their code works in production, instead of just on the local machine.
This reality slows down the development process. This is not good for developers, who lack autonomy and their velocity is impacted. It is also not good for DevOps, who are tied down to trivial day-to-day tasks (like creating configuring security groups, creating S3 buckets or increasing the resources of a DB instance) instead of working on more strategic tasks that require heavy lifting. Finally, it is not good for companies, since it significantly impedes time-to-market.
Developer Ownership to the Rescue
Surprisingly, this piece is not going to claim that the solution is a certain tool or technology. Instead, I believe the right approach is changing the way developers approach their code and the development process.
Instead of signing off once they finish writing the code, and passing it on to QA (for testing purposes) or DevOps (for deployment purposes), I believe developers should be taking ownership of their code – from their IDE all the way to their customers, as much as they can. By understanding the core technologies they are using and being responsible for the code from the moment it is typed onto their IDE and until it is being used by customers, developers can ensure that it really works – wherever it runs, and however it’s used.
This is essentially the idea behind what we’re seeing in security, DevOps and testing, which are empowering developers to shift left their capabilities that were once owned by security, DevOps or QA engineers. Instead of relying on other teams, developers are now owning these processes and delivering code that is ready from a quality and security perspective.
Developer ownership provides:
- Velocity – Developers can move faster since they can move more independently than before.
- Higher quality features – When developers own their code end-to-end they ensure features will work across all use cases and at all times.
- Stability and scalability – If developers don’t sign off after writing their code they will ensure that the code is stable in production, meets performance SLAs, and can be used by users.
- Professional development – Developers who extend their daily work to ensuring their code is properly deployed and production-ready, and works in production, expand their skill set to additional capabilities, technologies, practices and tools. This helps them improve themselves as developers and also opens them up to new opportunities.
Developers vs. DevOps: What’s Left for DevOps?
But wait, what about DevOps? Contrary to what you may be thinking, developer ownership does not make DevOps redundant. On the contrary – empowering the software engineers means DevOps professional can focus on long-term, strategic processes that are not in the scope of the every tasks of developers. This includes:
- CI/CD optimization
- Optimizing database and messaging clusters
- Managing Kubernetes clusters
- Cloud cost optimization
- Evangelizing new technologies
- Owning compliance and security processes
How Developers Can Take Ownership
It’s true what you might be thinking – taking ownership requires developers to go beyond their day-to-day and to put in that extra effort into expanding their horizons. From my experience, however, it’s something that most developers enjoy, if they’re given the chance, and it’s a win-win for both the engineer and the organzation in the not-so-long term.
How would one get started? Start from the next feature you’re building. Make sure you understand everything about it – where would the code changes need to be applied, but also what are all the upstream and downstream components that are involved. How do they communicate (synchronously/asynchronously)? What’s the impact of my change on this communication? What would be the most efficient and compact way of testing it (unit tests / component test / e2e test)? What observability tools (tracing, logging, metrics) tools are available for you? Try figuring out what data is available to you, and what’s still missing. You may find OpenTelemetry (OTel), for example, as a useful tool which could help you make sense of all of these questions – I believe it could become and important bridge between you code and your infrastructure.
Cloud infrastructure, scalability, and a talent shortage have turned the DevOps position into the holy grail of engineering recruitment. But in many engineering organizations (usually smaller ones), developers can take on most of the activities and responsibilities DevOps has. This is not only a way to bridge a gap, it is actually better for the organization and the developers themselves, ensuring higher quality code and higher velocity – which is what everyone is aiming for.