Synopsis
Let’s take a web application platform where many HTTP Host header points to.
Of course, this platform hosts many backends and HAProxy is used to perform content switching based on the Host header to route HTTP traffic to each backend.
HAProxy map
HAProxy 1.5 introduced a cool feature: converters. One converter type is map.
Long story made short: a map allows to map a data in input to an other one on output.
A map is stored in a flat file which is loaded by HAProxy on startup. It is composed by 2 columns, on the left the input string, on the right the output one:
in out
Basically, if you call the map above and give it the in strings, it will return out.
Mapping
Now, the interesting part of the article 🙂
As stated in introduction, we want to map hundreds of Host headers to tens of backends.
The old way of mapping: acl and use_backend rules
Before the map, we had to use acls and use_backend rules.
like below:
frontend ft_allapps [...] use_backend bk_app1 if { hdr(Host) -i app1.domain1.com app1.domain2.com } use_backend bk_app2 if { hdr(Host) -i app2.domain1.com app2.domain2.com } default_backend bk_default
Add one statement per use_backend rule.
This works nicely for a few backends and a few domain names. But this type of configuration is hardly scallable…
The new way of mapping: one map and one use_backend rule
Now we can use map to achieve the same purpose.
First, let’s create a map file called domain2backend.map, with the following content: on the left, the domain name, on the right, the backend name:
#domainname backendname app1.domain1.com bk_app1 app1.domain2.com bk_app1 app2.domain1.com bk_app2 app2.domain2.com bk_app2
And now, HAProxy configuration:
frontend ft_allapps [...] use_backend %[req.hdr(host),lower,map_dom(/etc/hapee-1.5/domain2backend.map,bk_default)]
Here is what HAProxy will do:
- req.hdr(host) ==> fetch the Host header from the HTTP request
- lower ==> convert the string into lowercase
- map_dom(/etc/hapee-1.5/domain2backend.map) ==> look for the lowercase Host header in the map and return the backend name if found. If not found, the name of a default backend is returned
- route traffic to the backend name returned by the map
Now, adding a new content switching rule means just add one new line in the map content (and reload HAProxy). No regexes, map data is stored in a tree, so processing time is very low compared to matching many string in many ACLs for many use_backend rules.
simple is beautiful!!!
HAProxy map content auto update
If you are an HAProxy Enterprise user (and soon available for the ALOHA), you can use the lb-update content to download the content of the map automatically.
Add the following statement in your configuration:
dynamic-update update id domain2backend.map url https://10.0.0.1/domain2backend.map delay 60s timeout 5s retries 3 map