Silence is better than unmeaning words.
Over the time I’ve been programming, I’ve come to value certain things in a code base. Without going into too much detail (which will probably be its own post soonish), I value code that is easy to understand and manipulate.
The first level of understanding, which is facilitated by the style and organization in a code base is ‘What’. If I can look at code and mentally map ‘What’ it is doing, I start to get a level of productive joy. I can’t get that if I’m trying to sort out which branch of the if-else plinko, meta-scrambled self.foo or side effect driven development is actually getting executed at any given moment. ‘What’ is really really nice.
A higher level of understanding code is ‘Why’. ‘Why’ is more subtle, but orders of magnitude more powerful than ‘What’. ‘What’ is a technique, ‘Why’ is the purpose, the driving principle. Understanding ‘Why’ gives flexibility and options to ‘What’. (Unfortunately, most code does a poor job of conveying ‘What’, let alone ‘Why’, but that is a topic for another day.)
Which brings me to ‘semantics matter’, which is something I’ve heard Luke say over and over when talking about Puppet. When I heard him before, I just nodded and thought he was talking about nifty Puppet language features like ‘after’ and ‘subscribe’ for managing relationships between services and the underlying packages and config files, because that was what he was using as the example. I was understanding the ‘What’ level.
You think I would have figured this out faster after listening to Luke rant about it so much, but the whole ‘semantics’ thing didn’t click until a discussion with Teyo about preparing for his ‘Golden Images’ talk at Linux Plumbers Conf.
Puppet let’s one model system configuration with code. Just like any other language, the ‘What’ and especially the ‘Why’ can be made apparent if the code is organized in certain ways and/or if one shares certain metaphors with the original author.
Until quite recently, I was having a hard time understanding why rebuilding virtual images with Puppet was superior to just versioning working images. I mean I heard the words, but in my mind I was questioning the practical difference. In one case you start with a base image, get everything set up and save the working copy, in the other you start with the base image and let puppet build it up. I kept thinking to myself, what is the difference, both solutions end up in the same place, right?
Being afraid to turn off real machines where you have no idea what is running, because there might be some critical cron job that matters on the third Tuesday of the month is one thing… (this happens, for real, some of you know this is true, someone reading this works at places like this right now, guaranteed), but once everything is virtual and running what you want, what’s the harm of just making images?
The difference is the potential to encode ‘What’, and if your code is sensibly organized, ‘Why’.
I was only seeing the static state of the working system. What if you want to change things? If you have working images, you have to reconstruct ‘What’ by discovery, good luck with ‘Why’. If you are lucky, it was you that set up the systems and it wasn’t over 6 months ago. The ‘What’ and ‘Why’ were apparent to someone, potentially you, when the systems were first set up, but now you just have this bucket of bootable bits that ostensibly does something. If it isn’t working, or there is a need to change something significant, the choice is poking around the bucket of bits until the new ‘What’ is in place or starting over with a new ‘Why’ that is lost as soon as the new image is finished.
If Puppet is building your services, ‘What’ and ‘Why’ can be recorded, clarified, recovered and manipulated. Version control becomes straight forward, manageable, and transparent. Services can have clear definitions and relationships. So obvious… can’t believe it took me this long to ‘get it’…
How many 500 MB images do you want to version? Can you make any sense of the diffs? Really? Seriously?