{"id":42341499,"url":"https://github.com/six-group/haproxy-operator","last_synced_at":"2026-01-27T15:02:54.610Z","repository":{"id":214337294,"uuid":"716967943","full_name":"six-group/haproxy-operator","owner":"six-group","description":"HAProxy Operator is a Kubernetes-native solution designed to automate the deployment, configuration, and management of HAProxy instances using Custom Resources to abstract the key components such as backends, frontends, and listens.","archived":false,"fork":false,"pushed_at":"2025-11-10T02:06:43.000Z","size":23980,"stargazers_count":28,"open_issues_count":10,"forks_count":7,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-11-22T19:05:37.507Z","etag":null,"topics":["haproxy","haproxy-configuration","ingress","kubernetes","kubernetes-operator","loadbalancing","operator-sdk"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/six-group.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-11-10T09:01:32.000Z","updated_at":"2025-10-13T07:00:56.000Z","dependencies_parsed_at":"2024-01-30T09:31:37.715Z","dependency_job_id":"87fd1246-3d70-4146-b295-17968063477b","html_url":"https://github.com/six-group/haproxy-operator","commit_stats":null,"previous_names":["six-group/haproxy-operator"],"tags_count":76,"template":false,"template_full_name":null,"purl":"pkg:github/six-group/haproxy-operator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/six-group%2Fhaproxy-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/six-group%2Fhaproxy-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/six-group%2Fhaproxy-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/six-group%2Fhaproxy-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/six-group","download_url":"https://codeload.github.com/six-group/haproxy-operator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/six-group%2Fhaproxy-operator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28815385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T12:25:15.069Z","status":"ssl_error","status_checked_at":"2026-01-27T12:25:05.297Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["haproxy","haproxy-configuration","ingress","kubernetes","kubernetes-operator","loadbalancing","operator-sdk"],"created_at":"2026-01-27T15:02:53.161Z","updated_at":"2026-01-27T15:02:54.591Z","avatar_url":"https://github.com/six-group.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Github Build](https://github.com/six-group/haproxy-operator/actions/workflows/publish.yml/badge.svg)](https://github.com/six-group/haproxy-operator/actions/workflows/publish.yml)\n[![Github Test](https://github.com/six-group/haproxy-operator/actions/workflows/test.yml/badge.svg)](https://github.com/six-group/haproxy-operator/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/six-group/haproxy-operator)](https://goreportcard.com/report/github.com/six-group/haproxy-operator)\n[![Coveralls github](https://img.shields.io/coveralls/github/six-group/haproxy-operator?logo=coveralls)](https://coveralls.io/github/six-group/haproxy-operator?branch=master)\n[![GitHub Release](https://img.shields.io/github/release/six-group/haproxy-operator.svg?style=flat)](https://github.com/six-group/haproxy-operator/releases)\n\n# HAProxy Operator\nHAProxy Operator is a Kubernetes-native solution designed to automate the deployment, configuration, and management of HAProxy instances using Custom Resources to abstract the key components such as backends, frontends, and listens.\n\n## Installation\n### Helm\n```console\nhelm repo add six-group https://six-group.github.io/haproxy-operator\nhelm install haproxy-operator six-group/haproxy-operator\n```\n\n## Usage\n### Getting Started\nThis example will guide you through the process of setting up a basic HAProxy instance, configuring a frontend for receiving traffic, inspecting the generated HAProxy configuration, and making a sample request to demonstrate its functionality.\n\n1. Create a simple instance of the HAProxy by applying the following YAML manifest:\n    ```yaml\n    apiVersion: proxy.haproxy.com/v1alpha1\n    kind: Instance\n    metadata:\n      name: example\n      namespace: default\n    spec:\n      configuration:\n        defaults: {}\n        global: {}\n        selector: \n          matchLabels:\n            proxy.haproxy.com/instance: example\n      network:\n        service:\n          enabled: true\n    ```\n\n2. To define the port at which HAProxy should receive traffic, create a basic frontend configuration by applying the following YAML manifest:\n    ```yaml\n    apiVersion: config.haproxy.com/v1alpha1\n    kind: Frontend\n    metadata:\n      name: example\n      namespace: default\n      labels:\n        proxy.haproxy.com/instance: example\n    spec:\n      mode: http\n      binds:\n        - name: hello-world\n          port: 8080\n      defaultBackend: {}\n    ```\n\n3. Check the generated `haproxy.cfg` stored in the `Secret` `example-haproxy-config`:\n    ```\n    defaults unnamed_defaults_1\n      mode http\n      timeout connect 5000\n      timeout client 5000\n      timeout server 10000\n\n    frontend example\n      mode http\n      bind :8080 name hello-world\n    ```\n\n4. The HAProxy pod is now listening on port 8080 exposed by a `Service` called `example-haproxy`. If you make a request using `curl` executed from a pod within the same namespace, you’ll get back a response:\n    ```bash\n    $ curl http://example-haproxy:8080\n    \u003chtml\u003e\u003cbody\u003e\u003ch1\u003e503 Service Unavailable\u003c/h1\u003e\n    No server is available to handle this request.\n    \u003c/body\u003e\u003c/html\u003e\n    ```\n    Granted, there’s no reply from a server since we haven't configured any backend servers yet. Nevertheless, you can see that HAProxy is functional.\n\nFor a more in-depth understanding of the HAProxy Operator and to explore complex use cases, refer to the upcoming sections in this documentation. These sections will provide detailed explanations, advanced examples, and configuration options to help you tailor the HAProxy solution to your specific requirements.\n\n### HAProxy Instance (proxy.haproxy.com/v1alpha1)\n\nAn HAProxy instance refers to a single running instance of the HAProxy service. This service can be configured to manage the load balancing and distribution of network traffic among a set of servers or backends within or external to a Kubernetes cluster.\n\nEach HAProxy instance has its own configuration file, named haproxy.cfg and stored as a Secret, which defines all the settings for that instance, including defaults, frontends, and backends. This configuration file specifies how incoming connections are handled, which algorithms are used for load balancing, and how to monitor the health of the backends. Multiple HAProxy instances can be run on the same namespace, each with its own configuration and each listening on different ports.\n\n***Example:***\n\nThis is a configuration for an HAProxy instance with two sections: `global` and `defaults`. The `global` section sets process-wide parameters, including the number of threads, maximum concurrent connections, stats socket configuration, buffer sizes, SSL parameters, and logging settings. The `defaults` section sets default parameters for all other sections. It sets the mode to TCP, enables logging, and sets various timeout values for different types of connections and requests.\n\n```\nglobal\n  nbthread 4\n  stats socket /var/lib/haproxy/run/haproxy.sock expose-fd listeners level admin mode 600\n  stats timeout 300000\n  tune.bufsize 32768\n  tune.maxrewrite 8192\n  tune.ssl.default-dh-param 2048\n  ssl-default-bind-options ssl-min-ver TLSv1.2 \n  ssl-default-bind-ciphers SHA256\n  ssl-default-bind-ciphersuites TLS_SHA256\n  log /var/lib/rsyslog/rsyslog.sock local0\n  log-send-hostname\n\ndefaults unnamed_defaults_1\n  mode tcp\n  log global\n  option tcplog\n  timeout http-request 10000\n  timeout connect 5000\n  timeout client 30000\n  timeout client-fin 1000\n  timeout server 30000\n  timeout server-fin 1000\n  timeout tunnel 3600000\n  timeout http-keep-alive 300000\n ```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: proxy.haproxy.com/v1alpha1\nkind: Instance\nmetadata:\n  name: example\n  namespace: default\nspec:\n  configuration:\n    defaults:\n      logging:\n        enabled: true\n        tcpLog: true\n      mode: tcp\n      timeouts:\n        client: 30s\n        client-fin: 1s\n        connect: 5s\n        http-keep-alive: 5m0s\n        http-request: 10s\n        server: 600s\n        server-fin: 1s\n        tunnel: 1h0m0s\n    selector:\n      matchLabels:\n        proxy.haproxy.com/instance: example\n    global:\n      logging:\n        address: /var/lib/rsyslog/rsyslog.sock\n        enabled: true\n        facility: local0\n      ssl:\n        defaultBindCipherSuites:\n          - TLS_SHA256\n        defaultBindCiphers:\n          - SHA256\n        defaultBindOptions:\n          minVersion: TLSv1.2\n      statsTimeout: 5m0s\n      tune:\n        bufsize: 32768\n        maxrewrite: 8192\n        ssl:\n          defaultDHParam: 2048\n      nbthread: 4\n      reload: true\n  image: 'haproxy:2.8.0'\n  replicas: 2\n  network:\n    route:\n      enabled: false\n    service:\n      enabled: false\n```\n\n[API Reference Instance](docs/api-reference.md#instance) defines all the features that can be configured in an HAProxy instance.\n\n### HAProxy Configuration (config.haproxy.com/v1alpha1)\nFor the dynamic configuration of HAProxy instances, custom resources have been created for each configuration section, i.e., `listen`, `frontend`, `backend`, and `resolver`.\nThese configuration resources are associated with particular instances by the use of label selectors. A label selector is specified within the `Instance` configuration, and the corresponding label is applied to each configuration resource to establish a relation.\n\nAn example of a label selector used within an `Instance` to match a specific HAProxy instance is provided below:\n```yaml\nselector:\n  matchLabels:\n    proxy.haproxy.com/instance: example\n```\nThis approach allows HAProxy instances to be configured dynamically, with a focus on modularity and ease of management.\n\n\n#### Frontend\n\n`Frontend` defines how incoming connections are handled  based on the rules defined. It specifies the IP addresses and ports that HAProxy listens on and sets rules for what to do with connections once they are received. These rules can include Access Control Lists (ACLs), which allow you to route traffic based on various factors such as the client's IP address, the requested URL, or the type of protocol used. The HAProxy Operator allows you to define frontends in a declarative manner, specifying things like the port number and the default backend.\n\n***Example 1:***\n\nThe HAProxy frontend 'example-1' operates in HTTP mode and listens for incoming connections on a Unix socket at /var/lib/haproxy/run/local.sock:9443. It has a certificate file configured, which is used to terminate TLS connections. It also has a default backend configured, which is used when no other rules match an incoming request.\n\n\n ```\n frontend example-1\n  mode http\n  bind unix@/var/lib/haproxy/run/local.sock:9443 name https crt /usr/local/etc/haproxy/ssl-certs.crt ssl accept-proxy crt-list /usr/local/etc/haproxy/cert_list.map\n  errorfile 403 /usr/local/etc/haproxy/error-403.http\n  use_backend %[base,map_reg(/usr/local/etc/haproxy/edge.map)] if { base,map_reg(/usr/local/etc/haproxy/edge.map) -m found }\n  use_backend %[base,map_reg(/usr/local/etc/haproxy/reencrypt.map)] if { base,map_reg(/usr/local/etc/haproxy/reencrypt.map) -m found }\n  default_backend default-namespace\n ```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: config.haproxy.com/v1alpha1\nkind: Frontend\nmetadata:\n  name: example-1\n  namespace: default\n  labels:\n    proxy.haproxy.com/instance: example\nspec:\n  backendSwitching:\n    - backend:\n        regexMapping:\n          name: edge\n          parameter: base\n      condition: '{ base,map_reg(/usr/local/etc/haproxy/edge.map) -m found }'\n      conditionType: if\n    - backend:\n        regexMapping:\n          name: reencrypt\n          parameter: base\n      condition: '{ base,map_reg(/usr/local/etc/haproxy/reencrypt.map) -m found }'\n      conditionType: if\n  binds:\n    - acceptProxy: true\n      address: unix@/var/lib/haproxy/run/local.sock\n      hidden: true\n      name: https\n      port: 9443\n      ssl:\n        certificate:\n          name: ssl-certs\n          valueFrom:\n            - secretKeyRef:\n                key: tls.crt\n                name: ssl-certs\n            - secretKeyRef:\n                key: tls.key\n                name: ssl-certs\n        enabled: true\n      sslCertificateList:\n        name: cert_list\n  defaultBackend:\n    name: default-namespace\n  errorFiles:\n    - code: 403\n      file:\n        name: error-403\n        value: |-\n          HTTP/1.0 403 Forbidden\n          Pragma: no-cache\n          Cache-Control: private, max-age=0, no-cache, no-store\n          Connection: close\n          Content-Type: text/html\n\n          \u003c!DOCTYPE html\u003e\n          \u003chtml lang=\"en\"\u003e\n             \u003chead\u003e\n                \u003ctitle\u003e403 Forbidden\u003c/title\u003e\n             \u003c/head\u003e\n          \u003c/html\u003e\n        valueFrom: {}\n  mode: http\n```\n\n***Example 2:***\n\nThis is a HAProxy frontend configuration named 'example-2'. It operates in TCP mode, binds to a specific IP and port, and inspects TCP requests with a delay. It accepts requests with a specific SSL hello type.\n\n```\nfrontend example-2\n  mode tcp\n  bind ${BIND_ADDRESS}:443 name public-ssl\n  tcp-request inspect-delay 5000\n  tcp-request content accept if { req_ssl_hello_type 1 }\n  default_backend default-namespace\n```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: config.haproxy.com/v1alpha1\nkind: Frontend\nmetadata:\n  name: example-2\n  namespace: default\n  labels:\n    proxy.haproxy.com/instance: example\nspec:\n  binds:\n    - address: '${BIND_ADDRESS}'\n      name: public-ssl\n      port: 443\n  defaultBackend:\n    name: default-namespace\n  mode: tcp\n  tcpRequest:\n    - timeout: 5s\n      type: inspect-delay\n    - action: accept\n      condition: '{ req_ssl_hello_type 1 }'\n      conditionType: if\n      type: content\n```\n\n***Example 3:***\n\nThis is a HAProxy frontend configuration named 'example-3'. It operates in HTTP mode and binds to a specific IP and port. For every HTTP request, it immediately returns a HTTP 200 OK status with a JSON response indicating a successful health check.\n\n\n```\nfrontend example-3\n  mode http\n  bind ${BIND_ADDRESS}:50055 name health\n  http-request return status 200 content-type application/json string \"{\\\"status\\\":\\\"OK\\\"}\"\n```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: config.haproxy.com/v1alpha1\nkind: Frontend\nmetadata:\n  name: example-3\n  namespace: default\n  labels:\n    proxy.haproxy.com/instance: example\nspec:\n  binds:\n    - address: '${BIND_ADDRESS}'\n      name: health\n      port: 50055\n  defaultBackend: {}\n  httpRequest:\n    return:\n      content:\n        format: string\n        type: application/json\n        value: '{\\\"status\\\":\\\"OK\\\"}'\n      status: 200\n  mode: http\n```\n[API Reference Frontend](docs/api-reference.md#frontend) defines all the features that can be configured in an HAProxy frontend.\n\n\n#### Backend\n\n`Backend` refers to a set of servers that will receive the forwarded requests. The backend section defines how to reach the server, how to check its health, and how to balance the load among the servers. It can contain one or more servers, each server representing an application server in your infrastructure. With the HAProxy Operator, you can define the desired state for your backends in OpenShift, and the operator will ensure that the actual state matches the desired state.\n\n***Example 1:***\n\nThis is a HAProxy backend configuration named 'example-1'. It operates in TCP mode and defines an Access Control List (ACL) for a specific source IP. It enables connection redispatching with a maximum of 3 retries per request. It rejects TCP requests not matching the ACL. It defines a server with specific health check settings, initial address resolution disabled, a specific check interval, and specified resolvers for hostname resolution.\n\n```\nbackend example-1\n  mode tcp\n  acl whitelist src 0.0.0.0\n  option redispatch 3\n  tcp-request content reject if !whitelist\n  server web web.namespace.svc.cluster.local:443 check init-addr none inter 500 resolvers dns-namespace\n```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: config.haproxy.com/v1alpha1\nkind: Backend\nmetadata:\n  name: example-1\n  namespace: default\n  labels:\n    proxy.haproxy.com/instance: example\nspec:\n  acl:\n    - criterion: src\n      name: whitelist\n      values:\n        - 0.0.0.0\n  mode: tcp\n  redispatch: true\n  servers:\n    - address: web.namespace.svc.cluster.local\n      check:\n        enabled: true\n        inter: 500ms\n      initAddr: none\n      name: web\n      port: 443\n      resolvers:\n        name: dns-namespace\n  tcpRequest:\n    - action: reject\n      condition: '!whitelist'\n      conditionType: if\n      type: content\n```\n\n***Example 2:***\n\nThe HAProxy backend 'example-2' operates in HTTP mode. It has an Access Control List (ACL) named \"whitelist\" that matches when the source IP of the request is 0.0.0.0. It adds the X-Forwarded-For header to preserve the client's IP address, redistributes sessions in case of failure, and sets a health check timeout of 5 seconds. If a TCP request doesn't match the \"whitelist\" ACL, it's rejected. Various X-Forwarded-* and Forwarded headers are added to the HTTP request to convey information about the original request.  A server named \"web\" is defined within this backend, with health checks enabled and an interval of 500 milliseconds between checks. The server's hostname resolution uses the \"dns-namespace\" resolvers. SSL/TLS configuration and certificate verification are also specified for this server and its weight is set to 256.\n\n```\nbackend example-2\n  mode http\n  acl whitelist src 0.0.0.0\n  option forwardfor\n  option redispatch 3\n  timeout check 5000\n  tcp-request content reject if !whitelist\n  http-request add-header X-Forwarded-Host %[req.hdr(host)]\n  http-request add-header X-Forwarded-Port %[dst_port]\n  http-request add-header X-Forwarded-Proto http if !{ ssl_fc }\n  http-request add-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }\n  http-request add-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)]\n  cookie e76a2f0f39106e5e833f1323866171d4 attr SameSite=None httponly indirect nocache insert secure\n  server web web.namespace.svc.cluster.local:443 check ssl alpn http/1.1,h2 ca-file /usr/local/etc/haproxy/service-ca.crt cookie 4b24b04d486a91808d248592b93d2293 init-addr none inter 500 resolvers dns-namespace verify required verifyhost web.namespace.svc weight 256\n```\n\n```yaml title=\"haproxy.yaml\"\napiVersion: config.haproxy.com/v1alpha1\nkind: Backend\nmetadata:\n  name: example-2\n  namespace: default\n  labels:\n    proxy.haproxy.com/instance: example\nspec:\n  mode: http\n  cookie:\n    attribute:\n      - SameSite=None\n    httpOnly: true\n    indirect: true\n    mode:\n      insert: true\n      prefix: false\n      rewrite: false\n    name: app\n    noCache: true\n    secure: true\n  forwardFor:\n    enabled: true\n  httpRequest:\n    addHeader:\n      - name: X-Forwarded-Host\n        value:\n          str: '%[req.hdr(host)]'\n      - name: X-Forwarded-Port\n        value:\n          str: '%[dst_port]'\n      - condition: '!{ ssl_fc }'\n        conditionType: if\n        name: X-Forwarded-Proto\n        value:\n          str: http\n      - condition: '{ ssl_fc_alpn -i h2 }'\n        conditionType: if\n        name: X-Forwarded-Proto-Version\n        value:\n          str: h2\n      - name: Forwarded\n        value:\n          str: 'for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)]'\n  acl:\n    - criterion: src\n      name: whitelist\n      values:\n        - 0.0.0.0\n  redispatch: true\n  tcpRequest:\n    - action: reject\n      condition: '!whitelist'\n      conditionType: if\n      type: content\n  servers:\n    - port: 443\n      initAddr: none\n      verifyHost: web.namespace.svc\n      cookie: true\n      check:\n        enabled: true\n        inter: 500ms\n      name: web\n      ssl:\n        alpn:\n          - http/1.1\n          - h2\n        caCertificate:\n          name: service-ca.crt\n          valueFrom:\n            - configMapKeyRef:\n                key: service-ca.crt\n                name: openshift-service-ca.crt\n        enabled: true\n        verify: required\n      resolvers:\n        name: dns-namespace\n      address: web.namespace.svc.cluster.local\n      weight: 256\n  timeouts:\n    check: 5s\n```\n\n[API Reference Backend](docs/api-reference.md#backend) defines all the features that can be configured in an HAProxy backend.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsix-group%2Fhaproxy-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsix-group%2Fhaproxy-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsix-group%2Fhaproxy-operator/lists"}