If you attended FluxCon at KubeCon North America 2025, you probably saw Erick and Alexis discussed a new approach to GitOps called Configuration as Data.

In earlier posts, Brian Grant, our CTO, has introduced ConfigHub’s Configuration-as-Data approach: the practice of storing fully rendered, literal configuration in a database rather than managing templates in Git repositories. This philosophy treats the authoritative source of record as structured data that can be queried, validated, and manipulated through APIs.

But this raises an immediate, practical question: What about Helm charts? The Helm ecosystem contains thousands of pre-packaged applications, and countless teams rely on it for deploying complex systems like cert-manager, Prometheus, and Istio.

The challenge is clear: Helm charts are parameterized templates - the opposite of Configuration as Data. Yet, abandoning Helm means losing access to a vast and valuable ecosystem. So, how do we bridge these two worlds?

The Problem with Traditional Helm Workflows

A traditional Helm workflow is an exercise in ephemeral generation. A command like this is typical:

helm install my-app my-repo/app --set image.tag=v1.2.3 -f values.yaml

This command performs a sequence of actions:

  1. Fetches the chart from a repository.

  2. Renders the templates with your specified values.

  3. Applies the resulting manifests to your cluster.

  4. Stores the rendered output as inventory information in the helm release.

The rendered manifests, the actual configuration that runs in your cluster, are temporary artifacts. They are regenerated every time you run helm upgrade. Want to query what image tag is running across all your environments? You can’t ask about or see the configuration directly. You must re-render each chart with environment-specific values and then parse the output, or look the chart up in the cluster. This is the essence of the Infrastructure-as-Code (IaC) model: the templates are authoritative, and the generated artifacts are throwaway.

The Rendered Manifest Pattern

ConfigHub takes a different approach for managing a Helm application’s lifecycle by separating the rendering and application phases. We use Helm for what it excels at — rendering charts — but we treat the rendered output as the authoritative configuration data. This is the Rendered Manifest Pattern, where our experimental Helm Applier ensures full fidelity with the Helm lifecycle by using the official Helm SDK to drive the apply process and natively processing Helm hooks.

Phase 1: Render and Store

The first step is to render the chart and store its output as structured data.

cub helm install \
--namespace cert-manager \
cert-manager \
jetstack/cert-manager \
--version v1.17.1 \
--set installCRDs=true

Under the hood,cub helm installperforms these steps:

  1. Uses the Helm SDK to locate and load the specified chart.

  2. Merges your values from files and--set flags.

  3. Renders the chart’s templates into literal YAML manifests.

  4. Stores these manifests as versioned “config units" in the ConfigHub database, not in Git.

  5. Attaches metadata from the Chart.yaml as queryable labels on the config unit.

The crucial difference is that the rendered manifests become first-class data objects, complete with revision history and a rich API for management.

Phase 2: Apply with Helm Semantics

Once the configuration is stored, you can apply it to your cluster.

cub unit apply --where "Labels.HelmRelease='cert-manager'"

The HelmApplier (implemented using our public SDK) takes the stored manifests and uses the Helm SDK to drive the apply (and later destroy) process. This ensures full fidelity with the Helm lifecycle:

  • It uses the same install, upgrade, and uninstall mechanics as the Helm’s CLI.

  • It correctly executes pre- and post-install hooks.

  • It performs garbage collection to remove orphaned resources during upgrades.

  • It stores release metadata in Helm’s own storage backend.

  • It fully supports rollbacks via ConfigHub revision restore.

This correct execution of hooks is critical. Hooks are a powerful Helm feature that allows chart authors to run imperative jobs at specific points in a release’s lifecycle, such as running a database migration before an upgrade (pre-upgrade) or backing up data before deletion (pre-delete). Many of the most popular and complex charts in the Helm ecosystem rely on hooks to manage their stateful deployments. By natively processing hooks using the Helm SDK, ConfigHub ensures compatibility and automates these complex rollouts, something that would not be possible if it only applied the manifest files.

This is not a re-implementation of Helm. We are leveraging the official Helm libraries (helm.sh/helm/v3/pkg packages and v4 in the future). The key distinction is our source of truth: we feed pre-rendered, authoritative manifests into Helm’s application logic instead of rendering them on the fly.

The Power of Configuration as Data

By treating Helm charts as data, you unlock a host of capabilities that are cumbersome in a template-based workflow:

Query Across All Environments

You can now ask detailed questions across your entire configuration landscape without rendering anything.

