The Tao of DevOps : Building things
The principles of Tao can be applied to almost anything, as evidenced by for instance Fritiof Capras "Tao Of Physics" and Benjamin Hoffs "The Tao of Pooh".
Tao applies well to DevOps because who knows what DevOps is? It is an idiom as hard to define as quality, and indeed DevOps is closely tied to the quality of the product.
What is Tao then? One way of putting it is that things go better if one finds the natural way of doing things and do things that way.
A recipe for cooking a dish normally starts with a list of ingredients, because that's normally the most efficient way of describing cooking.
For instance, when making a simple desert, the recipe starts with a title "Strawberries And Cream; a Delicious desert". Already from the title we can infer a number of steps in making the dish. We must acquire strawberries and cream, and probably put them together on a plate. The recipe will continue to describe the preparation of the dish in more detail, but even if we read only the heading, we will make very few mistakes.
The observation here is that when putting things together, when building things, the intuitive and natural way to describe the process is to do it declaratively, that is, describe the "whats" rather than the "hows". The "hows" can be inferred.
I'm not claiming that this is always the case, only that its a natural way to think for humans. For instance, the DNA code that builds us is an imperative form of code, but when trying to understand DNA we often think of it as declarative.
Now lets discuss the Tao of building software.
Most build tools have at their core a way of declaring relationships between software components. Here's a Make snippet:
1a : b
2 cc b
And here's an Ant snippet:
1<build>
2 cc b
3</build>
And a Maven snippet:
1<dependency>
2lala
3</dep>
Many people think they wound up in a Lovecraftian hell when they see XML, even though the brackets are perfectly euclidean. What you need to do is squint hard enough, and you will see that most tools at their core describe dependency trees.
Maven is a well known tool very explicit about the declarative approach, so we will focus on maven, and try to find the Tao of maven.
When we are having a good day with maven, when we are following the ways of Tao, we describe what type of software artifact we want to build, and what the components we are going to use to put it together. That's all. The concrete building steps are inferred.
Of course, since life is interesting and complex, we will often encounter situations were the way of Tao eludes us.
Consider this example:
1type:pom
2
3 antcall
4 tar together ../*/target/*.jar
Although abbreviated, i have observed this antipattern several times in real world projects.
Whats wrong with it? After all, this antipattern occurs because the alternatives are non-obvious, or more verbose.
First of all, notice that we are not describing, whats, at least not in a way that Maven can interpret, we are describing hows.
Fixing this will probably require a lot of work, but in any larger build we will eventually have to fix it.
Here you might pause and consider that dependency trees are already described within the code of most programming languages. isn't the "import" statement of Java and Python, etc, enough? In theory, for code, yes, if we disregard the dynamism afforded by Java, where it is possible to construct a class name as a string and load it. In practice there are a lot of different artifact types that might contain various resources.
Even so, it is clearly possible in theory to package all required code if the language just supported it. Jsr 294 "modularity in java" is an effort to provide such support at the language level.
To summarize:
- When building things, focus on the "whats" before the "Hows"
- Work with the tool rather than around it.