Create/modify/delete an F5 virtual server using Python and Jenkins pipelines

Introduction

F5 BIG-IP load balancers are essential components for ensuring high availability and scalability for applications. One of the critical elements in a BIG-IP deployment is the virtual server, which enables traffic distribution across backend servers. F5 provides a robust API called iControl REST, allowing the automation of tasks that would otherwise require manual intervention. This article will discuss how to create, modify, and delete F5 virtual servers using Python and the F5 iControl REST API. Additionally, we will explore how to integrate this functionality into a Jenkins pipeline running inside a Docker container.

Prerequisites(or what I used)

To follow along with this article, you will need the following:

  • An F5 BIG-IP device running version 13.1.4.1 or higher.
  • Python 3.10.9 installed on your local machine.
  • GitHub/GitLab account
  • Docker Desktop (version 4.16.3) installed on your local machine.
  • Basic knowledge of Jenkins and Jenkins pipelines.

Python stuff

From the start, I was planning to use some sort of pipeline, so I’ve created a script for each action (create, modify, delete, list) for each object like pool, profile, irule, and virtual server. All scripts use F5 iControl REST API to push/get/modify/delete data from the F5 device. F5 also has an SDK which would make things easier, but I’ve used this opportunity to learn more python stuff.
I’ve organized all the entry data in JSON files under a folder for each service. So a service would contain a JSON file for pool creation, one for profiles, one for irules, and one for the virtual server.
For example, service1 would look like this:

virtual.json  irules.json  pool.json  profiles.json  

Each file is in fact a list of JSON dictionaries because I wanted to be able to create multiple objects. For example, service1 has 2 virtual servers.
Also, I have a folder for some test python scripts, because I wanted to test if a virtual server exists before I modify/delete it for example.
And last, I have a python script called graph.py to create a graphical representation of the virtual server. It will show you the pools of the virtual server: the default pool, and the pools that are attached to this virtual server using irules.

All of these was pushed to GitHub in my case because later I’ll be using this repository in my pipelines.

Docker stuff

For building the Jenkins server I’ve used Docker and an Ubuntu image. To do this I’ve used a Dockerfile to specify which image to use, install python3, Jenkins, Java(needed for Jenkins), and all the libraries/modules I’ve used for my scripts. You can find this file in the GitHub repository I’ve shared at the end of the article.

Jenkins pipelines

Before talking about it, let’s see what it is:
Jenkins is an open-source automation server that is used for continuous integration and continuous delivery (CI/CD) of software projects. It is a powerful tool that allows developers to automate and streamline the building, testing, and deployment of their software applications. Jenkins can be used to automate tasks such as compiling code, running unit tests, packaging the application, and deploying it to production environments.”

I’ve created 3 pipelines:

‘Create-F5-VIP’ and ‘Delete-F5-VIP’ perform only one action, while ‘all-in-F5-VIP’ takes the action as a parameter so you can use this pipeline for different actions. All these pipelines use the GitHub repository as the source of the data, python scripts, and even the Jenkins files used for creating the pipelines.

For creating the Jenkins pipelines I’ve used a Jenkinsfile for each one of them.
Here is an example of for ‘all-in-F5-VIP‘ pipeline:

pipeline {
  agent any
  parameters {
    string(name: 'service', defaultValue: 'default_value', description: 'what service do you want to play with?')
    string(name: 'action', defaultValue: 'default_value', description: 'action: create/modify/delete')
        }
  stages {
    stage('Build') {
      steps {
        script {
          withCredentials([string(credentialsId: 'Authorization_string', variable: 'Authorization_string')]) {
            env.Authorization_string = "${Authorization_string}"
                    }
                }
            }
    }

    stage('Pre-test') {
      steps {
        echo 'Running pre-test...'
         sh 'python3 $WORKSPACE/Tests/pre_${action}_test.py ${service} 2>&1'
            }
    }

    stage('Deploy') {
      steps {
        echo 'Deploying the application...'
        sh 'python3 $WORKSPACE/${action}_vip.py ${service} 2>&1'
      }
    }

    stage('Post_test') {
      steps {
        echo 'Running post-test...'
        sh 'python3 $WORKSPACE/Tests/post_${action}_test.py ${service} 2>&1'
      }
    }
  }
}

In this pipeline, I am defining 2 parameters, service and action, so when I run it I can specify which service I want to do an action on, and the action I want to run.

Then, I am defining the stages:

  • Build, where I am importing the basic authorization string as an environment variable used in the python scripts when using the F5 API.
  • Pre-test, this is a python script where I test if the virtual server already exists.
  • Deploy, where I run the create virtual server script
  • Post-test, this is a python script where I test if the virtual server was created.

Now let’s see each of these stages.

Example for ‘service1’:

When the virtual server does not exist already, everything should run smoothly. In the Deploy stage, because I use logging in all my scripts, you will see what objects have been created.

Now, If we run this again, the pre-test script should not allow us to create the virtual server.

If we want to modify anything on an existing virtual server we should first edit one of the JSON files, then push it to Git, and then run the pipeline but in this case, use modify action.

And last, we can delete a virtual server and all of the associated objects(irules, profiles, pools).
When we run this, we need to specify the service we want to delete and action ‘delete’.

Again, if we expand the Deploy stage you will see everything that it deleted.

And if we run it again it should not find the virtual server and the pre-test script should fail.

Conclusion

By following these steps, you should be able to successfully create F5 virtual servers using Jenkins pipelines. This is just a basic example and the JSON payload can be modified to include additional configurations and options as needed. Happy testing!

You can find all the scripts and files I’ve used in the below repository.
Source code: https://github.com/czirakim/F5-CRUD-VIP

About the author

Mihai is a Senior Network Engineer with more than 15 years of experience