Every Sufficiently Advanced Configuration Language Is Wrong
matt-rickard.com
matt-rickard.com
The industry is going to great lengths to avoid writing configuration in any ubiquitous imperative programming language. We're seeing the proliferation of hyper-specialized, clunky declarative languages with sub-par tooling and package ecosystems. In what world are templates acceptable code? I don't mean to pick on anything specific, but this[0] is the most recent example I've come across, and it's far from the most unreadable examples.
[0]: https://github.com/traefik/traefik-helm-chart/blob/master/tr...
So for example the application should always take a JSON blob, or some other simple format.
However the user will likely want to generate their configuration form something with the ability to control complexity like Jsonnet, CUE or just Python.
IMHO this kind of audit is useless because even if one option has the expected value what guarantees do you have that this option is used as expected? Well you have to audit the code!
This is the only way to be sure you're auditing what you think you're auditing, and it doesn't matter what kind of provisioning tool you've used.
"Its supposed to be state and not a procedure" is BS in my experience. When you need to do IFs, load vars, do things in order anyways...it stops being a state declaration.
I've been been using it for a couple personal projects, and I really like it.
Note: I am python-fanatic with 15y experience.
Also: complex cases will likely result in complex code. Do you have a viable alternative for this?
> Do you have a viable alternative for this?
My imperative Fabric 1k line deploy scripts in the past allowed to encapsulate complexity because I had remote state on hands.
There ought to be some way to export the data structure definitions those things parse to, and then generate go/python/whatever bindings with IDE support for people that want to programmatically manipulate the config files.
Something like ~/.ssh/config is closer to what I am talking about.
Most imperative programming languages aren't quite a natural fit for declarative management of resources because the general loop of how the tools work is functional evaluation of the declarative statements to instantiate the desired states of all managed resources, a reader to get the current states of managed resources, a dependency solver to help order the plans, a differ to produce a plan of what needs to be changed detect and show what will need to be changed, and finally the applicative layer to modify/create/delete managed resources by executing plans against APIs. This is a pretty functional model at every step (except perhaps plan execution, but in theory all executions should be modeled as edges on state machines of valid possible configurations and not as a spaghetti of if/then http/bash invocations) and so while it's certainly possible to implement configuration in imperative languages I think it will almost always fit functional languages a bit better.
I haven't implemented anything better than the current crop of tools, so take this with a pinch of salt I guess.
Instead of a language, it was a schema for configuration statements. You edited the schema to add new launch commands, then added launch commands to the script.
It was pretty esoteric - used all three kinds of braces to express one-of, required, optional etc. The only person I knew who changed it other than me was Andrew Thurber (the one at Cisco). He was a new hire at the time, and I was startled to find he'd just read the schema-parser code and figured it out.
Anyway not sure how that approach fits into the OP's objections.
Declaring constants, lists, dicts, etc can be basic config, that is an importable python module.
Advanced config can be functions or some constructs around code that the program packages into a module during runtime.
I am looking at you, Postfix `main.conf` and ISC Bind9 `named.conf`.
Damn near unauditable by machine code.