Some DevOps Practices
This is another one of my opinionated rants. Over two years working in DevOps, I’ve seen both good and bad practices. Everyone has a different understanding of DevOps, and in this post I’m simply sharing my own perspective — please feel free to correct me where I’m wrong.
Broadly speaking, I follow three principles:
- Zero manual operations.
- Keep it clean: the Boy Scout Rule.
- Keep it simple: Occam’s Razor.
Zero Manual Operations
What is a manual operation? Any resource or action that has not been codified (as code) can be considered a manual operation.
Common examples of manual operations:
- Infrastructure that is not codified — resources exist that are not managed by code, or certain operations are not captured in code.
- Application deployment processes that require manual intervention.
- Application configuration that must be specified manually.
Do You Really Need to Do It Manually?
Before performing any manual operation, ask yourself a series of questions:
- Has this operation already been codified (as code)? If yes, execute the code. Don’t let your own code gather dust in a corner. If not, move on to the next question.
- Is this operation urgent? If it is, a temporary manual operation may be acceptable, but it should involve multiple people and follow a strict process. Afterwards, the operation must be codified. If you’re reluctant to codify it, work through the following questions.
- Is there a chance this operation will need to happen again in the future? If so, it needs to be codified. If you’re still reluctant, move on to the next question.
- How can you guarantee that the next time this runs (whether a week or a month from now) it will reproduce exactly what you did today? Any manual operation is non-auditable and cannot be fully reproduced. If you can’t guarantee that, it needs to be codified. If you can guarantee it, then you’re a genius and I bow to you.
- We have thorough documentation — do we still need to codify it? Code is more reliable than documentation, and well-written code is far more readable than a doc.
Practices for Avoiding Manual Operations
- Infrastructure as Code (IaC)
- CI/CD
- Automation scripts
- GitOps
Keep It Clean: The Boy Scout Rule
The Boy Scout Rule: Always leave the campground cleaner than you found it.
Cleanliness can be discussed from two angles: clean code and clean environments. The Boy Scout Rule — leave the campsite cleaner than you found it — is an extremely applicable guideline.
Clean Code
The “code” in clean code refers not just to business logic, but to everything: test code, infrastructure code, and all other code. I’ve seen projects where the business code is well-written but the non-business code is a mess. Why does this happen? My best guess is that the team doesn’t treat infrastructure code as real code, and has strategically overlooked it.
All code deserves equal standing. Whether it’s business code or not, we need to maintain it throughout the application’s lifecycle.
On this topic, I strongly recommend reading Clean Code and Refactoring.
Clean Environments
During development, keep the development environment clean.
In the CI/CD environment, keep the build, test, and deployment environments clean. Typically, a CI/CD agent is shared by more than one application, which makes maintaining a clean environment especially important.
In production, keep the runtime environment clean.
Practices
- TDD
- Simple Design
- Containerization
- Code Diff
Keep It Simple: Occam’s Razor
Entities should not be multiplied unnecessarily
While writing this post, I kept going back and forth on whether to merge “clean” and “simple” into a single section. When I talk about cleanliness, it’s the opposite of messiness — it generally refers to whether code is well-organized. Simplicity, on the other hand, is the opposite of complexity, and is usually associated with business logic, architecture, and technology stack choices.
Whether business logic is complex or not comes from functional requirements; I haven’t done deep research on that side, so I’ll leave it aside for now.
The complexity of architecture and technology stacks comes from non-functional requirements. Every project experiences team turnover, and during those transitions, complex things are easily distorted as they are passed along. When introducing a new technology or programming language, you need to carefully consider whether it is truly necessary — if it isn’t, don’t bring it in. In short, follow Occam’s Razor: entities should not be multiplied unnecessarily.