Traditionally, documenting software architecture involves creating static diagrams and design documents that describe various aspects of the system, such as its structure, behavior, and deployment. Traditional documentation methods often fall short when it comes to keeping up with the pace of development.
Problems with the traditional approach
- Static, stale and hard to maintain: As the system evolves, these documents often become outdated, leading to inconsistencies between documentation and actual implementation. Keeping the documentation up-to-date is challenging for busy teams.
- Tribal knowledge: Many aspects of the system may be known only to a few individuals, making it difficult for new team members to get up to speed. Oftentimes, this knowledge goes away with the employee, leaving a gap in understanding of the system.
- Reinventing the wheel: Teams may implement their own solutions to common problems, unaware that other teams have already solved the same issue.
Our philosophy: architecture-first approach
We believe that architecture documentation should be single source of truth. Any new change, either in terms of software or infrastructure, should be made in the architecture and then percolate down to the environments. This approach promotes consistency, reusability, and a better understanding of the system's overall design. In order to achieve a mature DevOps process, we need to enable both, Devs and Ops, to make changes in architecture with proper guardrails. We accomplish this by following these three core principles:
1. Consistent language
We propose using a Structured Architecture Requirement Language to formally describe the system architecture. It also helps in modularisation and reuse, accelerating the entire development process and promoting a cohesive user experience.
2. Architecture as single source of truth
Architecture documentation needs to be the single source of truth for deployments. Everyone can use the common protocols to make changes to architecture, preventing any isolated changes in environments. This also enables powerful things like audit, versioning and rollback.
3. Automation
With recent advancements in cloud SDKs, Kubernetes and Terraform, standardization of well-architected principles, we now have the possibilities to introduce automation for infrastructure provisioning and configurations taking the blueprint as an input. Manual operations or custom automations are time consuming and error prone.
To understand different levels of DevOps maturity, let’s Imagine that a new product is being developed and it requires deployment of a few microservices. It also requires a MySQL database, with backups, read/write optimisations and other fine tuned configurations.
In the traditional approach, Devs will raise a request with the Ops team to provision infrastructure for them. To accomplish this, the Ops team will leverage some scripts and manual steps after understanding the requirements. With this approach:
- Architecture documentation is not updated and soon becomes stale.
- Developers rely on Ops team for architectural changes.
- Manual/automated deployment by Ops team can cause inconsistencies.
If we consider an evolved DevOps process for the same, then both Dev and Ops team read from and update the architecture document. Devs will add their requirements in architecture and Ops will provision the required items using a combination of scripts and manual steps. This solves the problem of stale architecture, however manual steps and scripts still present the same sort of issues with inconsistent deployments.
As the DevOps process reaches maturity, architecture acts as a single source of truth for automated deployments. In this case, Devs can still add their requirements to architecture, but the provisioning is taken care of automatically, freeing up the Ops team and reducing any risk of manual errors.
Possibilities beyond provisioning infrastructure
We propose that architecture should not be limited to infrastructure and micro-services. Things like alerts, observability, monitoring, CD pipelines, database schemas etc. should also be part of architecture.
A uniform and automated way to plug in alerts to any service, or enabling APM, or setting up a new CD pipeline, possibilities are endless here. Enabling developers with a self-service model for infrastructure requirements also empowers the DevOps team to take on bigger challenges like cost optimization, disaster recovery, compliance, cloud posture, optimizations and security, resulting in overall improvement at organizational level.