HAProxy override backend cookie using query parameter

haproxy

Based on this answer, I can successfully override the backend with a query parameter:

backend servers
  balance roundrobin
  cookie SERVERID insert indirect nocache
  use-server web1 if { urlp(SERVERID) -i web1 }
  use-server web2 if { urlp(SERVERID) -i web2 }
  server web1 web1-internal:80 check cookie web1
  server web2 web2-internal:80 check cookie web2

However, I would like for this to "persist" in subsequent requests; i.e. I want a new Set-Cookie with the value from the query parameter to overwrite any existing SERVERID cookies. HAProxy doesn't add a Set-Cookie if the request came in with a valid SERVERID Cookie. Removing the indirect option didn't work.

Is the only solution to use preserve and have the backend always respond with Set-Cookie, or is there a way to do this in HAProxy?

Best Answer

I did this by creating new backends that set the SERVERID cookie and routing to them via frontend directives.

frontend http_in
  acl set_current_site_cookie urlp(current_site) true
  acl set_snapshot_site_cookie urlp(snapshot_site) true

  bind *:80
  use_backend set_current_site_cookie if set_current_site_cookie
  use_backend set_snapshot_site_cookie if set_snapshot_site_cookie
  default_backend servers

backend set_current_site_cookie
  cookie SERVERID insert
  server current_site server.com:80 cookie current_site

backend set_snapshot_site_cookie
  cookie SERVERID insert
  server snapshot_site snapshot-server:80 cookie snapshot_site

backend servers
  cookie SERVERID insert indirect nocache
  server current_site server.com:80 cookie current_site weight 50
  server snapshot_site snapshot-server:80 cookie snapshot_site weight 50

We use this for staged rollouts, setting the weight in the servers backend to 0, and then testing using the query param current_site=true.