So, you've probably read all about the BIG-IP LTM VE.  You've gone through the download process and got the thing configured and running in VMWare.  You've even gone through the initial configuration steps to get the management port configured and got the thing licensed up.  Now what?  Well, we've got a bunch of examples of firing up separate VM instances of host operating systems so that you can test creating pools of servers with those other VM instances.  The problem there is that running those VM's is costly in RAM and CPU.

Being a developer, my first thought was how I could make use of my existing development environment with Visual Studio and IIS on the laptop that is hosting the LTM VE virtual machine.  Why should I have to create a new VM instance of Windows and incur the overhead of running that extra VM?  Well, you don't! 

In this article, I'm going to show you how to build a full client-server environment utilizing only the laptop's host operating system and a single LTM VE instance.

Configuring IIS

The first step is to configure a web application.  You could use any web server you desire (apache, tomcat, etc) but I'll use IIS since I'm already using it to debug applications I've written with Microsoft Visual Studio .NET.  Below is the IIS 7 admin console running under Windows 7.  The main trick here, is to make sure that the site bindings for your app will accept all ip addresses.  That way requests coming from the internal VMWare interface will be able to handle the requests.


The Web Application

For this example, I'm going to go old school and write a simple .asp (HTML) page with no server side processing.  Requests to the Default Web Site in IIS will return the contents of this file.


Creating your VM

I'm going to assume for this article, that you already have VMWare Workstation or Server installed and that you have got your BIG-IP LTM-VE fired up and licensed.  If you don't, there are several walkthroughs here on DevCentral that will help you get going.

VMWare sets up several network adapters.  We are going to make use of two of those interfaces to act as the external and internal networks for the LTM.  By configuring IIS to handle requests from all addresses, this means we can create a pool member pointing to the internal network here.  In this example is my external network and is my internal network address that will act as a pool member.


Provisioning your LTM-VE

Now, I could go and document all of the steps needed to create the objects on the LTM needed to successfully deploy the application but that wouldn't be any fun, plus it wouldn't let me show off my iControl PowerShell integration.

I've written a deployment iControl PowerShell script that will go through the process of configuring VLANs and SelfIPs, creating a pool with the internal host NIC as a pool member with it's associated health monitors, creating the Virtual Server, and, just for fun, an iRule that will modify the response content from IIS back to the browser.

Here's the output of the script.  I'll describe the pieces below.


Create VLANs

A default LTM-VE configuration has no objects created so the first step is configuring VLAN for the external and internal networks.  The code below can be used to create the "external" and "internal" VLANs.  In my example the external VLAN is configured with the 1.1 interface as untagged (corresponding to the external VMWare NIC) and the internal VLAN using interface 1.2 (corresponding to the internal VMWare NIC).

   1: function Create-VLAN()
   2: {
   3:   param([string]$name, [long]$id, [string]$member_name);
   5:   # Create VLAN
   6:   $vlans = (, $name);
   7:   $vlan_ids = (, $id);
   8:   $member = New-Object -TypeName iControl.NetworkingVLANMemberEntry;
   9:   $member.member_name = $member_name
  10:   $member.member_type = "MEMBER_INTERFACE";
  11:   $member.tag_state = "MEMBER_UNTAGGED"
  12:   $memberA = (, $member);
  13:   $memberAofA = (, $memberA);
  14:   $failsafe_states = (, "STATE_DISABLED");
  15:   $timeouts = (, 1500);
  16:   $mac_masquerade = (, "");
  18:   (Get-F5.iControl).NetworkingVLAN.create(
  19:     $vlans, $vlan_ids, $memberAofA,
  20:     $failsafe_states, $timeouts, $mac_masquerade);
  21: }

Looking in the BIG-IP GUI, the following VLANs were created.


Create SelfIPs

Now that the VLANs have been created, Self IP Addresses must be configured for those VLANs so that the LTM can communicate with the laptop network interfaces.  The following code is used to create two SelfIPs ( for the internal VLAN, and for the external VLAN).

   1: function Create-SelfIP()
   2: {
   3:   param([string]$address, [string]$vlan);
   5:   $self_ips = (, $address);
   6:   $vlan_names = (, $vlan);
   7:   $netmasks = (, "");
   8:   $unit_ids = (, 0);
   9:   $floating_states = (, "STATE_DISABLED");
  10:   (Get-F5.iControl).NetworkingSelfIP.create(
  11:     $self_ips, $vlan_names, $netmasks,
  12:     $unit_ids, $floating_states
  13:   );
  14: }

And again, the BIG-IP GUI shows the two Self IPs for the two VLANs.


Create Pool

