%[] in use-server

:wave:

I’m trying to make servers “dynamic” by using a “templated” backend with servers pulled from a map

backend be_template
  server-template websrv 1-100 localhost:6666 check disabled
  use-server %[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map,websrv0)] if { req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map) -m found }

However, the above doesn’t work, haproxy fails to start with the following error:

haproxy_1  | [ALERT] 048/160628 (1) : config : backend 'be_template' : unable to find server '%[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map,websrv0)]' referenced in a 'use-server' rule.
haproxy_1  | [ALERT] 048/160628 (1) : Fatal errors found in configuration.

I wonder if %[] syntax is allowed in use-server like in use_backend?


HAProxy version that I’m using is 1.9.

Full config:

global
  log /dev/log local0
  log /dev/log local1 notice
  chroot /var/lib/haproxy
  # TODO
  stats socket ipv4@127.0.0.1:9999 level admin
  # stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
  stats timeout 30s
  daemon

defaults
  log global
  mode http
  option httplog
  option dontlognull
  option forwardfor
  option http-keep-alive
  http-reuse safe
  timeout connect 5000
  timeout client 50000
  timeout server 50000

frontend http
  bind :::80 v4v6
  use_backend be_template

backend be_template
  server-template websrv 1-100 localhost:6666 check disabled
  use-server %[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map)] if { req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map) -m found }

I think Dynamic server selection might be related. I thought about using a lua script to pick the server but it seems it’s not supported either.

My use case is similar to gitlab review apps – on some PRs I want to be able to start web apps each with its own subdomain which would register themselves with haproxy via a socket like this:

set server be_template/websrv<i> addr <app_host> port <app_port>
set server be_template/websrv<i> state ready
add map /usr/local/etc/haproxy/domain2server.map <COMMIT_REF_SLUG>.domain.com websrv<i>

I’ve also asked this question on the mailing list: https://www.mail-archive.com/haproxy@formilux.org/msg32843.html

Seems like it is not possible, haproxy just does a strcmp without expanding what’s inside %[]

The only option I have left now is to regenerate the whole config and reload haproxy or look for some other reverse proxy (traefik might be a good fit) for this particular use case.

But there’s a workaround: https://www.mail-archive.com/haproxy@formilux.org/msg32845.html

http-request set-dst %[req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map)] if { req.hdr(host),lower,map_dom(/usr/local/etc/haproxy/domain2server.map) -m found }
1 Like