# Pool member failback

**URL:** <https://community.f5.com/t/pool-member-failback/21028>\
**Category:** Technical Forums\
**Tags:** irules, ltm, application-delivery, pool\
**Created:** [August 18, 2016, 1:50pm UTC](https://community.f5.com/t/pool-member-failback/21028 "2016-08-18T13:50:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kram\_259300](https://avatars.discourse-cdn.com/v4/letter/k/7ba0ec/32.png) [@Kram\_259300](https://community.f5.com/u/Kram_259300)\
**Post date:** [August 18, 2016, 1:50pm UTC](https://community.f5.com/t/pool-member-failback/21028/1 "2016-08-18T13:50:48Z")

</div>

I have a requirement to select pool member based on the availability.

Primary pool has 4 servers & backup pool has 2 servers. I know failover can be triggered based on the prioriy group or writing an iRULE to verify the availablility using [LB::server pool]. But there is a catch on the failback from backup to primary pool should be triggered when all the 4 servers are active on the primary. Do you guys have any idea how this can be done?

Failover when 3 server fails in primary pool and failback when all severs are available in primary pool.

---

<div class="post-metadata">

**Author:** ![jgranieri](https://avatars.discourse-cdn.com/v4/letter/j/fbc32d/32.png) [@jgranieri](https://community.f5.com/u/jgranieri)\
**Post date:** [August 18, 2016, 2:34pm UTC](https://community.f5.com/t/pool-member-failback/21028/2 "2016-08-18T14:34:20Z")

</div>

so the only way you can achieve this is via irule. You virtual server will use an irule to determine which pool to use. So your irule will need a line like this to determine when to use the Primary pool or backup pool.

```tcl
if { [active_members [LB::server pool] ] = 4 } { 
       pool primary "   
     } else { 
        pool backup

```

---

<div class="post-metadata">

**Author:** ![Kai\_Wilke](https://d1p9zq3aats0t8.cloudfront.net/user_avatar/community.f5.com/kai_wilke/32/24646_2.png) [@Kai\_Wilke](https://community.f5.com/u/Kai_Wilke)\
**Post date:** [August 18, 2016, 4:16pm UTC](https://community.f5.com/t/pool-member-failback/21028/3 "2016-08-18T16:16:04Z")

</div>

Hi Kram,

you may use the iRule below as a starting point. The iRule uses the **table** command to switch between a primary/backup mode to be able to apply different rule sets…

```tcl
when RULE_INIT {
    set static::primary_pool "pool_a"
    set static::backup_pool "pool_b"
}
when CLIENT_ACCEPTED {
     Check session table if backup mode is currently active
    if { [table lookup "status_$static::primary_pool"] eq "backup" } then {
         Backup mode is currently active. Applying Backup mode availability requirements. Check if primary pool has equal or more than 4 members.
        if { [active_members "$static::primary_pool"] >= 4] } then {
              Primary pool has equal or more than 4 members. Switching back to primary pool and disable Backup mode.
            table delete "status_$static::primary_pool"
            pool "$static::primary_pool"
        } else {
              Primary pool has less than 4 members. Using backup pool and keeping Backup mode active...
            pool "$static::backup_pool"
        }
         Exit the script...
        return
    }
     Backup mode is currently not active (default). Applying normal availability requirements. Check if primary pool has more than 1 members.
    if { [active_members "$static::primary_pool"] > 1] } then {
          Primary pool more than 1 member. Using primary pool and keeping Backup mode disabled...
        pool "$static::primary_pool"
    } else {
          Primary pool less than 2 available member. Using the backup pool and enable Backup mode in session table...
        table add "status_$static::primary_pool" "backup" indefinite indefinite 
        pool "$static::backup_pool"
    }   
}

```

_ **Update:** Changed the order of the script to make it easier to understand. Added additional comments, to explain what the purpose of each line is…_

Cheers, Kai

---

<div class="post-metadata">

**Author:** ![BinaryCanary\_19](https://avatars.discourse-cdn.com/v4/letter/b/c2a13f/32.png) [@BinaryCanary\_19](https://community.f5.com/u/BinaryCanary_19)\
**Post date:** [September 2, 2016, 1:16pm UTC](https://community.f5.com/t/pool-member-failback/21028/4 "2016-09-02T13:16:58Z")

</div>

Hi guys,

the following irule logic inspired by some of the comments above, seems a bit neater and should do the trick. You will need to adjust the pool names and pool member counts as required, and you can of course perform more complex calculations if you prefer.

I did some basic testing, but i can’t promise i caught all potential errors, so make sure to give it a whirl in a test environment first.

```tcl
when RULE_INIT {
    set static::pp "webpool" 
    set static::bp "backupwebpool" 
    set static::flag "flag"
}

when CLIENT_ACCEPTED {
    if { [table lookup $static::flag] eq "backup" && [active_members $static::pp] < 1 } {
        we're in backup mode 
        log local0. "backup mode"
        pool $static::bp

    }elseif { [active_members $static::pp] >= 1} {
       active mode
        log local0. "going back to active mode"
        table set $static::flag "active"
        pool $static::pp

    }else {
        backup mode needs to be enabled
        log local0. "enabling backup mode"
        table set $static::flag "backup"
        pool $static::bp
    }
}

```

---

<div class="post-metadata">

**Author:** ![BinaryCanary\_19](https://avatars.discourse-cdn.com/v4/letter/b/c2a13f/32.png) [@BinaryCanary\_19](https://community.f5.com/u/BinaryCanary_19)\
**Post date:** [September 2, 2016, 1:39pm UTC](https://community.f5.com/t/pool-member-failback/21028/5 "2016-09-02T13:39:12Z")

</div>

also, might be worth looking into priority group activation, a feature of pools that can do something similar to this without needing irules, and with probably better handling of cases like persistence than this irule.

---

<div class="post-metadata">

**Author:** ![Kai\_Wilke](https://d1p9zq3aats0t8.cloudfront.net/user_avatar/community.f5.com/kai_wilke/32/24646_2.png) [@Kai\_Wilke](https://community.f5.com/u/Kai_Wilke)\
**Post date:** [September 2, 2016, 2:39pm UTC](https://community.f5.com/t/pool-member-failback/21028/6 "2016-09-02T14:39:48Z")

</div>

Hi FKnuckles,

I’m a big fan of the Priority Based Activation feature, but unfortunately you can’t use this feature for the given requirement (different availability thresholds for failover and failback).

Well, you’re code uses just 3 instead of 4 different conditions and looks therefor indeed much cleaner. But on the other hand it does not cover the requirements of the OP and produces a slightly higher overhead. Let me try to compare the different iRules…

_ **Active Operation Scenario** _

Your code:

```tcl
if [table lookup $static::flag] eq "backup"
if [active_members $static::pp] >= 1
table set $static::flag "active"
pool $static::pp

```

My Code:

```tcl
if [table lookup "status_$static::primary_pool"] eq "backup" 
if [active_members "$static::primary_pool"] > 1]
pool "$static::primary_pool"

```

Performance Difference: Your code requires one additional table command execution.

Functional Difference: None

_ **Active Operation Failover Scenario** _

Your code:

```tcl
if [table lookup $static::flag] eq "backup"
if [active_members $static::pp] >= 1
table set $static::flag "backup"
pool $static::bp

```

My Code:

```tcl
if [table lookup "status_$static::primary_pool"] eq "backup" 
if [active_members "$static::primary_pool"] > 1]
table add "status_$static::primary_pool" "backup" indefinite indefinite 
pool "$static::backup_pool"

```

Performance Differences: None

Functional Difference: None

_ **Backup Operation Scenario** _

Your code:

```tcl
if [table lookup $static::flag] eq "backup"
if [active_members $static::pp] < 1
pool $static::bp

```

My Code:

```tcl
if [table lookup "status_$static::primary_pool"] eq "backup" 
if { [active_members "$static::primary_pool"] >= 4]
pool "$static::backup_pool"

```

Performance Differences: None

Functional Difference: The OPs requirement is not covered. The requirement for triggering the failback is **[active\_members $static::pp] = 4** nodes.

_ **Backup Operation Failback Scenario** _

Your code:

```tcl
if [table lookup $static::flag] eq "backup"
if [active_members $static::pp] < 1
if [active_members $static::pp] >= 1
table set $static::flag "active"
pool $static::pp

```

My Code:

```tcl
if [table lookup "status_$static::primary_pool"] eq "backup" 
if { [active_members "$static::primary_pool"] >= 4]
table delete "status_$static::primary_pool"
pool "$static::primary_pool"

```

Performance Differences: Your code requires one additional **[active\_members $static::pp]** command execution.

Functional Difference: The OPs requirement is not covered.

Cheers, Kai

---

<div class="post-metadata">

**Author:** ![BinaryCanary\_19](https://avatars.discourse-cdn.com/v4/letter/b/c2a13f/32.png) [@BinaryCanary\_19](https://community.f5.com/u/BinaryCanary_19)\
**Post date:** [September 2, 2016, 3:01pm UTC](https://community.f5.com/t/pool-member-failback/21028/7 "2016-09-02T15:01:57Z")

</div>

Hi Kai,

First off, Thanks for posting your original irule. I believe you solved the OP’s question, which is much appreciated. This wasn’t really a critique of your irule. The context in which I made this version was just expressly to improve readability for a different person who actually drew their inspiration from your solution. I did not attempt to tweak for performance in any way, and I posted this here just as a way of sharing an alternative version since the work was already done.

I also didn’t attempt to use the OP’s numbers, understanding being that the user will place the numbers they desire.

Talking of performance, strictly speaking, the “table set $static::flag active” is completely unnecessary in my version, as the “active” value is never really used. That’s one quick optimisation that I spotted.

Going further, the table set is probably totally unnecessary in fact, considering that the fallback to active pool always happens whenever the active pool is healthy. My version looks like this because I basically just took yours and tried to improve readability. I didn’t approach OP’s question from clean slate. It is possible that a simple solution could be devised where you simply need an

```markup
if [primary pool available members less than 4] then 
    backup; 
Else: 
    primary;

```

---

<div class="post-metadata">

**Author:** ![Kai\_Wilke](https://d1p9zq3aats0t8.cloudfront.net/user_avatar/community.f5.com/kai_wilke/32/24646_2.png) [@Kai\_Wilke](https://community.f5.com/u/Kai_Wilke)\
**Post date:** [September 2, 2016, 4:28pm UTC](https://community.f5.com/t/pool-member-failback/21028/8 "2016-09-02T16:28:12Z")

</div>

Hi F5Knuckles,

I didn’t recognized your answer as a critique towards my irule. I was just interested in a technical discussion, to explain the pros and cons of the different coding styles… 🙂

Cheers, Kai

---

<div class="post-metadata">

**Author:** ![PeterP79\_360635](https://avatars.discourse-cdn.com/v4/letter/p/f6c823/32.png) [@PeterP79\_360635](https://community.f5.com/u/PeterP79_360635)\
**Post date:** [July 20, 2018, 9:13am UTC](https://community.f5.com/t/pool-member-failback/21028/9 "2018-07-20T09:13:28Z")

</div>

Hello

I used the script/irule that Kai posted and works great (thank you Kai). But I notice if the connection/session is permanent, the irule doesn’t work. I think I should use “reject” command, but I have no luck with write the right irule. Thank you in advance for any help.

Peter

---

<div class="post-metadata">

**Author:** ![kridsana](https://avatars.discourse-cdn.com/v4/letter/k/d2c977/32.png) [@kridsana](https://community.f5.com/u/kridsana)\
**Post date:** [July 20, 2018, 10:02am UTC](https://community.f5.com/t/pool-member-failback/21028/10 "2018-07-20T10:02:49Z")

</div>

Hi

I know it’s old thread and the job is done but i wish to know if my method is possible. 😃

Is it possible to create 2 pool (Primary pool have 4 member, Backup pool have 6 member)

then assign Primary pool as Default pool and write irule like this

if [active\_member Primary\_pool \< 4] { pool Backup\_pool }
