Administration
Convert an HAProxy Enterprise configuration to CRDs
This page applies to:
- HAProxy Enterprise Kubernetes Ingress Controller version
3.2.6-ee2and newer
HAProxy Enterprise Kubernetes Ingress Controller’s CRD converter can convert an HAProxy Enterprise configuration file into Kubernetes Custom Resource Definitions (CRDs). The CRD converter parses an existing config file and outputs YAML files, which expedites migrations to your Kubernetes cluster.
Use cases for the CRD converter include:
-
You want to migrate from HAProxy Enterprise to HAProxy Enterprise Kubernetes Ingress Controller.
-
You are already using HAProxy Enterprise Kubernetes Ingress Controller and want to begin using custom resources. You want to extract the HAProxy Enterprise configuration from your running HAProxy Enterprise Kubernetes Ingress Controller pod, which may contain config snippets and annotations.
-
You can use the CRD converter as a one-time conversion tool or repeatedly to simplify the creation of custom resources. Convert one-line HAProxy Enterprise configurations inside a
global,defaults,frontend, orbackendsection (including just one config snippet) or up to an entire, complete configuration. The CRD converter makes it easier to add to existing custom resources.
Prerequisites Jump to heading
-
Log into the HAProxy Docker registry using your HAProxy Enterprise license key as both the username and password. You can also view this registry in a browser to confirm your target HAProxy Enterprise Kubernetes Ingress Controller version is available.
nixsudo docker login https://registry.haproxy.comnixsudo docker login https://registry.haproxy.com -
Create an empty working directory and navigate into it. For example:
nixmkdir example-working-directorycd example-working-directorynixmkdir example-working-directorycd example-working-directory -
Create or extract a copy of your HAProxy Enterprise configuration file (by default named
hapee-lb.cfg) in the working directory. You can:-
Create a new config file and manually add lines to it to see how the conversion works, or to try different directives and see how they work. It’s great for development and experimental use.
-
Extract a copy of your config file from the HAProxy Enterprise Ingress Controller pod.
nixkubectl cp <namespace>/<pod-name>:<path-in-pod> <local-destination>nixkubectl cp <namespace>/<pod-name>:<path-in-pod> <local-destination>Example command
nixkubectl cp haproxy-controller/haproxy-kubernetes-ingress-9cf5bf877-9q2sb:/etc/haproxy/haproxy.cfg hapee-lb.cfgnixkubectl cp haproxy-controller/haproxy-kubernetes-ingress-9cf5bf877-9q2sb:/etc/haproxy/haproxy.cfg hapee-lb.cfg -
Extract a copy of your config file from any working HAProxy Enterprise load balancer.
-
-
Remove the following lines from the configuration file accordingly:
- Remove
fromlines in thedefaultssection. - Remove
bindanddefault_backendlines in frontends. You can set new binds after the conversion, which requires a manual step to add port numbers to a Kubernetes Service object; see binds. serverlines in backends will be ignored, so they can be removed.- Commented lines will be ignored, so they can be removed.
config-snippets are allowed; however, their commented lines will be ignored so only the lines in between will be converted.
- Remove
Convert an HAProxy Enterprise configuration to CRDs Jump to heading
From the working directory, run the docker command to convert the HAProxy Enterprise configuration file.
nixdocker run \--rm \--volume "$(pwd):/example" \--workdir /example \--entrypoint /haproxy-ingress-controller registry.haproxy.com/haproxytech/hapee-ingress:v<VERSION> \--job-convert-config=<CONFIG_FILE>
nixdocker run \--rm \--volume "$(pwd):/example" \--workdir /example \--entrypoint /haproxy-ingress-controller registry.haproxy.com/haproxytech/hapee-ingress:v<VERSION> \--job-convert-config=<CONFIG_FILE>
Where:
docker run --rmruns a new container and automatically deletes it once it exits or stops running.--volume "$(pwd):/example"mounts the current host directory into the container at/example, so the container can read your local files (such ashapee-lb.cfg) and write results back to your host filesystem.--workdir /examplesets/exampleas the working directory inside the container, matching the mounted volume.--entrypoint /haproxy-ingress-controlleroverrides the image’s default entrypoint, forcing the container to run the/haproxy-ingress-controllerbinary directly.registry.haproxy.com/haproxytech/hapee-ingress:v<VERSION>pulls the target version of HAProxy Enterprise Kubernetes Ingress Controller’s image to run. Replace<VERSION>with your desired target version from our registry.--job-convert-config=<CONFIG_FILE>runs the CRD converter job to convert the target HAProxy Enterprise configuration file into Kubernetes CRDs, writing the output to your current directory. Replace<CONFIG_FILE>with your target config file. A YAML file will be created for eachglobal,defaults,frontend, andbackendsections in the config file.
Example conversion
The following example HAProxy Enteprise configuration file contains:
hapee-lb.cfgtext#---------------------------------------------------------------------# Process global settings#---------------------------------------------------------------------globalstats socket /var/run/hapee-3.3/hapee-lb.sock user hapee-lb group hapee mode 660 level adminlog stdout format raw local0 info#---------------------------------------------------------------------# Common defaults that the 'backend' section will# use if not designated in their block#---------------------------------------------------------------------defaultsmode httplog globaltimeout connect 10stimeout client 300stimeout server 300s#---------------------------------------------------------------------# main frontend#---------------------------------------------------------------------frontend fe_mainoption accept-unsafe-violations-in-http-requestfilter comp-reqcompression algo-req identityacl images_url path -i -m beg /images/#---------------------------------------------------------------------# round-robin balancing in the backend#---------------------------------------------------------------------backend web_serversbalance roundrobinserver s1 172.16.0.11:80 checkserver s2 172.16.0.12:80 check
hapee-lb.cfgtext#---------------------------------------------------------------------# Process global settings#---------------------------------------------------------------------globalstats socket /var/run/hapee-3.3/hapee-lb.sock user hapee-lb group hapee mode 660 level adminlog stdout format raw local0 info#---------------------------------------------------------------------# Common defaults that the 'backend' section will# use if not designated in their block#---------------------------------------------------------------------defaultsmode httplog globaltimeout connect 10stimeout client 300stimeout server 300s#---------------------------------------------------------------------# main frontend#---------------------------------------------------------------------frontend fe_mainoption accept-unsafe-violations-in-http-requestfilter comp-reqcompression algo-req identityacl images_url path -i -m beg /images/#---------------------------------------------------------------------# round-robin balancing in the backend#---------------------------------------------------------------------backend web_serversbalance roundrobinserver s1 172.16.0.11:80 checkserver s2 172.16.0.12:80 check
The following docker command uses HAProxy Enterprise Kubernetes Ingress Controller version 3.2 to convert the hapee-lb.cfg file:
nixdocker run --rm -v "$(pwd):/example" -w /example --entrypoint /haproxy-ingress-controller registry.haproxy.com/haproxytech/hapee-ingress:v3.2 --job-convert-config=hapee-lb.cfg
nixdocker run --rm -v "$(pwd):/example" -w /example --entrypoint /haproxy-ingress-controller registry.haproxy.com/haproxytech/hapee-ingress:v3.2 --job-convert-config=hapee-lb.cfg
outputtext2026/07/30 19:35:06 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined2026/07/30 19:35:06 /src/main.go:118_ _ _ ____ _____ _____| | | | / \ | _ \ _ __ _____ ___ _ | ____| ____|| |_| | / _ \ | |_) | '__/ _ \ \/ / | | | | _| | _|| _ |/ ___ \| __/| | | (_) > <| |_| | | |___| |___|_| |_/_/ \_\_| |_| \___/_/\_\\__, | |_____|_____|_ __ _ |___/ ___ ____| |/ / _| |__ ___ _ __ _ __ ___| |_ ___ ___ |_ _/ ___|| ' / | | | '_ \ / _ \ '__| '_ \ / _ \ __/ _ \/ __| | | || . \ |_| | |_) | __/ | | | | | __/ || __/\__ \ | | |___|_|\_\__,_|_.__/ \___|_| |_| |_|\___|\__\___||___/ |___\____|2026/07/30 19:35:06 INFO /src/main.go:119 HAProxy Ingress Controller CRD Converter v3.22026/07/30 19:35:06 INFO /src/main.go:120 Build from: github.com/haproxytech/kubernetes-ingress2026/07/30 19:35:06 INFO /src/main.go:121 Build date: 2026-02-27T10:43:42Z2026/07/30 19:35:06 INFO job/crd-converter.go:40 converting HAProxy config to CRDs2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote global_global.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote defaults_unnamed-defaults-1.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote frontend_fe-main.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote backend_web-servers.yml
outputtext2026/07/30 19:35:06 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined2026/07/30 19:35:06 /src/main.go:118_ _ _ ____ _____ _____| | | | / \ | _ \ _ __ _____ ___ _ | ____| ____|| |_| | / _ \ | |_) | '__/ _ \ \/ / | | | | _| | _|| _ |/ ___ \| __/| | | (_) > <| |_| | | |___| |___|_| |_/_/ \_\_| |_| \___/_/\_\\__, | |_____|_____|_ __ _ |___/ ___ ____| |/ / _| |__ ___ _ __ _ __ ___| |_ ___ ___ |_ _/ ___|| ' / | | | '_ \ / _ \ '__| '_ \ / _ \ __/ _ \/ __| | | || . \ |_| | |_) | __/ | | | | | __/ || __/\__ \ | | |___|_|\_\__,_|_.__/ \___|_| |_| |_|\___|\__\___||___/ |___\____|2026/07/30 19:35:06 INFO /src/main.go:119 HAProxy Ingress Controller CRD Converter v3.22026/07/30 19:35:06 INFO /src/main.go:120 Build from: github.com/haproxytech/kubernetes-ingress2026/07/30 19:35:06 INFO /src/main.go:121 Build date: 2026-02-27T10:43:42Z2026/07/30 19:35:06 INFO job/crd-converter.go:40 converting HAProxy config to CRDs2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote global_global.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote defaults_unnamed-defaults-1.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote frontend_fe-main.yml2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote backend_web-servers.yml
global_global.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Globalmetadata:creationTimestamp: nullname: globalspec:log_target_list:- address: stdoutfacility: local0format: rawlevel: inforuntime_apis:- address: /var/run/hapee-3.3/hapee-lb.sockgroup: hapeelevel: adminmode: "660"user: hapee-lb
global_global.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Globalmetadata:creationTimestamp: nullname: globalspec:log_target_list:- address: stdoutfacility: local0format: rawlevel: inforuntime_apis:- address: /var/run/hapee-3.3/hapee-lb.sockgroup: hapeelevel: adminmode: "660"user: hapee-lb
defaults_unnamed-defaults-1.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Defaultsmetadata:creationTimestamp: nullname: unnamed-defaults-1spec:client_timeout: 300000connect_timeout: 10000log_target_list:- global: truemode: httpname: unnamed_defaults_1server_timeout: 300000
defaults_unnamed-defaults-1.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Defaultsmetadata:creationTimestamp: nullname: unnamed-defaults-1spec:client_timeout: 300000connect_timeout: 10000log_target_list:- global: truemode: httpname: unnamed_defaults_1server_timeout: 300000
frontend_fe-main.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Frontendmetadata:name: fe-mainspec:accept_unsafe_violations_in_http_request: enabledacl_list:- acl_name: images_urlcriterion: pathvalue: -i -m beg /images/compression:algo-req: identityfrom: unnamed_defaults_1name: fe_main
frontend_fe-main.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Frontendmetadata:name: fe-mainspec:accept_unsafe_violations_in_http_request: enabledacl_list:- acl_name: images_urlcriterion: pathvalue: -i -m beg /images/compression:algo-req: identityfrom: unnamed_defaults_1name: fe_main
backend_web-servers.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Backendmetadata:creationTimestamp: nullname: web-serversspec:balance:algorithm: roundrobinfrom: unnamed_defaults_1name: web_servers
backend_web-servers.ymltextapiVersion: ingress.v3.haproxy.com/v3kind: Backendmetadata:creationTimestamp: nullname: web-serversspec:balance:algorithm: roundrobinfrom: unnamed_defaults_1name: web_servers
After the conversion Jump to heading
If you successfully converted from an existing HAProxy Enterprise Kubernetes Ingress Controller configuration, remove any old config snippets and annotations from the CRD files; you will no longer need them.
See the HAProxy Enterprise Kubernetes Ingress Controller’s configuration reference to connect your new custom resources, especially if it’s your first time:
Continue using the CRD converter to make future changes to your custom resources. This tool makes it easier to write valid custom resources.
See also Jump to heading
See add user-defined annotations for further information on config snippets and annotations.