Skip to content

HAPTIC

HAPTIC (HAProxy Template Ingress Controller) is a template-driven HAProxy Ingress Controller for Kubernetes that generates HAProxy configurations using Scriggo templates and applies them to your HAProxy fleet — reloading only when the change needs one.

Community Project

This is an independent community project and isn't affiliated with or endorsed by HAProxy Technologies.

What's HAPTIC?

HAPTIC is an event-driven Kubernetes controller that:

  • Watches any Kubernetes resource - Ingresses, Services, Secrets, Gateway API resources, or any custom resource type you configure
  • Renders Scriggo templates - A Go-native template engine
  • Validates before deployment - Every rendered config passes syntax, schema, and haproxy -c checks before it reaches your load balancers
  • Applies configurations to HAProxy pods through the HAPTIC agent, which runs map, certificate and server changes on the live worker instead of reloading

Unlike traditional ingress controllers with hardcoded configuration logic, HAPTIC uses a template-driven approach that gives you full control over the generated HAProxy configuration. This means you can:

  • Define custom annotations that your platform users can use, implemented with just a few lines of template code
  • Support new standards like Gateway API without waiting for controller updates
  • Watch domain-specific CRDs and generate HAProxy configuration from any Kubernetes resource type

Key features

Template-driven flexibility

Traditional ingress controllers embed configuration logic in code. HAPTIC inverts this:

  • Full HAProxy access - If HAProxy supports it, your templates can emit it — every section, every directive in the configuration manual
  • Add features without code changes - New directives are template updates, not controller releases
  • Rich template context - Access any Kubernetes resource, fetch external data via HTTP, and use controller state in your templates
  • Everything is templatable - Generate not just haproxy.cfg but also map files, SSL certificates, CRT-lists, and custom auxiliary files

Production ready

  • High availability - Leader election with automatic failover
  • Layered validation - Admission webhook, template validation, and tests you can run in CI before anything reaches a cluster
  • Observability - Per-route request metrics (rate, errors, latency by phase) derived from the access log, JSON structured logging, and debug endpoints

Project maturity

The current release is 0.2.0-alpha.1, a pre-1.0 alpha, and the custom resources are served at API version v1alpha1 — their schemas can still change before 1.0. The high-availability, validation, and observability features above are implemented and covered by tests, but pin an exact chart version (--version 0.2.0-alpha.1) and read the changelog before you upgrade.

Ready to use out of the box

The Helm chart ships with Template Libraries enabled by default. They cover Kubernetes Ingress and Gateway API resources out of the box, with HAPTIC's native haproxy-haptic.org/* annotations — a best-of-breed superset of the common HAProxy and nginx ingress-controller annotations — enabled by default. No template authoring required, and the vendor annotation libraries are available opt-in for migration. Customizing or extending the templates is entirely optional.

Architecture

The controller follows an event-driven architecture where changes to Kubernetes resources trigger a pipeline that renders templates, validates the output, and syncs configurations to HAProxy pods.

Key components:

  • Watcher - Subscribes to Kubernetes API for configured resource types
  • Template Engine - Renders Scriggo templates with resource data as context
  • Validator - Runs syntax, schema, and haproxy -c checks on the rendered config so broken configs never deploy
  • Deployer - Decides per pod whether a change can run on the live worker or needs a reload, and sends it to that pod's agent

Quick start

helm install haptic oci://registry.gitlab.com/haproxy-haptic/haptic/charts/haptic --version 0.2.0-alpha.1 --namespace haptic --create-namespace

This installs both the controller and a 2-replica HAProxy Deployment, plus the default template libraries that cover Ingress and Gateway API out of the box. For the full walkthrough — including a sample app, end-to-end verification, and inspecting the rendered config the controller publishes as a HAProxyCfg resource — see Getting Started.

What makes HAPTIC different

Templates are the difference. Suppose your platform users want a custom annotation that injects an X-Request-ID header for tracing. One snippet — no controller fork, no waiting for a release (with the Helm chart you'd place it under controller.config.templateSnippets in your values):

The frontend-filters-300-request-id snippet under templateSnippets implements the annotation. In the Resources panel, change the shop Ingress's example.com/request-id-header value to X-Trace-ID — or remove the annotation — and watch the http-request set-header line in haproxy.cfg follow.

apiVersion: haproxy-haptic.org/v1alpha1
kind: HAProxyTemplateConfig
spec:
  templateSnippets:
    # The frontend-filters-* glob picks this up automatically; the 300 prefix
    # places it alongside the built-in header-manipulation snippets.
    frontend-filters-300-request-id:
      template: |
        {%- for _, ingress := range resources.ingresses.List() %}
        {%- var header = ingress | dig("metadata", "annotations", "example.com/request-id-header") | fallback("") | tostring() %}
        {%- if header != "" %}
        http-request set-header {{ header }} %[uuid()]
        {%- end %}
        {%- end %}

Users opt in per-Ingress with example.com/request-id-header: "X-Request-ID". The same pattern works for rate limiting, header rewrites, custom ACLs — anything HAProxy can express. Override any snippet, replace the main template, or disable all libraries and start from scratch. See the Templating Guide.

Where to go next

Reading the docs as an AI agent

Every page is also served as raw Markdown: append index.md to any page URL (for example this page's Markdown is at index.md). Two site-wide maps help agents crawl the whole site:

  • llms.txt — a link index of every page's Markdown endpoint, following the llmstxt.org convention
  • llms-full.txt — every page's Markdown concatenated into one document

Fetch them at the site root, for example https://haproxy-haptic.org/docs/llms.txt.

Contributing to the docs

For a quick fix — a typo or a clearer sentence — click the pencil icon above any page title. It opens that page's Markdown in GitLab's web editor and turns your change into a merge request.

For larger changes, edit the sources under docs/site/docs/ in the repository and preview them locally:

cd docs/site
mkdocs serve

This serves the site at http://127.0.0.1:8000/ and reloads on save.

Found a problem on this page? Report it or edit the page with the pencil icon above the title.