I discovered recently that you can match a backend dynamically, based on the request hostheader, like this:
use_backend %[req.hdr(host),lower]
However, does anyone know any way I could use the subdomain of the request hostheader to match the backend?
E.g. something along these lines:
backend one
backend two
use_backend %[<SUBDOMAIN OF HOSTHEADER>,lower]
which would match like this:
one.example.com -> backend one
two.example.com -> backend two
Adding and removing DNS entries allows you to route subdomains to various backends on the fly, buy you still need to define those backends so there's still a service restart. As such, I'm not entirely sure of the usefulness of this config.
In any event, here's how you'd do it.
We know we can find the contents of the
host
header, by using req.hdr (req.hdr(host)
), but that gives us the FQDN of the request, not the subdomain.Thankfully, there's a regsub converter we should be able to apply to the
req.hdr
sample to clip off the base domain and TLD.The emphasis in that quote is mine and aims to show that in this case, where the regex you'd need is
^(.*)(?:\..*){2}$
, it won't work because of the parenthesis.Thus, you'll need to use the field converter.
If we put the whole sample pipline together, the
use_backend
line looks like:Now, this opens up the fact that
one.*.*
will go to the same backend, and could lead to some very weird situations.It might make some sense to check the base domain and TLD to ensure they're what you expect. Assuming you've only got two (
example.com
andfoo.com
) of them, you'd usereq.hdr_end(host)
to check for them, making the ACL look like:And if we put it all together, the whole config would look something like this:
You can get even fancier if you want by having different "dynamic" backends for each sub-domain, per base domain; you'd just need to use the pieces above to work that out.
As far as I know, HAProxy doesn't have regex support to extract specific part of the subdomain from the Host header and then assign that value to a variable, which is later used to form complete backend name.
However, you one way to solve your problem would be to use mapping:
The content of
/etc/haproxy/subdomains.map
would look like this:All requests that don't match any of the subdomains in that file will go to
backend_main
backend.