HAProxy config,
rendered from your templates.

HAPTIC — the HAProxy Template Ingress Controller — is an open-source Kubernetes controller that builds your HAProxy config from templates you control. Watch Ingress, the Gateway API, or any custom resource, and shape the generated config exactly the way you want it.

$ haptic --features

No Upstream Waiting

Add an annotation, a header rewrite, or support for a new API by editing a template — not by forking the controller or waiting for an upstream release.

You Own Every Line

Scriggo — a fast, Go-native template engine — renders the exact haproxy.cfg you want. No magic translation layer; every line is yours to tune, extend, or override.

Watch Any Resource

Resource-agnostic by design: point HAPTIC at any Kubernetes kind — even a CRD you defined — with no per-resource controller code.

If you own every line, are you maintaining a config fork forever?

No — you don't start from a blank file. Bundled libraries render classic Ingress and the Gateway API out of the box, and read existing annotations from ingress-nginx, HAProxy Technologies' kubernetes-ingress, and the community haproxy-ingress. Much of a current setup migrates by pointing HAPTIC at the Ingresses you already run — you only template the gap, a few lines in HAPTIC's config, not a fork you rebase.

$ haptic --extend

Need something the bundled libraries don't ship — say an X-Request-ID header your platform users opt into per Ingress? Drop a snippet into the HAProxyTemplateConfig HAPTIC watches. No controller fork, no waiting for a release.

haproxytemplateconfig.yaml
apiVersion: haproxy-haptic.org/v1alpha1
kind: HAProxyTemplateConfig
metadata:
  name: haptic
spec:
  # bundled libraries already cover Ingress and the Gateway API — you add:
  templateSnippets:
    frontend-filters-300-request-id:
      template: |
        {%- for _, ingress := range resources.ingresses.List() %}
        {%- var header = fallback(ingress.metadata.annotations["example.com/request-id-header"], "") %}
        {%- if header != "" %}
        http-request set-header {{ header }} %[uuid()]
        {%- end %}
        {%- end %}

Any Ingress opts in: example.com/request-id-header: "X-Request-ID"

$ haptic --install

bash — install
$ helm install \
    haptic oci://registry.gitlab.com/haproxy-haptic/haptic/charts/haptic \
    --version 0.1.0
$ kubectl get haproxytemplateconfig

$ haptic --docs

~/controller

Controller

How the ingress controller works: resource watching, template rendering, configuration validation, and HAProxy deployment.

Available versions

Loading…
~/helm-chart

Helm Chart

Installs the controller into your cluster with preconfigured templates. Start here if you already know the basics or just want to deploy.

Available versions

Loading…

// Built for operators who'd rather write a template than file a feature request.

Apache-2.0 · Source on GitLab

Community project — independent and not affiliated with or endorsed by HAProxy Technologies.