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.