Core concepts
Map files
A map file contains a list of keys and values. From you load balancer configuration, you can look up a key to get its associated value. For example, you could look up which URL to use in a redirect or look up which backend to send a request to.
Map files are read at startup. After making a change to the map file, reload your load balancer configuration to put the changes into effect.
Map files for host-based routing Jump to heading
Map files help simplify complex configurations. A common example is host-based routing. In host-based routing, you choose which backend to send a request to based on the requested hostname. For example, the load balancer would relay requests for api.example.com
to the backend named apiservers
.
Here’s how it would work:
-
Create a map file on the load balancer, such as
hostnames.map
. Add keys and values, which in this case indicate the hostname and the name of thebackend
to use:hostnames.maptxtwww.example.com webserversapi.example.com apiserversstatic.example.com cacheservershostnames.maptxtwww.example.com webserversapi.example.com apiserversstatic.example.com cacheservers -
In the load balancer configuration, use a
map
converter to look up a value by its key.In this example we use the
req.hdr
fetch method to get theHost
request header and then pass it to themap
converter to look up the matching key in the filehostnames.map
. If a matching key exists in the file, the converter returns its value (such asapiservers
). Otherwise, it uses the default value,webservers
.haproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(/hostnames.map,webservers)]backend webserversserver s1 192.168.1.10:80 checkbackend apiserversserver s1 192.168.1.20:80 checkbackend cacheserversserver s1 192.168.1.30:80 checkhaproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(/hostnames.map,webservers)]backend webserversserver s1 192.168.1.10:80 checkbackend apiserversserver s1 192.168.1.20:80 checkbackend cacheserversserver s1 192.168.1.30:80 check
Map files for path-based routing Jump to heading
Another common use case for map files is path-based routing. In path-based routing, you choose which backend to send a request to based on the requested URL path. For example, requests to the path /cart
would go to the backend named cartservers
, while requests to /reviews
would go to the backend named reviewservers
.
Here’s how it would work:
-
Create a map file on the load balancer, such as
paths.map
. Add keys and values, which in this case indicate the URL path and the name of thebackend
to use:paths.maptxt/cart/ cartservers/review/ reviewserverspaths.maptxt/cart/ cartservers/review/ reviewservers -
In the load balancer configuration, use a
map_beg
converter to lookup a value by its key. A key that begins with the requested value will match.Below, we first get the requested URL path to use as the value. We do a lookup by using the
map_beg
converter, which passes the value into the given map file and looks for a matching key that begins with the value. If there is no matching key found in the map file, it uses the default valuewebservers
:haproxyfrontend wwwbind :80# Choose which backend depending on the URL pathuse_backend %[path,map_beg(/paths.map,webservers)]backend webserversserver s1 192.168.1.10:80 checkbackend cartserversserver s1 192.168.1.20:80 checkbackend reviewserversserver s1 192.168.1.30:80 checkhaproxyfrontend wwwbind :80# Choose which backend depending on the URL pathuse_backend %[path,map_beg(/paths.map,webservers)]backend webserversserver s1 192.168.1.10:80 checkbackend cartserversserver s1 192.168.1.20:80 checkbackend reviewserversserver s1 192.168.1.30:80 check
Map files for blue-green deployments Jump to heading
Limitations
This feature requires the HAProxy Runtime API, which is not available with HAProxy ALOHA.
In the blue-green deployment release model, you transfer traffic from a production backend, referred to as blue, to a new release, referred to as green. Use a map file and the Runtime API to manage this type of deployment.
-
Create a text file at
/bluegreen.map
with a single entry:bluegreen.maptextactive backend_bluebluegreen.maptextactive backend_blue -
Modify your configuration to include both a blue and a green backend and add a
use_backend
directive to your frontend to reference the map file. Whichever backend you set in the map file will be selected for all traffic.haproxyfrontend fe_mainbind :80use_backend %[str(active),map(/bluegreen.map)]backend backend_blueserver server1 10.0.0.3:80 checkserver server2 10.0.0.4:80 checkbackend backend_greenserver server1 10.0.0.5:80 checkserver server2 10.0.0.6:80 checkhaproxyfrontend fe_mainbind :80use_backend %[str(active),map(/bluegreen.map)]backend backend_blueserver server1 10.0.0.3:80 checkserver server2 10.0.0.4:80 checkbackend backend_greenserver server1 10.0.0.5:80 checkserver server2 10.0.0.6:80 check -
Use the Runtime API to modify the map to move traffic from blue to green as open connections to
backend_blue
close:nixecho "set map /bluegreen.map active backend_green" | socat stdio unix-connect:/var/run/hapee-3.0/hapee-lb.socknixecho "set map /bluegreen.map active backend_green" | socat stdio unix-connect:/var/run/hapee-3.0/hapee-lb.sock
Virtual and optional files Jump to heading
Available since
- HAProxy 3.0
- HAProxy ALOHA 16.5
- HAProxy Enterprise 3.0r1
The examples so far show how to define a map file that you save to your server’s filesystem. But you can also use virtual and optional map files, which can exist in memory.
-
A virtual file does not exist on disk and exists only in memory. The load balancer creates it as an in-memory representation during startup. Virtual files will not persist after restarting the load balancer.
-
When you mark a file as optional, the load balancer will check for it on the filesystem, but if it doesn’t find it, it will assume that the file is virtual. Optional files are useful for allowing startup without a file on disk, but saving the file to disk at a later time for long-term persistence.
To create a virtual file:
-
Prefix the filename with
virt@
. Here, we define a virtual map file namedhostnames.map
where the keys are hostnames and the values are the backends to route requests to for each hostname. The virtual file will exist only in memory:haproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(virt@hostnames.map)]haproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(virt@hostnames.map)] -
Use the Runtime API commands add map and del map to add or remove values from the virtual file.
In this example, we add the key-value pair
www.example.com webservers
to the virtual map filehostnames.map
:nixecho "add map virt@hostnames.map www.example.com webservers" | sudo socat stdio tcp4-connect:127.0.0.1:9999nixecho "add map virt@hostnames.map www.example.com webservers" | sudo socat stdio tcp4-connect:127.0.0.1:9999
To create an optional file:
-
Prefix the filename with
opt@
. Here, we define the samehostnames.map
file to route requests by hostname, but this time the file is optional. It can exist on the filesystem, but if not found will be loaded as a virtual, in-memory file:haproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(opt@hostnames.map)]haproxyfrontend wwwbind :80# Choose which backend depending on the Host headeruse_backend %[req.hdr(host),map(opt@hostnames.map)] -
Use the Runtime API commands add map and del map to add or remove values from the optional file. Note that you should not include the
opt@
prefix when updating optional files with the Runtime API.In this example, we add the key-value pair
www.example.com webservers
to the optional map filehostnames.map
:nixecho "add map hostnames.map www.example.com webservers" | sudo socat stdio tcp4-connect:127.0.0.1:9999nixecho "add map hostnames.map www.example.com webservers" | sudo socat stdio tcp4-connect:127.0.0.1:9999 -
Use the Runtime API to save the optional file to disk before reloading or restarting the load balancer. You can use the show map command. This command returns multiple columns, but you can use
awk
to get only the columns you want. Then direct the output to a file.In this example, we get the contents of the
hostnames.map
optional file with theshow map
command, useawk
to get only the second and third columns of the output, and then write the result to the filehostnames.map
:nixecho "show map hostnames.map" | sudo socat stdio tcp4-connect:127.0.0.1:9999 | awk '{print $2,$3}' > hostnames.mapnixecho "show map hostnames.map" | sudo socat stdio tcp4-connect:127.0.0.1:9999 | awk '{print $2,$3}' > hostnames.maphostnames.maptextwww.example.com webserversapi.example.com apiserversstatic.example.com cacheservershostnames.maptextwww.example.com webserversapi.example.com apiserversstatic.example.com cacheservers
Map converters Jump to heading
You access map files using the map
family of converters. A converter’s first argument is the path to the map file. Its second argument is optional and sets a default value. Variants of the map
converter allow a partial match of a key.
Match the beginning of a sample Jump to heading
The map_beg
converter matches the key against the beginning of the input sample. For instance, a requested URL path of /api/weather/midwest
would match the key /api/
in the map file.
routes.maptxt
/api/ apiservers/static/ cacheservers
routes.maptxt
/api/ apiservers/static/ cacheservers
Use the map_beg
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[path,map_beg(/routes.map)]
haproxy
frontend wwwbind :80use_backend %[path,map_beg(/routes.map)]
Match the end of a sample Jump to heading
The map_end
converter matches the key against the end of the input sample. For instance, a URL path /images/image.jpg
would match the key .jpg
in the map file.
filetypes.maptxt
.jpg cacheservers.png cacheservers
filetypes.maptxt
.jpg cacheservers.png cacheservers
Use the map_end
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[path,map_end(/filetypes.map)]
haproxy
frontend wwwbind :80use_backend %[path,map_end(/filetypes.map)]
Match a substring of a sample Jump to heading
The map_sub
converter matches a substring in the input sample. For instance, a URL path /shop/shirts/sale/
would match the key /shirts/
in the map file.
routes.maptxt
/shirts/ webservers1/pants/ webservers2
routes.maptxt
/shirts/ webservers1/pants/ webservers2
Use the map_sub
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[path,map_sub(/routes.map)]
haproxy
frontend wwwbind :80use_backend %[path,map_sub(/routes.map)]
Match an IP address Jump to heading
The map_ip
converter matches an IP address. If a key in the map file has a netmask (e.g. 192.168.0.0/16
), then the IP matches if it falls within the IP range.
ipranges.maptxt
10.0.0.0/16 eastcoast10.1.0.0/16 westcoast
ipranges.maptxt
10.0.0.0/16 eastcoast10.1.0.0/16 westcoast
Use the map_ip
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[src,map_ip(/ipranges.map)]
haproxy
frontend wwwbind :80use_backend %[src,map_ip(/ipranges.map)]
Match a domain Jump to heading
The map_dom
converter matches a domain or a part of a domain against a key. For instance, the key example.com
would match input samples example.com
, www.example.com
, or demo.example.com
.
domains.maptxt
example.com webservers1test.com webservers2
domains.maptxt
example.com webservers1test.com webservers2
Use the map_dom
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[req.hdr(host),map_dom(/domains.map)]
haproxy
frontend wwwbind :80use_backend %[req.hdr(host),map_dom(/domains.map)]
Match a regular expression Jump to heading
The map_reg
converter matches the input sample based on a regular expression. For instance, the regular expression ^(\/sale\/).*(\.jpg)$
would match a URL that begins with /sale/
and ends with .jpg
.
patterns.maptxt
^(\/sale\/).*(\.jpg)$ cacheservers
patterns.maptxt
^(\/sale\/).*(\.jpg)$ cacheservers
Use the map_reg
converter in your configuration:
haproxy
frontend wwwbind :80use_backend %[path,map_reg(/patterns.map)]
haproxy
frontend wwwbind :80use_backend %[path,map_reg(/patterns.map)]
See also Jump to heading
Do you have any suggestions on how we can improve the content of this page?