iRules Recipe 3: Pool and SNAT Selection by Host Header Value
The Problem
You manage a number of web sites, and they are spread across servers in several different pools. You want to use a single public IP for all of these, so you need to make a pool selection based on the incoming Host header value. Moreover, one pool requires SNAT but the others do not. Finally, you need persistence for all landing sites but one.
The Configuration
ltm virtual vs-websites { destination 203.0.113.10:http ip-protocol tcp mask 255.255.255.255 persist { cookie { } } pool default-web-pool profiles { http { } tcp { } } rules { by-host-pool-selector } }
The Code
when HTTP_REQUEST { switch [string tolower [HTTP::host]] { "www.great-app.com" - "great-app.com" { pool great-app-pool } "dev.great-app.com" { pool great-app-dev-pool snat automap } "www.fun-app.org" - "fun-app.org" - { pool fun-app-pool persist none } } }
Analysis
Notice that the Virtual Server to which this rule is applied does not have SNAT enabled, but does have Cookie Persistence enabled. The
switch
command's first argument normalizes the Host header value, changing it to all lower-case. See the "Analysis" section in iRule Recipe 1 to understand why this is necessary when performing comparisons on the Host header. If the (lower-case normalized) Host header has the value "www.great-app.com" or "great-app.com", then the pool selected will be "great-app-pool" (rather than the pool configured on the attached Virtual Server, which in this example is called "great-app-pool"). Notice that, if this branch is followed, then Cookie Persistence applies (because it is defined on the Virtual Server and this condition doesn't disable it) and SNAT is not used (because no SNAT is configured on the Virtual Server and it is not enabled in this code branch). To understand why the first matching case has a dash (-), and why that means this match uses the code for the following case, refer to the "Analysis" section of iRule Recipe 2. If the Host header has the value "dev.great-app.com", then the pool is "great-app-dev-pool" and Automap SNAT is enabled. Notice that, once again Cookie persistence applies in this case because it is defined on the Virtual Server, and is not disabled in the code. If the Host header is "www.fun-app.org" or "fun-app.org", then the pool used will be "fun-app-pool". In this case, the Cookie persistence is disabled (because of persist none
), which means that no persistence will apply. Moreover, SNAT is not used because it is not configured on the Virtual Server and is not activated in the code. If the Host header matches none of these conditions, then the pool will be "default-web-pool", there will be no SNAT, and Cookie persistence will apply. That's because these are all configured on the Virtual Server, and no code overrides these settings.
Elaboration
In Recipe 2, I used the -glob flag with the
switch
command. Notice that I do not do so here. The -glob flag makes the switch
slower (that is, it takes more processing cycles). So, if you are performing only exact string matching (and specifically, are not using glob-style matchers), then omit the -glob flag. Notice that the persist
command can be used to enable or change persistence. This is beyond the scope of this article, but it's worth noting. Moreover, the snat
command can be used to disable Automap SNAT, or it can be used to specify a specific SNAT address (and, optionally, port). If, however, you want to use a SNAT pool, use the snatpool
command. However, if a SNAT pool is assigned to the Virtual Server, and you want to disable it for a particular condition, then you would still use snat none
to disable use of the SNAT pool.- kdkapildhamija_Nimbostratus
can you please tell me irules is written in which language?
- VernonWellsEmployee
iRules is a Tcl dialect. It supports a subset of the language, but also adds BIG-IP specific commands and operators.
- nov1ce_120072Nimbostratus
Thank you! And to extend it - how to perform http to https redirection at the same time? We do this with the following iRule attached to the VIP:
when HTTP_REQUEST { HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri] }
Do we need to keep it as a second iRule?
- VernonWellsEmployee
For a given incoming request, you can either redirect or perform pool selection, but not both. That's because a redirect is a direct response from the BIG-IP platform to the client, and there is only a client flow, whereas pool selection specifies the destination for the server-side flow.