Exercise 1.4: Adding members to a pool on F5¶
Objective¶
Demonstrate use of the BIG-IP pool member
module
to tie web server nodes into the load balancing pool http_pool
created in the previous exercises.
Guide¶
Step 0:
Make sure you have the virtuals_pools.yml files defined, refer exercise 1.3-add-pool.
Step 1:
Using your text editor of choice create a new file called bigip-pool-members.yml
.
[student1@ansible ~]$ nano bigip-pool-members.yml
``vim`` and ``nano`` are available on the control node
Step 2:
Enter the following play definition into bigip-pool-members.yml
:
---
- name: BIG-IP SETUP
hosts: lb
connection: local
gather_facts: false
vars_files:
virtuals_pools.yml
- The
---
at the top of the file indicates that this is a YAML file. - The
hosts: lb
, indicates the play is run only on the lb group. Technically there only one F5 device but if there were multiple they would be configured simultaneously. connection: local
tells the Playbook to run locally (rather than SSHing to itself)gather_facts: false
disables facts gathering. We are not using any fact variables for this playbook.vars_file
is a ansible reserved word to include a file to the playbook
Step 3
Next, add the first task
. This task will use the set_fact
module to set a parameter called ‘provider’.
This parameter will hold all the connection details to the BIG-IP and will be used in subsequent tasks
---
- name: BIG-IP SETUP
hosts: lb
connection: local
gather_facts: false
vars_files:
virtuals_pools.yml
tasks:
- set_fact:
provider:
server: "{{private_ip}}"
user: "{{ansible_user}}"
password: "{{ansible_ssh_pass}}"
server_port: 8443
validate_certs: no
- The
server: "{{private_ip}}"
parameter tells the module to connect to the F5 BIG-IP IP address, which is stored as a variableprivate_ip
in inventory - The
user: "{{ansible_user}}"
parameter tells the module the username to login to the F5 BIG-IP device with - The
password: "{{ansible_ssh_pass}}"
parameter tells the module the password to login to the F5 BIG-IP device with - The
server_port: 8443
parameter tells the module the port to connect to the F5 BIG-IP device with
Step 4
Next, add the first task
. This task will use the bigip_pool_member
module configure the two RHEL web servers as nodes
on the BIG-IP F5 load balancer.
---
- name: BIG-IP SETUP
hosts: lb
connection: local
gather_facts: false
vars_files:
virtuals_pools.yml
tasks:
- set_fact:
provider:
server: "{{private_ip}}"
user: "{{ansible_user}}"
password: "{{ansible_ssh_pass}}"
server_port: 8443
validate_certs: no
- name: ADD POOL MEMBERS
bigip_pool_member:
provider: "{{provider}}"
state: "present"
name: "{{hostvars[item[0]].inventory_hostname}}"
host: "{{hostvars[item[0]].ansible_host}}"
port: "80"
pool: "{{item[1].pool_name}}"
with_nested:
- "{{ groups['webservers'] }}"
- "{{vips_pools}}"
Explanation of each line within the task:
- name: ADD POOL MEMBERS
is a user defined description that will display in the terminal output.
- bigip_pool_member:
tells the task which module to use.
- The state: "present"
parameter tells the module we want this to be added rather than deleted.
- The name: "{{hostvars[item].inventory_hostname}}"
parameter tells the module to use the inventory_hostname
as the name (which will be host1 and host2).
- The host: "{{hostvars[item].ansible_host}}"``parameter tells the module to add a web server IP address already defined in our inventory.
- The ``pool:` parameter tells the module to put this node into a pool with name from the second list {{vips_pool}}
- ``with_nested:
tells the task to perform a nested loop over the provided list. The list in this case is the group webservers which includes two RHEL hosts and the list of virtuals
Step 5
Run the playbook - exit back into the command line of the control host and execute the following:
[student1@ansible ~]$ ansible-playbook bigip-pool-members.yml
Playbook Output¶
The output will look as follows.
[student1@ansible ~]$ ansible-playbook bigip-add-pool.yml
PLAY [BIG-IP SETUP] *****************************************************************************************************************************************
TASK [set_fact] *********************************************************************************************************************************************
ok: [f5]
TASK [ADD POOL MEMBERS] *************************************************************************************************************************************
changed: [f5] => (item=[u'host1', {u'pool_name': u'http-pool', u'vs_name': u'vip', u'port': 8081}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool1', u'vs_name': u'vip1', u'port': 8082}]) 8,5 All
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool2', u'vs_name': u'vip2', u'port': 8083}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool3', u'vs_name': u'vip3', u'port': 8084}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool4', u'vs_name': u'vip4', u'port': 8085}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool5', u'vs_name': u'vip5', u'port': 8086}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool6', u'vs_name': u'vip6', u'port': 8087}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool7', u'vs_name': u'vip7', u'port': 8088}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool8', u'vs_name': u'vip8', u'port': 8089}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool9', u'vs_name': u'vip9', u'port': 8090}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool10', u'vs_name': u'vip10', u'port': 8091}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool11', u'vs_name': u'vip11', u'port': 8092}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool12', u'vs_name': u'vip12', u'port': 8093}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool13', u'vs_name': u'vip13', u'port': 8094}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool14', u'vs_name': u'vip14', u'port': 8095}])
ok: [f5] => (item=[u'host1', {u'pool_name': u'http-pool15', u'vs_name': u'vip15', u'port': 8096}])
changed: [f5] => (item=[u'host2', {u'pool_name': u'http-pool', u'vs_name': u'vip', u'port': 8081}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool1', u'vs_name': u'vip1', u'port': 8082}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool2', u'vs_name': u'vip2', u'port': 8083}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool3', u'vs_name': u'vip3', u'port': 8084}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool4', u'vs_name': u'vip4', u'port': 8085}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool5', u'vs_name': u'vip5', u'port': 8086}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool6', u'vs_name': u'vip6', u'port': 8087}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool7', u'vs_name': u'vip7', u'port': 8088}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool8', u'vs_name': u'vip8', u'port': 8089}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool9', u'vs_name': u'vip9', u'port': 8090}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool10', u'vs_name': u'vip10', u'port': 8091}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool11', u'vs_name': u'vip11', u'port': 8092}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool12', u'vs_name': u'vip12', u'port': 8093}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool13', u'vs_name': u'vip13', u'port': 8094}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool14', u'vs_name': u'vip14', u'port': 8095}])
ok: [f5] => (item=[u'host2', {u'pool_name': u'http-pool15', u'vs_name': u'vip15', u'port': 8096}])
Output parsing¶
Let’s use the bigip_device_info to collect the pool members on BIG-IP. JSON query is a powerful filter that can be used. Please go through before proceeding
..code:
[student1@ansible ~]$ nano display-pool-members.yml
Enter the following:
- name: "List pool members"
hosts: lb
gather_facts: false
connection: local
tasks:
- set_fact:
provider:
server: "{{private_ip}}"
user: "{{ansible_user}}"
password: "{{ansible_ssh_pass}}"
server_port: 8443
validate_certs: no
- name: Query BIG-IP facts
bigip_device_info:
provider: "{{provider}}"
gather_subset:
- ltm-pools
register: device_facts
- name: "View complete output"
debug: "msg={{device_facts}}"
- name: "Show members belonging to pool"
debug: "msg={{item}}"
loop: "{{device_facts.ltm_pools | json_query(query_string)}}"
vars:
query_string: "[?name=='http-pool'].members[*].name[]"
vars:
in the module is defining a variable query_string to beused within the module itselfquery_String
will have the name of all members from pool name ‘http-pool’. query_string is defined to make it easier to read the entire json string
Execute the playbook
[student1@ansible ~]$ ansible-playbook display-pool-members.yml
Output
[student1@ansible ~]$ ansible-playbook display-pool-member.yml
PLAY [List pool members] ************************************************************************************************************************************
TASK [Query BIG-IP facts] ***********************************************************************************************************************************
changed: [f5]
TASK [Show members belonging to pool] ***********************************************************************************************************************
ok: [f5] => (item=host1:80) => {
"msg": "host1:80"
}
ok: [f5] => (item=host2:80) => {
"msg": "host2:80"
}
PLAY RECAP **************************************************************************************************************************************************
f5 : ok=2 changed=1 unreachable=0 failed=0
Solution¶
The finished Ansible Playbook is provided here for an Answer key. Click here: bigip-pool-members.yml.
Verifying the Solution¶
Login to the F5 with your web browser to see what was configured. Grab the IP information for the F5 load balancer from the lab_inventory/hosts file, and type it in like so: https://X.X.X.X:8443/
Login information for the BIG-IP: - username: admin - password: provided by instructor defaults to ansible
The pool will now show two members (host1 and host2). Click on Local Traffic-> then click on Pools. Click on a particular pool to get more granular information. Click on the Members tab in the middle to list all the Members.
You have finished this exercise.