Administration

Convert an HAProxy Enterprise configuration to CRDs

This page applies to:

  • HAProxy Enterprise Kubernetes Ingress Controller version 3.2.6-ee2 and 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, or backend section (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

  1. 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.

    nix
    sudo docker login https://registry.haproxy.com
    nix
    sudo docker login https://registry.haproxy.com
  2. Create an empty working directory and navigate into it. For example:

    nix
    mkdir example-working-directory
    cd example-working-directory
    nix
    mkdir example-working-directory
    cd example-working-directory
  3. 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.

      nix
      kubectl cp <namespace>/<pod-name>:<path-in-pod> <local-destination>
      nix
      kubectl cp <namespace>/<pod-name>:<path-in-pod> <local-destination>
      Example command
      nix
      kubectl cp haproxy-controller/haproxy-kubernetes-ingress-9cf5bf877-9q2sb:/etc/haproxy/haproxy.cfg hapee-lb.cfg
      nix
      kubectl 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.

  4. Remove the following lines from the configuration file accordingly:

    • Remove from lines in the defaults section.
    • Remove bind and default_backend lines 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.
    • server lines 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.

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.

nix
docker run \
--rm \
--volume "$(pwd):/example" \
--workdir /example \
--entrypoint /haproxy-ingress-controller registry.haproxy.com/haproxytech/hapee-ingress:v<VERSION> \
--job-convert-config=<CONFIG_FILE>
nix
docker 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 --rm runs 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 as hapee-lb.cfg) and write results back to your host filesystem.
  • --workdir /example sets /example as the working directory inside the container, matching the mounted volume.
  • --entrypoint /haproxy-ingress-controller overrides the image’s default entrypoint, forcing the container to run the /haproxy-ingress-controller binary 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 each global, defaults, frontend, and backend sections in the config file.
Example conversion

The following example HAProxy Enteprise configuration file contains:

hapee-lb.cfg
text
#---------------------------------------------------------------------
# Process global settings
#---------------------------------------------------------------------
global
stats socket /var/run/hapee-3.3/hapee-lb.sock user hapee-lb group hapee mode 660 level admin
log stdout format raw local0 info
#---------------------------------------------------------------------
# Common defaults that the 'backend' section will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
timeout connect 10s
timeout client 300s
timeout server 300s
#---------------------------------------------------------------------
# main frontend
#---------------------------------------------------------------------
frontend fe_main
option accept-unsafe-violations-in-http-request
filter comp-req
compression algo-req identity
acl images_url path -i -m beg /images/
#---------------------------------------------------------------------
# round-robin balancing in the backend
#---------------------------------------------------------------------
backend web_servers
balance roundrobin
server s1 172.16.0.11:80 check
server s2 172.16.0.12:80 check
hapee-lb.cfg
text
#---------------------------------------------------------------------
# Process global settings
#---------------------------------------------------------------------
global
stats socket /var/run/hapee-3.3/hapee-lb.sock user hapee-lb group hapee mode 660 level admin
log stdout format raw local0 info
#---------------------------------------------------------------------
# Common defaults that the 'backend' section will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
timeout connect 10s
timeout client 300s
timeout server 300s
#---------------------------------------------------------------------
# main frontend
#---------------------------------------------------------------------
frontend fe_main
option accept-unsafe-violations-in-http-request
filter comp-req
compression algo-req identity
acl images_url path -i -m beg /images/
#---------------------------------------------------------------------
# round-robin balancing in the backend
#---------------------------------------------------------------------
backend web_servers
balance roundrobin
server s1 172.16.0.11:80 check
server 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:

nix
docker 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
nix
docker 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
output
text
2026/07/30 19:35:06 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
2026/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.2
2026/07/30 19:35:06 INFO /src/main.go:120 Build from: github.com/haproxytech/kubernetes-ingress
2026/07/30 19:35:06 INFO /src/main.go:121 Build date: 2026-02-27T10:43:42Z
2026/07/30 19:35:06 INFO job/crd-converter.go:40 converting HAProxy config to CRDs
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote global_global.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote defaults_unnamed-defaults-1.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote frontend_fe-main.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote backend_web-servers.yml
output
text
2026/07/30 19:35:06 maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined
2026/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.2
2026/07/30 19:35:06 INFO /src/main.go:120 Build from: github.com/haproxytech/kubernetes-ingress
2026/07/30 19:35:06 INFO /src/main.go:121 Build date: 2026-02-27T10:43:42Z
2026/07/30 19:35:06 INFO job/crd-converter.go:40 converting HAProxy config to CRDs
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote global_global.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote defaults_unnamed-defaults-1.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote frontend_fe-main.yml
2026/07/30 19:35:06 INFO job/crd-converter.go:180 wrote backend_web-servers.yml
global_global.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Global
metadata:
creationTimestamp: null
name: global
spec:
log_target_list:
- address: stdout
facility: local0
format: raw
level: info
runtime_apis:
- address: /var/run/hapee-3.3/hapee-lb.sock
group: hapee
level: admin
mode: "660"
user: hapee-lb
global_global.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Global
metadata:
creationTimestamp: null
name: global
spec:
log_target_list:
- address: stdout
facility: local0
format: raw
level: info
runtime_apis:
- address: /var/run/hapee-3.3/hapee-lb.sock
group: hapee
level: admin
mode: "660"
user: hapee-lb
defaults_unnamed-defaults-1.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Defaults
metadata:
creationTimestamp: null
name: unnamed-defaults-1
spec:
client_timeout: 300000
connect_timeout: 10000
log_target_list:
- global: true
mode: http
name: unnamed_defaults_1
server_timeout: 300000
defaults_unnamed-defaults-1.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Defaults
metadata:
creationTimestamp: null
name: unnamed-defaults-1
spec:
client_timeout: 300000
connect_timeout: 10000
log_target_list:
- global: true
mode: http
name: unnamed_defaults_1
server_timeout: 300000
frontend_fe-main.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Frontend
metadata:
name: fe-main
spec:
accept_unsafe_violations_in_http_request: enabled
acl_list:
- acl_name: images_url
criterion: path
value: -i -m beg /images/
compression:
algo-req: identity
from: unnamed_defaults_1
name: fe_main
frontend_fe-main.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Frontend
metadata:
name: fe-main
spec:
accept_unsafe_violations_in_http_request: enabled
acl_list:
- acl_name: images_url
criterion: path
value: -i -m beg /images/
compression:
algo-req: identity
from: unnamed_defaults_1
name: fe_main
backend_web-servers.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Backend
metadata:
creationTimestamp: null
name: web-servers
spec:
balance:
algorithm: roundrobin
from: unnamed_defaults_1
name: web_servers
backend_web-servers.yml
text
apiVersion: ingress.v3.haproxy.com/v3
kind: Backend
metadata:
creationTimestamp: null
name: web-servers
spec:
balance:
algorithm: roundrobin
from: unnamed_defaults_1
name: 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.

Do you have any suggestions on how we can improve the content of this page?