# Find all deployments using a specific nginx image
cub unit list --space "*" \
--resource-type "apps/v1/Deployment" \
--where-data "spec.template.spec.containers.*.image = 'nginx:1.21.0'"

Or something like:

# Check cert-manager chart versions across all environments
cub unit list --where "Labels.HelmChart = 'cert-manager'" \
--jq '.[] | {space: .Space.Slug, unit: .Unit.Slug, version: .Unit.Labels.HelmChartVersion}'

Perform Bulk Operations with Confidence

ConfigHub implements resource dependencies, even across different Helm charts, via links.

# Install multiple charts
cub helm install --namespace monitoring prometheus prometheus-community/prometheus
cub helm install --namespace monitoring grafana grafana/grafana
cub link create - grafana prometheus

# Apply them all at once in the correct order
cub unit apply --where "Labels.HelmChart IN ('prometheus', 'grafana')"

Its built-in dependency manager ensures that Prometheus is applied before Grafana if a link exists.

Validate Before You Apply

A benefit of treating configuration as data is the ability to validate it against policies before it is ever applied to a cluster. Since the rendered manifests are stored directly in ConfigHub, you can run sophisticated checks at any point in the workflow, catching errors and policy violations early.

With ConfigHub, you can define validation rules using Common Expression Language (CEL). These triggers can be set up to run automatically whenever a configuration changes. For demonstration purposes, we’ll create them and run them manually.

First, let’s define a few common validation policies as triggers for our production environment:

cub trigger create --space prod \
replicated Mutation Kubernetes/YAML \
--vet-celexpr 'r.kind != "Deployment" || r.spec.replicas > 1'

cub trigger create --space prod \
no-privileged Mutation Kubernetes/YAML \
--vet-celexpr "r.kind != 'Deployment' || (r.spec.template.spec.securityContext.runAsNonRoot == true && r.spec.template.spec.containers.all(container, !has(container.securityContext.runAsNonRoot) || container.securityContext.runAsNonRoot == true)) || r.spec.template.spec.containers.all(container, has(container.securityContext.runAsNonRoot) && container.securityContext.runAsNonRoot == true)"

cub trigger create --space prod \
resource-limits Mutation Kubernetes/YAML \
--vet-celexpr 'r.spec.template.spec.containers.all(c, has(c.resources.limits))'

Then, test the policies against all config units labeled with “HelmChart” key.

# Run the validation pipeline
cub function do --space prod \
--where "Labels.HelmChart = 'prometheus'" \
--trigger replicated,no-privileged,resource-limits

Make Targeted, Environment-Specific Changes

Overrides no longer require complex values.yaml files or templating logic. A simple API call or edit is all it takes.

# Update container resources for the production app
cub function do --space prod \
--unit app \
set-container-resources app all 500m 1Gi 2

Each environment’s configuration is independent and literal, eliminating the risk of a change to a shared template accidentally affecting an unrelated environment.

Bridging Two Worlds

The experimental Helm Applier and the Rendered Manifest Pattern offer a powerful synthesis: they allow you to leverage the vast Helm ecosystem without compromising the principles of Configuration as Data. It’s not about replacing Helm, but rather about elevating its output from an ephemeral artifact to a first-class, manageable data asset.

In addition, Configuration as Data used by ConfigHub allows configuration management with its Bidirectional GitOps approach, moving beyond a simple one-way push to keep your stored configuration perfectly synchronized with the live cluster. This powerful workflow allows you to refresh the state of live resources and automatically patch any manual, out-of-band changes, such as those from “break glass” scenarios, directly back into the stored manifests. By preventing configuration drift, ConfigHub ensures that the pre-rendered manifests remain the genuine source of truth, creating a more resilient and realistic model that masterfully balances declarative control with operational flexibility.

Brian Grant and Alexis Richardson will be talking about Configuration as Data at KubeCon. And you don’t want to miss it!

KubeCon + CloudNativeCon North America 2025: GitOps Without Variables - Brian Grant &... _View more about this event at KubeCon + CloudNativeCon North America 2025_kccncna2025.sched.com

Try ConfigHub today

We now opened preview access to ConfigHub. If you are interested in moving beyond the complexity of managing templates and values files, we would love to hear from you. You can also explore our open-source SDK, our Flux Bridge implementation, our experimental Helm integration on GitHub to see exactly how we can extend ConfigHub to cover your Flux and Helm use cases.

Questions or feedback? Email us at hello@confighub.com.