Using Ansible to Manage BGP on BIG-IP
So, if you've ever wanted to manage BGP (Border Gateway Protocol) Settings for your BIG-IP with Ansible, you may have run into an issue with not having an ansible module for advanced routing. You could maybe use bigip_command, but not all tmsh is created equal, with respect to advanced routing commands. Functionality is version dependent. I present to you, a way to manage BIG-IP's BGP configuration via imish. This particular example was used by a service provider as part of a configuration process for BIG-IP VE in a CI/CD pipeline, created by OpenStack HEAT.
Since we cannot rely on BIG-IP Ansible modules, we must use native ansible, which uses ssh as a default transport, versus https. To accomodate for this, I made an adjustment in my hosts file (password can be keyed also.. it was a Proof of Concept):
[test]
192.168.197.131
[test-ssh]
192.168.197.131 ansible_connection=ssh ansible_ssh_user=root ansible_ssh_pass=default
Since the customer wanted to be able to make changes on the fly, I used the blockinfile module from Ansible, which denotes a block of code with a # character, and the lineinfile module, which adds a line in a specified file, to update a bash script on the box in /tmp, which we apply with imish. To finish it off, we use the shell module to simply run the script. All this can be done w/ one playbook:
---
- name: BGP File Creation
hosts: test-ssh
gather_facts: false
vars_files:
- var.yml
tasks:
- name: "Write out BGP Config"
blockinfile:
create: yes
path: /var/tmp/bgp_conf.sh
content: |
CE_V4_1=192.168.13.3
CE_V4_2=192.168.13.4
CE_V6_1=2001:1890:e00f:f3c:192:168:13:3
CE_V6_2=2001:1890:e00f:f3c:192:168:13:4
SVC1_V4_VIP=xxx.xxx.xxx.xxx
SVC2_V6_VIP=2001:1890:e00f:xxx::xxx
SVC2_V4_VIP=xxx.xxx.xxx.xxx
imish << EOF > /dev/null
en
conf t
no service password-encryption
router bgp 65003
bgp graceful-restart restart-time 2
bgp log-neighbor-changes
redistribute kernel route-map ANYCAST_ROUTES_CE
neighbor $CE_V4_1 remote-as 4466
neighbor $CE_V4_1 timers 15 45
neighbor $CE_V4_1 next-hop-self
neighbor $CE_V4_1 soft-reconfiguration inbound
neighbor $CE_V4_2 remote-as 4466
neighbor $CE_V4_2 timers 15 45
neighbor $CE_V4_2 next-hop-self
neighbor $CE_V4_2 soft-reconfiguration inbound
neighbor $CE_V6_1 remote-as 4466
neighbor $CE_V6_1 timers 15 45
neighbor $CE_V6_1 next-hop-self
neighbor $CE_V6_1 soft-reconfiguration inbound
neighbor $CE_V6_2 remote-as 4466
neighbor $CE_V6_2 timers 15 45
neighbor $CE_V6_2 next-hop-self
neighbor $CE_V6_2 soft-reconfiguration inbound
address-family ipv6
redistribute kernel route-map ANYCAST_ROUTES_CE_IPV6
no neighbor $CE_V4_1 activate
no neighbor $CE_V4_1 capability graceful-restart
no neighbor $CE_V4_2 activate
no neighbor $CE_V4_2 capability graceful-restart
neighbor $CE_V6_1 activate
neighbor $CE_V6_1 soft-reconfiguration inbound
neighbor $CE_V6_1 route-map
neighbor $CE_V6_2 activate
neighbor $CE_V6_2 soft-reconfiguration inbound
neighbor $CE_V6_2
exit-address-family
ip prefix-list ADD_ANYCAST_VIP_CE seq 5 permit $SVC1_V4_VIP/32
ip prefix-list ADD_ANYCAST_VIP_CE seq 6 permit $SVC2_V4_VIP/32
ip prefix-list ADD_ANYCAST_VIP_CE seq 20 deny any
ipv6 prefix-list Anycast_VIP_IPV6 seq 5 permit $SVC_V6_VIP/128
ipv6 prefix-list Anycast_VIP_IPV6 seq 10 deny any
route-map ANYCAST_ROUTES_CCE_IPV6 permit 20
match ipv6 address prefix-list Anycast_VIP_IPV6
set origin igp
set community 4466:21 4466:100
set as-path prepend 65003
route-map ANYCAST_ROUTES_CE permit 10
match ip address prefix-list ADD_ANYCAST_VIP_CE
set origin igp
set community 4466:21 4466:100
set as-path prepend 65003
line con 0
login
line vty 0 39
login
end
wr
clear ip bgp * soft
EOF
- name: "Correct BGP bash path"
lineinfile:
path: /var/tmp/bgp_conf.sh
insertbefore: '^# BEGIN ANSIBLE MANAGED BLOCK'
line: '#!/bin/bash'
- name: "Apply BGP Config"
shell: sh /var/tmp/bgp_conf.sh
For context, this was created when TMOS 14.1 was released, so it's a bit dated, but none of the elements listed here have changed much in BIG-IP. As always, YMMV, but this is part of a production deployment that supports millions of people every day. Make any adjustments neccessary for your environment.
Here's a video which shows the code with a bit more explained:
It is great but I wondering to try the Ansible URI module and just pust to POST the data to the URI endoint:
https://github.com/ansible/workshops/blob/master/exercises/ansible_f5/3.0-as3-intro/as3.yml
https://www.f5.com/company/blog/f5-as3-and-red-hat-ansible-automation
- AubreyKingF5Moderator
That is an elegant solution for more modern TMOS, for sure. There were discrepancies between what was available w/ TMOS routing at the time. This solution works for any ZebOS implemented routing.