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:

Published Jun 13, 2022
Version 1.0