Configuration as Data
The core concept underlying ConfigHub is Configuration as Data.
Background
In ConfigHub, configuration is represented, stored, and managed as data. It is serialized using standard data formats, such as YAML, and stored in a database within ConfigHub. Code that operates on configuration is separate from the data, and the data is the source of record. Configuration data is not parameterized. It contains literal values for every field in the configuration.
This is in contrast to Infrastructure as Code (IaC), which represents configuration as code or in a code-like format and is stored and managed as code in source control systems, and frequently deployed via Continuous Integration (CI) pipelines or GitOps tools.
ConfigHub enables configuration updates and queries to be performed via API rather than code-oriented processes and tools. The configuration data is not in git for similar reasons that database tables aren't maintained as templates or programs in git that generate CSV files.
Example
IaC
Take Helm as an example. There's a detailed walkthrough of a relatively simple case in this blog post, but here's an even simpler, common one.
Let's say you want to automatically update a container image tag to rollout each new release of your application. You'd template that field of the Kubernetes Deployment something like this:
containers:
- image: {{ .Values.deployment.main.image }}
And add a parameter to the values.yaml file for that environment like this:
deployment:
main:
image: ghcr.io/myorg/myapp:release12345
Now if you wanted to set that image automatically in CI/CD, there are a few common approaches:
- You could set it on the
helm upgradecommand line with--set "deployment.main.image=ghcr.io/myorg/myapp:$TAG". - You could use
yq,sed,awk, or a similar tool to change thevalues.yamlfile:yq -i ".deployment.main.image = ghcr.io/myorg/myapp:$TAG" values.yaml - You could template the
values.yamlfile and useenvsubstor similar tool to set the value from an environment variable. - You could write a file that set just that one input value, and use it to override the value in the main
values.yamlfile.
In any of those cases, the new image value wouldn't normally be recorded or versioned. To do that, an updated values.yaml file would need to be committed back to git. That is often done manually: clone or pull, branch, edit, commit, push, review, merge.
Also, because the Helm chart template syntax is no longer just YAML, it's hard to check it for correctness. It could be misindented, contain invalid properties, specify invalid values, be templated incorrectly, violate organizational policies, etc. It needs to be rendered to YAML first using helm template. The output can then be run through validation tools like kubeconform and/or policy tools like kyverno.
Then if a problem is found, it needs to be traced back to the template and/or values, and fixed manually due to the unidirectional approach of IaC and the lack of an explicit relationship between deployed resources and the configuration sources. The change can't be made directly to the clusters or other systems under management because such changes are considered to produce undesirable drift.
ConfigHub
On the other hand, with ConfigHub, the full standard Kubernetes Deployment YAML would be stored, including the image.
apiVersion: apps/v1
kind: Deployment
...
containers:
- name: main
image: ghcr.io/myorg/myapp:release12345
Then to change the image, you can just do:
cub function do --unit myapp set-image main "ghcr.io/myorg/myapp:$TAG"
And the change is stored, versioned, and validated automatically. You don't need to deal with complicated templates. You don't need to worry about messing up the YAML indentation. You don't need to perform 10 git commands to make a one-line change.
If you want to search for where a specific release was deployed, you could do something like:
cub unit list --space "*" --resource-type apps/v1/Deployment --where-data "spec.template.spec.containers.*.image#reference = ':$TAG'"
If you're thinking, "but I prefer code to YAML," you can write your own functions, like set-image, to perform common transformations. And not only to perform transformations, but also to validate or introspect configuration. For instance, you can get the current image value with a function:
cub function do --where "Slug='myapp'" get-image main --output-values-only
One way you can think of functions is as mini tools to perform common configuration tasks. They can be single-purpose, like set-image and get-image, or multi-purpose, if desired. It's up to you.
You can also write or read configuration data through client surfaces (GUIs, CLIs), other tools, and automation external to ConfigHub.
The configuration data can be queried, analyzed, and updated through interoperable, reusable automation, individually and in bulk.
Conclusion
ConfigHub provides the database, API, and SDK to unleash your automation of configuration data.