The previous two steps were to ensure the lower networking layer was in place to allow connections from the upcoming generated Virtual Server as well as the defined pool members.  The next step is to create a pool with a pool member of the internal VMWare NIC address (  In this code, the pool is created and I've associated two health check monitors on the pool member.  In this case I'm using the standard http and gateway_icmp monitors.  You can modify these to suit your taste.

   1: function Create-Pool()
   2: {
   3:   param([string]$name, [string]$member_ip, [long]$member_port);
   5:   $pool_list = (Get-F5.iControl).LocalLBPool.get_list();
   6:   if ( -not (Is-InList -search $name -list $pool_list) )
   7:   {
   8:     $pool_names = (, $name);
   9:     $lb_methods = (, "LB_METHOD_ROUND_ROBIN");
  10:     $member = New-Object -TypeName iControl.CommonIPPortDefinition;
  11:     $member.address = $member_ip;
  12:     $member.port = $member_port;
  13:     $memberA = (, $member);
  14:     $memberAofA = (, $memberA);
  16:     Write-Host "Creating Pool `"$name`"...";
  17:     (Get-F5.iControl).LocalLBPool.create($pool_names, $lb_methods, $memberAofA);
  19:     $monitor_association = New-Object -TypeName iControl.LocalLBPoolMonitorAssociation;
  20:     $monitor_association.pool_name = $name;
  21:     $monitor_association.monitor_rule = New-Object -TypeName iControl.LocalLBMonitorRule;
  22:     $monitor_association.monitor_rule.type = "MONITOR_RULE_TYPE_AND_LIST";
  23:     $monitor_association.monitor_rule.quorum = 1;
  24:     $monitor_association.monitor_rule.monitor_templates = ("http", "gateway_icmp");
  25:     $monitor_associations = (, $monitor_association);
  27:     Write-Host "Assigning monitors to Pool `"$name`"...";
  28:     (Get-F5.iControl).LocalLBPool.set_monitor_association($monitor_associations);
  29:   }
  30: }

And again, the BIG-IP GUI shows the generated Pool with the single defined member.  Oh, and as a bonus, we have a Green Circle status which means the health checks succeeded and we're ready to go!


Create Virtual Server

Now that the application pool is created, the virtual server is configured to give an IP address you can use to test the IIS application.  The Virtual Server creation process involves specifying virtual server configuration as well as a list of profiles to associate with the virtual.  In this example, I'm using the stock "http" profile and as an added bonus, I've added in the "stream" profile so that my upcoming iRule will be able to do some content replacement.

   1: function Create-Virtual()
   2: {
   3:   param([string]$name, [string]$ip, [long]$port, [string]$pool);
   4:   $vs_list = (Get-F5.iControl).LocalLBVirtualServer.get_list();
   5:   if ( -not (Is-InList -search $name -list $vs_list) )
   6:   {
   7:     $definition = New-Object -TypeName iControl.CommonVirtualServerDefinition;
   8:     $ = $name;
   9:     $definition.address = $ip;
  10:     $definition.port = $port;
  11:     $definition.protocol = "PROTOCOL_TCP";
  12:     $definitions = (, $definition);
  13:     $wildmasks = (, "");
  14:     $resource = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerResource;
  15:     $resource.type = "RESOURCE_TYPE_POOL";
  16:     $resource.default_pool_name = $pool;
  17:     $resources = (, $resource);
  18:     $profile = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerProfile;
  19:     $profile.profile_context = "PROFILE_CONTEXT_TYPE_ALL";
  20:     $profile.profile_name = "http";
  21:     $profile2 = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerProfile;
  22:     $profile2.profile_context = "PROFILE_CONTEXT_TYPE_ALL";
  23:     $profile2.profile_name = "stream";
  24:     $profileA = ($profile2, $profile);
  25:     $profileAofA = (, $profileA);
  27:     Write-Host "Creating Virtual Server `"$name`"...";
  29:     (Get-F5.iControl).LocalLBVirtualServer.create($definitions, $wildmasks, $resources, $profileAofA);
  31:     Write-Host "Enabling SNAT Automap on Virtual Server `"$name`"...";
  32:     (Get-F5.iControl).LocalLBVirtualServer.set_snat_automap( (, $name) );
  33:   }
  34: }

You'll see the Virtual Server has been created with a destination address of which coincides with the "external" VLAN and external VMWare NIC.


Create iRules

Now, this isn't necessarily needed for this deployment but I figured I'd throw something in to prove that traffic is actually going through the LTM and get you an iRule to start with.  The follow code will create an iRule that does a stream replacement in the HTTP response from IIS.  It converts all occurrences of "Test" with "Test (Modified by iRule)".  This way we can tell from our client testing that the iRule is getting processed.

After the iRule is created, it is assigned to the Virtual Server with the LocalLB.VirtualServer.add_rule method.

   1: function Create-iRule()
   2: {
   3:   param([string]$virtual, [string]$rule_name);
   5:   $rule_list = (Get-F5.iControl).LocalLBRule.get_list();
   6:   if ( -not (Is-InList -search $rule_name -list $rule_list) )
   7:   {
   8:     $rule = New-Object -TypeName iControl.LocalLBRuleRuleDefinition;
   9:     $rule.rule_name = $rule_name;
  10:     $rule.rule_definition = @"
  11: when HTTP_REQUEST {
  12:   log local0. "Request for URI: [HTTP::uri]";
  13: }
  14: when HTTP_RESPONSE {
  15:   log local0. "Response [HTTP::status]";
  16:   STREAM::expression "@Test@Test (Modified by iRule)@";
  17:   STREAM::enable;
  18: }
  19: "@;
  20:     Write-Host "Creating iRule `"$rule_name`"...";
  21:     (Get-F5.iControl).LocalLBRule.create( (, $rule) );
  22:   }
  24:   # Assign iRule to Virtual Server
  25:   $vs_rules = (Get-F5.iControl).LocalLBVirtualServer.get_rule( (, $virtual) );
  26:   $found = $false;
  27:   foreach ($vs_rule in $vs_rules[0])
  28:   {
  29:     if ( $rule_name.Equals($vs_rule.rule_name) ) { $found = $true; }
  30:   }
  31:   if ( -not $found )
  32:   {
  33:     $virtual_servers = (, $virtual);
  34:     $rule = New-Object -TypeName iControl.LocalLBVirtualServerVirtualServerRule;
  35:     $rule.rule_name = $rule_name;
  36:     $rule.priority = 500;
  37:     $rules = (, $rule);
  38:     Write-Host "Assigning iRule `"$rule_name`" to virtual `"$virtual`"...";
  39:     (Get-F5.iControl).LocalLBVirtualServer.add_rule($virtual_servers, $rules);
  40:   }
  41: }

And there is the iRule in the BIG-IP GUI.


Testing Your Application

Now that the VLANs, SelfIPs, Pool, and VirtualServer are configured and functioning, it's time to test out the application.  Here, I opened up a browser and typed in the address of the new Virtual Server ( and you'll see the response came back.  And, you'll also notice that the iRule did it's magic and modified the response content from the IIS application.

DevProvisioningClientBrowser If a browser is too much work for you, curl works just as well.














I've shown in this example how you can build and test a fully functional web application with a single host operating system (in my case Windows 7) and a single instance of BIG-IP LTM VE.  This will greatly reduce the complexity for developers who want to test applications they are currently debugging in the host operating system.


The provisioning script used in this article can be found in the iControl CodeShare under PsProvisionVEForLocalDev

Comments on this Article
Comment made 24-Feb-2010 by Jason Rahm
That is killer, Joe. Nice work!
Comment made 24-Feb-2010 by Joe Pruitt 6272
Thanks Jason. Like the old song says, "I get by with a little help from my friends". Thanks for the assistance!

Comment made 07-Apr-2010 by da coug 0
Hi, I tried to apply this tuto but I got a pb with network connectivity : The eth0:mgmt is working fine (grabing a IP address on my internal DHCP server), the VMnet1 is ok as I affect an IP on the same subnet on one of the interface of the BigIP, but on the VMnet8 virtual interface; the interface is stuck on "limited connectivity" and there is no way to ping the BigIP with the hosting PC on this interface.

I'm using VMPlayer instead of VMWokstation, does anyone succeed in deploying this configuration with it ?
Comment made 04-Nov-2010 by tgriggs 0
I'm having a similar issue as da coug. I can ping from the host to the self-ip on the VMnet1 subnet and IP traffic works but I cannot get any taffic through to the other self-ip subnet using either a VMnet8 (NAT) or another Host-only interface such as VMnet2.

I'm also using VMPlayer v3.1.2. HELP!
Comment made 23-Nov-2010 by Narendra 0

I followed this document; however have some network issue.

I installed Big IP VE 10.1 in VMWARE workstation 7. The underlying OS is windows XP. I assigened to VMnet1 and to VMnet8. I created two VLAN in bigip. Internal VLAN with self IP and external VLAN with self IP

I can ping only from f5 command and not If I switchover IP configuraton between VMnet1 and VMnet5 then I can ping only

I am wonder what is issue? Can any one help me for resolving this issue?



Comment made 22-Dec-2010 by Deepak 0

I too have problem with the test setup. Issue is same as Narendra reported earlier in this post. I have followed the instruction as per original posting and even used same IP's.

Do any guys have any idea on resolving this?

Comment made 15-Sep-2014 by whswhswhs124 19