Code As UI: The UX of config-as-code and everything-as-code
Welcome to the UI review
Your UX person comes up to you with the new mocks for the configuration UI. It looks like this:
You: What is this? Is this modern?
UX: That’s be beauty of it. The user can type in the label and type in the value.
You: And how would they know what the labels are and what valid values are?
UX: We will write some documentation on what the labels and values should be.
You: What about validation?
UX: Hmm. That would be nice. But the UI doesn’t really know what the valid values are.
You: Come again?
UX: The UI is neutral. Again, the valid labels and values are documented.
You: Is it a good document?
UX: Let’s not get ahead of ourselves.
You: Is it a single document?
UX: We are thinking more along the line of leaning into crowd sourcing. Like there will be some documentation, but really the labels and values are consumed by the backend. We don’t really have much control of that.
You: So, the backend is responsible for keeping the documentation up to date? How has that worked out before?
UX: Not great.
You: So, any good news here? Why are we doing this?
UX: Because it’s config-as-code. It’s the new hotness.
You: Say no more fam.
So here’s the thing. Config-as-code isn’t new. That’s how it was
before any GUIs existed. Anyone hows configured an old OS, and some new
ones, will tell you that the only way some parts can be configured is by
editing text files; sometimes using an esoteric editor called
Then there was a glorious age of GUIs. At some point they started treating developers and sysadmins like real people. You might not believe this, but they even did user experience testing to make sure those sysadmins’ lives were as easy as possible. It was glorious.
And now, what’s old is new again.
There are in fact good reasons for config-as-code. Here’s a few:
No more opaque configuration.
Fancy UIs often mean that the configuration data goes straight into an opaque configuration store somewhere. Sure it will come around and affect the behavior of whatever it was that is being configured. But that stuff usually doesn’t involve the user.
Usually the the platform doesn’t have much reason to keep configuration a secret. So there will be some schema and some method to storing and querying the configuration.
However when it comes to third-party or hosted services, this is not always the case. The how the configuration is stored and how it is reified into behavior is opaque.
With configuration-as-code (Can I call this CaC? That’ll be more convenient.) the user is in control of storage. How else would they write it down? The schema must necessarily also be made available to the user.
All the controls of source code.
Anyone who’s written some source code and used some source control tool will tell you how useful source control can be.
Almost trivially you get:
History and all that comes with it like the ability to revert back to known good states.
Blame/Praise and attribution of changes to specific authors – assuming there’s sufficient authentication and authorization in place.
Reviews/Approvals that verify that the changes were correct and appropriate.
Unless someone can be mandated to stand behind you and look over your shoulder taking notes, none of that comes for free with a sysadmin at a GUI.
Audits, validation, automation.
Follows from the above. Now that the configuration is inspectable and understandable, it is easily amenable to automation and validation.
One could argue that this was always the case. However, now the user is empowered to do so with the same fidelity as the authors of the system.
And the cons
The things that need fixing is usability.
We spent decades saying Fitt’s law this and “recognition over recall” that, and then threw everything away. It’s time we put all that experience into action.
Just because the configuration is in text files doesn’t mean that it has to be authored that way. Even if it did, it is still possible to substantially improve the UX there.
Why do people enjoy Mad Libs but wouldn’t enjoy writing the same content from scratch? The answer is “recognition over recall”.
We can have the format and options documented somewhere and have the user consult the document at every step of the way. This sound reasonable at first. So people write things like “read all the documentation carefully before attempting to configure the thing.”
But the amount of information that a human being can keep track of at a given time is limited. What it ends up being is a tiresom sequence of flipping back and forth between reference and implementation.
Making things better
It turns out we already have some ideas on how to fix this, because the same problems plague software engineering. Or I should say the other areas of software engineering.
Here are several approaches I’ve seen in practice that make config-as-code more bearable.
Pretty much the only useful development in coding in the past several decades is autocomplete. A good schema along with documentation can make a huge difference. Try editing the VS Code settings file to see it in action.
As the Mad Libs example shows, templates are much easier and more expedient than a blank empty document.
Other examples of templates include:
But templates in general only work the first time. So subsequent edits to the configuration will have to contend without the help of a template. This is a biggie since configurations can’t be updated when updating their corresponding templates.
We once used to have WYSIWYG UI editors. Now we have to write our UIs as code in one of any number of frameworks that in turn try to reduce the toil of writing UIs. It doesn’t have to be this way.
At least for configuration, just because the configuration is written down as code doesn’t mean it has to be edited as code. The same UIs that we once used can still generate those text files.