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:

  1. 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 the backend to use:

    hostnames.map
    txt
    www.example.com webservers
    api.example.com apiservers
    static.example.com cacheservers
    hostnames.map
    txt
    www.example.com webservers
    api.example.com apiservers
    static.example.com cacheservers
  2. 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 the Host request header and then pass it to the map converter to look up the matching key in the file hostnames.map. If a matching key exists in the file, the converter returns its value (such as apiservers). Otherwise, it uses the default value, webservers.

    haproxy
    frontend www
    bind :80
    # Choose which backend depending on the Host header
    use_backend %[req.hdr(host),map(/hostnames.map,webservers)]
    backend webservers
    server s1 192.168.1.10:80 check
    backend apiservers
    server s1 192.168.1.20:80 check
    backend cacheservers
    server s1 192.168.1.30:80 check
    haproxy
    frontend www
    bind :80
    # Choose which backend depending on the Host header
    use_backend %[req.hdr(host),map(/hostnames.map,webservers)]
    backend webservers
    server s1 192.168.1.10:80 check
    backend apiservers
    server s1 192.168.1.20:80 check
    backend cacheservers
    server 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:

  1. 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 the backend to use:

    paths.map
    txt
    /cart/ cartservers
    /review/ reviewservers
    paths.map
    txt
    /cart/ cartservers
    /review/ reviewservers
  2. 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 value webservers:

    haproxy
    frontend www
    bind :80
    # Choose which backend depending on the URL path
    use_backend %[path,map_beg(/paths.map,webservers)]
    backend webservers
    server s1 192.168.1.10:80 check
    backend cartservers
    server s1 192.168.1.20:80 check
    backend reviewservers
    server s1 192.168.1.30:80 check
    haproxy
    frontend www
    bind :80
    # Choose which backend depending on the URL path
    use_backend %[path,map_beg(/paths.map,webservers)]
    backend webservers
    server s1 192.168.1.10:80 check
    backend cartservers
    server s1 192.168.1.20:80 check
    backend reviewservers
    server 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.

  1. Create a text file at /bluegreen.map with a single entry:

    bluegreen.map
    text
    active backend_blue
    bluegreen.map
    text
    active backend_blue
  2. 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.

    haproxy
    frontend fe_main
    bind :80
    use_backend %[str(active),map(/bluegreen.map)]
    backend backend_blue
    server server1 10.0.0.3:80 check
    server server2 10.0.0.4:80 check
    backend backend_green
    server server1 10.0.0.5:80 check
    server server2 10.0.0.6:80 check
    haproxy
    frontend fe_main
    bind :80
    use_backend %[str(active),map(/bluegreen.map)]
    backend backend_blue
    server server1 10.0.0.3:80 check
    server server2 10.0.0.4:80 check
    backend backend_green
    server server1 10.0.0.5:80 check
    server server2 10.0.0.6:80 check
  3. Use the Runtime API to modify the map to move traffic from blue to green as open connections to backend_blue close:

    nix
    echo "set map /bluegreen.map active backend_green" | socat stdio unix-connect:/var/run/hapee-2.9/hapee-lb.sock
    nix
    echo "set map /bluegreen.map active backend_green" | socat stdio unix-connect:/var/run/hapee-2.9/hapee-lb.sock

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.map
txt
/api/ apiservers
/static/ cacheservers
routes.map
txt
/api/ apiservers
/static/ cacheservers

Use the map_beg converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[path,map_beg(/routes.map)]
haproxy
frontend www
bind :80
use_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.map
txt
.jpg cacheservers
.png cacheservers
filetypes.map
txt
.jpg cacheservers
.png cacheservers

Use the map_end converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[path,map_end(/filetypes.map)]
haproxy
frontend www
bind :80
use_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.map
txt
/shirts/ webservers1
/pants/ webservers2
routes.map
txt
/shirts/ webservers1
/pants/ webservers2

Use the map_sub converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[path,map_sub(/routes.map)]
haproxy
frontend www
bind :80
use_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.map
txt
10.0.0.0/16 eastcoast
10.1.0.0/16 westcoast
ipranges.map
txt
10.0.0.0/16 eastcoast
10.1.0.0/16 westcoast

Use the map_ip converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[src,map_ip(/ipranges.map)]
haproxy
frontend www
bind :80
use_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.map
txt
example.com webservers1
test.com webservers2
domains.map
txt
example.com webservers1
test.com webservers2

Use the map_dom converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[req.hdr(host),map_dom(/domains.map)]
haproxy
frontend www
bind :80
use_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.map
txt
^(\/sale\/).*(\.jpg)$ cacheservers
patterns.map
txt
^(\/sale\/).*(\.jpg)$ cacheservers

Use the map_reg converter in your configuration:

haproxy
frontend www
bind :80
use_backend %[path,map_reg(/patterns.map)]
haproxy
frontend www
bind :80
use_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?