Unreleased documentation. Choose your installed release in the version menu. Features described here may be absent from that release.
Validate a configuration before you deploy it¶
Run haptic preflight to check your chart values before deployment. Helm runs it
by default during installation and upgrades. Adding it to your delivery pipeline
finds the same errors before you apply the release.
Prerequisites¶
- Your release's Helm values in
haptic-values.yaml. - The same HAPTIC binary, chart, and HAProxy series you plan to deploy. See Getting the binary and chart.
- Kubernetes credentials for the target cluster, or an offline schema directory.
- Docker or
podmanfor Vector and Varnish validation. Without a container runtime, those checks are skipped with a warning; the HAPTIC and HAProxy checks still run.
Run the check¶
With haptic on your path and the matching chart in ./chart, run:
haptic preflight \
--values ./haptic-values.yaml \
--chart ./chart \
--namespace haptic \
--release haptic
A non-zero exit means validation failed or couldn't run. Resolve the reported error before deploying. To make this a delivery-pipeline gate, run the check before Helm and stop the pipeline if it fails:
set -e
haptic preflight --values ./haptic-values.yaml --chart ./chart --namespace haptic
helm upgrade --install haptic ./chart --namespace haptic --create-namespace \
--values ./haptic-values.yaml
Keep preRolloutValidation.enabled: true so deployment also checks the final values.
What it checks¶
| Check | Catches |
|---|---|
Structural validation and the bundled validationTests, including haproxy -c |
A configuration the controller would refuse to load |
vector validate on the rendered sidecar config |
A malformed document or a broken transform that would keep the supervised Vector child unavailable |
varnishd -C on the rendered Varnish Configuration Language (VCL) |
A VCL that doesn't compile, which leaves the cache pod in CrashLoopBackOff |
With --resources or --resources-from-cluster: a render against your resources, then haproxy -c |
A configuration that only breaks with your real Ingresses, Services, or ConfigMaps — see Check against your resources |
Command-line flags¶
| Flag | Default | Meaning |
|---|---|---|
--values, -f |
required | Your values file. Repeatable — later files win, as with helm -f |
--namespace, -n |
haptic |
Release namespace. Use the one you deploy to — chart output depends on it |
--release |
haptic |
Release name, which resource names are derived from |
--chart |
image-embedded chart | Chart directory, then $HAPTIC_CHART_DIR, then the copy inside the controller image |
--kubeconfig |
$KUBECONFIG, then in-cluster |
Which cluster to read API schemas from — see Schemas |
--schema-dir |
$HAPTIC_SCHEMA_DIR |
Read schemas from a directory instead of the cluster, for running fully offline |
--api-versions |
— | Extra API versions your cluster serves. The Gateway API GatewayClass version is always declared, so the Gateway library renders the same way it does in the cluster |
--resources |
— | Manifest file or directory of the resources the controller watches once deployed. Repeatable. See Check against your resources |
--resources-from-cluster |
off | List the watched resources from the cluster (read-only) and render against them |
--expect-chart-version |
$HAPTIC_EXPECT_CHART_VERSION |
Fail unless the chart being rendered carries exactly this version. Set it to the version you plan to install |
Set HAPTIC_CONTAINER_RUNTIME to choose a runtime (default: docker, then
podman). Preflight selects Vector's image from the rendered Helm workload
and Varnish's image from the workload mounting each VCL ConfigMap. It checks
every distinct config and image pair, including variants with the same file name.
Set image overrides in your Helm values so validation and deployment use the
same images. If you set HAPTIC_VECTOR_IMAGE or HAPTIC_VARNISH_IMAGE, it must
equal the corresponding rendered image. A mismatch or an unresolved image
fails the check.
Check against your resources¶
The validationTests render only their own fixtures. To also render the
configuration against the resources the controller is going to watch, and run
haproxy -c on the result, pass them in:
# Manifests on disk, offline (with --schema-dir, or a cluster for the schemas):
haptic preflight --values ./haptic-values.yaml --chart ./chart --resources ./rendered/
# The resources in the target cluster, listed read-only:
haptic preflight --values ./haptic-values.yaml --chart ./chart --resources-from-cluster
Preflight keeps only what the controller would watch: each watched resource's
namespaces, label selector, and field selector (for example the Ingress class)
apply. The render uses your values' extraContext, as the controller does.
--resourcesreads every.yamland.ymlfile under each path, includingkind: Listdocuments. Include everything the configuration reads, such as the default TLS certificate Secret and ConfigMaps your annotations name; a missing one fails the render the way it would in the cluster.--resources-from-clusterneedslistaccess to every watched resource, Secrets included, like the controller's own ServiceAccount.- HTTP resources a template fetches aren't available, so a configuration that fetches one fails this check.
Schemas¶
Preflight requires schemas to resolve typed fields and determine which optional resources and features are available. It fails if it can't load a schema source.
By default, it reads schemas from the target cluster using your Kubernetes credentials. This includes the custom resource definitions (CRDs) and schema versions installed there.
For offline validation, pass --schema-dir with CRD manifests or OpenAPI v3
schemas. Keep this directory aligned with the target cluster; preflight can't
verify that alignment without cluster access.
# Offline: schemas from a directory, no cluster contacted.
haptic preflight --values ./haptic-values.yaml --chart ./chart --schema-dir ./schemas
Getting the binary and chart¶
Install the CLI for the release you plan to deploy and install the
matching HAProxy series on the same host. The check runs haproxy -c locally.
In a working directory without an existing chart directory, download the
matching chart:
helm pull oci://ghcr.io/haproxy-haptic/haptic/charts/haptic \
--version 0.10.0 --untar --untardir ./chart-download
mv ./chart-download/haptic ./chart
Use the same release version for the binary and chart; validating one version and deploying another leaves the deployed combination unchecked.
The controller image also contains the matching binary at /usr/local/bin/haptic
and chart at /usr/share/haptic/chart. CI systems can extract both from the image
used by their release. Run the binary on the host with HAProxy and a container
runtime available to include the sidecar checks.
What it doesn't cover¶
Without --resources or --resources-from-cluster, the check renders
against your values and the bundled test fixtures, not against your Ingresses,
Gateways, and Services. Neither option predicts what a future routing resource
renders to.
For that, keep the admission webhook enabled — it validates each watched resource as it's applied, and rejects one that would break the rendered configuration.
To check whether a change needs a reload, compare it with a running pod:
Use offline schemas when the candidate uses typed resources. See configuration comparison for output meanings and file-to-file comparison.