Do this instead:
1. Use flat yaml files. No loops nor conditionals, no complexity.
2. One (single) yaml file templated by ansible just for secret/sensitive stuff.
3. Done.
Boring is better and is easy to diff.
Do this instead:
1. Use flat yaml files. No loops nor conditionals, no complexity.
2. One (single) yaml file templated by ansible just for secret/sensitive stuff.
3. Done.
Boring is better and is easy to diff.
I mention all this to illustrate that we are nowhere near NetAppAmaGooSoft scale. Nevertheless our deployment is complex. We can't just have a few hundred identical machines. There are many heterogenous parts, and they have to be hooked up to each other. We currently do this with ~20K lines of HCL applied with Terraform. It's mostly written by some hella-smart infra engineers, and is very well factored.
Still, it's a BEAST. The Terraform Enterprise workflow is tedious, and writing configuration is a lot of work. We would love to replace it, with ...something better. There are alternatives out there, but nothing that's obviously much better. It wouldn't be worth the migration effort. As far as I can tell, this is the state of the art, and it sucks.
My coworkers are sick of hearing me say "We are not Google", so I'm sympathetic to the YAGNI argument, but there really is a problem here. Flat YAML files would be a nightmare for us. I bet there are a lot of companies out there that have worse solutions than we do. The default of "each team rolls their own ad hoc deployment tools" masks it somewhat because it's not obvious that the company has 17 solutions to the same problem, with varying levels of effectiveness and reliability, all of which are expensive to write and maintain, and none of which will be reused when a new team gets organized.
Terraform is a valiant attempt to solve the problem with middling results. We can do better, and we need more attempts! I'm excited that CUE exists. It's not ready for my use case yet, but it's very promising. The best thing about it is that it scales well, up and down. If you have simple needs, you can just write flat CUE to start. It's just JSON with some syntax sugar. The fancy stuff can come later, but it's there when you need it.
I do prefer to have lots of dumb files than having to deal with the cognitive load of a tool that in the end will generate lots of files anyways.
I'm going to chew on this. For me, Don't Repeat Yourself has been one of my highest values. My former colleagues would copy and paste code everywhere. It was a pain to make changes to, and I relished refactoring it.
But I also regret some of the libraries I wrote in my early years. They aren't designed how I would today, but now several applications depend on them.
One thing I will say is that it's okay for your first draft to be ugly. It helps to see all the duplication before you design the abstraction.
Obviously if there is a manageable way to reduce repetition, take it, but I would not add a lot of complexity for the sake of brevity. That's turning your dev team into a data compression algorithm made of meat.
I've been jokingly pushing for over-application of syntax-focused DRY to be called "Huffman coding"
I was just arguing that adding a lot of complexity to reduce duplication is an exercise in diminishing returns pretty fast.
I used to say "less complexity" but I've found that even for me, sometimes when I do something that seems simple and less complex, it ends up requiring more cognitive load (it's not descriptive enough, or it tries to do too much "magic", etc).
When you treat configuration as flat files your configuration becomes a 1:1 mapping of the thing you have running.
I won't speak to which is "really" DRY, but I think the original formulation is more useful. The more typical focus on surface syntax misses out in two respects.
First, a single piece of knowledge might be represented in multiple places even when they look different. For instance, if I'm saying "there's a button here" in HTML and in JavaScript and in CSS, there won't be any syntactic repetition but that's not DRY per TPP.
Second, just because there is syntactic repetition doesn't mean you're encoding the same piece of knowledge. Sometimes two pieces of code happen to be the same, but each looks that way for different reasons and are more likely to change independently than together. In that case, unifying them isn't DRY (per TPP). I joke that you're not improving that code, simply compressing it.
I think that original formulation is pretty spot on, although even then would note an exception for deliberately saying important things in different ways for error detection and clarity, but only if they are actually checked against each other.
If you're throwing it all into a docker container as a single artifact you don't need a separate language to patch into a complicated config parser. Just use hardcoded objects/maps in whatever language you use.