Terraform is an open source tool for provisioning and deployment of public and private cloud infrastructures. Terraform lets you to create, change and improve production infrastructure safely and predictably. Terraform use APIs abstraction through declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned. 

Many of our customers who have deployments in AWS, Azure and GCP are using terraform in DevOps and CICD initiatives. As automation in the network is pivotal for DevOps success and as F5 plays an important role in our customers network, we have  F5 provider plugin for terraform. Now, using Terraform, customers can deploy F5 BIG-IP in Public cloud using F5 BIG-IP YAML or JSON templates. The terraform F5 Provider repo is available for download at https://github.com/f5devcentral/terraform-provider-bigip  repository

Once the infrastructure is deployed, using the F5 BIG-IP provider for terraform we can automate several F5 BIG-IP operational tasks as well. Besides application deployment, operational tasks like removing the servers from the F5 BIG-IP pool so that, the server apps can be updated with new software or the server operating system can be upgraded - all while avoiding outages or downtime etc. can be automated and run with Terraform. If such operational tasks are done manually its very much time consuming and error prone. Also imagine if you need to do hundreds of such changes more frequently.

Let us look at a simple operational use case: Here, the F5 BIG-IP device is configured using Terraform. Configuration file shows deploying Virtual server for App1 application, App1_Pool and Application Servers 11.1.1.101 & 11.1.1.102.

Virtual Server, Pool and nodes configured on BIG-IP

provider "bigip" {

  address = "10.192.74.73"

  username = "admin"

  password = "admin"

}

resource "bigip_ltm_pool"  "App1_pool" {

        name = "/Common/App1_pool"

        load_balancing_mode = "round-robin"

        nodes = ["11.1.1.101:80","11.1.1.102:80"]

        monitors = ["/Common/App1_monitor"]

        allow_snat = true

       }

resource "bigip_ltm_virtual_server" "App1_http" {

            pool = "/Common/App1_pool"

        name = "/Common/App1_http_vs"

            destination = "100.1.1.100"

            port = 80

            source_address_translation = "automap"

            depends_on = ["bigip_ltm_pool.App1_pool"]

}
In the above configuration “bigip” highlighted is the F5 BIG-IP Provider which talks to the terraform software.  The parameters for this provider are address (mgmt. of BIG-IP), username and password. You can also use token. Resources highlighted are BIG-IP resources for terraform to deploy Pool, nodes and Virtual Server for App1 application.To preview changes before applying the configuration command terraform plan is used as shown below.
terraform-provider-bigip shitole$ terraform plan


+ bigip_ltm_pool.App1_pool

    allow_nat:           "true"

    allow_snat:          "true"

    load_balancing_mode: "round-robin"

    monitors.#:          "1"

    monitors.1751784255: "/Common/App1_monitor"

    name:                "/Common/App1_pool"

    nodes.#:             "2"

    nodes.2872054492:    "11.1.1.101:80"

    nodes.3112549682:    "11.1.1.102:80"

+ bigip_ltm_virtual_server.App1_http

    client_profiles.#:          "<computed>"

    destination:                "100.1.1.100"

    ip_protocol:                "<computed>"

    mask:                       "255.255.255.255"

    name:                       "/Common/App1_http_vs"

    pool:                       "/Common/App1_pool"

    port:                       "80"

    profiles.#:                 "<computed>"

    server_profiles.#:          "<computed>"

    snatpool:                   "<computed>"

    source:                     "0.0.0.0/0"

    source_address_translation: "automap"


Plan: 10 to add, 0 to change, 0 to destroy.

The above command will help us to see what configuration will be eventually applied to the F5 BIG-IP.  You can use terraform apply command to manifest the configuration on BIG-IP as shown below.

terraform-provider-bigip shitole$ terraform apply

bigip_ltm_pool.App1_pool: Creating...

  allow_nat:           "" => "true"

  allow_snat:          "" => "true"

  load_balancing_mode: "" => "round-robin"

  monitors.#:          "" => "1"

  monitors.1751784255: "" => "/Common/App1_monitor"

  name:                "" => "/Common/App1_pool"

  nodes.#:             "" => "2"

  nodes.2872054492:    "" => "11.1.1.101:80"

  nodes.3112549682:    "" => "11.1.1.102:80"


bigip_ltm_pool.App1_pool: Creation complete
 
bigip_ltm_virtual_server.App1_http: Creating...

  client_profiles.#:          "" => "<computed>"

  destination:                "" => "100.1.1.100"

  ip_protocol:                "" => "<computed>"

  mask:                       "" => "255.255.255.255"

  name:                       "" => "/Common/App1_http_vs"

  pool:                       "" => "/Common/App1_pool"

  port:                       "" => "80"

  profiles.#:                 "" => "<computed>"

  server_profiles.#:          "" => "<computed>"

  snatpool:                   "" => "<computed>"

  source:                     "" => "0.0.0.0/0"

  source_address_translation: "" => "automap"

bigip_ltm_virtual_server.App1_http: Creation complete

Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

The above terraform apply command creates Virtual server, Pool and adds 2 nodes to the Pool.

Server Node 11.1.1.101 is taken down for Maintenance

In order to remove the server 11.1.1.101 for maintenance we have to change the configuration file as shown below. You can see the node 11.1.1.101 is removed from the pool resource. The above TF file changes are made to the bigip_ltm_pool resource

resource "bigip_ltm_pool"  "App1_pool" {

        name = "/Common/App1_pool"

        load_balancing_mode = "round-robin"

        nodes = ["11.1.1.102:80"]    node 11.1.1.101 is removed

        monitors = ["/Common/App1_monitor"]

        allow_snat = true

        depends_on = ["bigip_ltm_provision.provision-afm"]

}
 
When terraform plan is executed you can see that server 11.1.1.101 is removed in the plan as shown below
 
terraform-provider-bigip shitole$ terraform plan


~ bigip_ltm_pool.App1_pool

    nodes.#:          "2" => "1"

    nodes.2872054492: "11.1.1.101:80" => ""

    nodes.3112549682: "11.1.1.102:80" => "11.1.1.102:80"


~ bigip_ltm_virtual_server.App1_http

    pool: "App1_pool" => "/Common/App1_pool"



Plan: 0 to add, 2 to change, 0 to destroy.

terraform-provider-bigip shitole$ terraform apply


bigip_ltm_monitor.App1_monitor: Refreshing state... (ID: /Common/App1_monitor)

bigip_ltm_pool.App1_pool: Refreshing state... (ID: /Common/App1_pool)

bigip_ltm_virtual_server.App1_http: Refreshing state... (ID: /Common/App1_http_vs)

bigip_ltm_pool.App1_pool: Modifying...

  nodes.#:          "2" => "1"

  nodes.2872054492: "11.1.1.101:80" => ""

  nodes.3112549682: "11.1.1.102:80" => "11.1.1.102:80"

bigip_ltm_pool.App1_pool: Modifications complete


bigip_ltm_virtual_server.App1_http: Modifying...

  pool: "App1_pool" => "/Common/App1_pool"

bigip_ltm_virtual_server.App1_http: Modifications complete


Apply complete! Resources: 0 added, 2 changed, 0 destroyed.
 
Above you can see that nodes have been reduced from 2 to 1. Now server 11.1.1.101 can be upgraded with new OS or CPU, RAM can be upgraded as per needs without affecting the live application traffic. Also, when the upgrade is done, the server 11.1.1.101 can be added back into the configuration file for a seamless operation.
 

Removal of residual Virtual Servers and Pools:

Another very important operation is to remove unwanted VIPs and Pools. When some of the Apps are retired we no longer need the configuration for VIPs, Pools and nodes on the F5 BIG-IP. Using F5 BIG-IP resources for terraform we can easily manage this kind for operation in a scaled environment without errors and do this in seconds instead of spending weeks when done manually. Also, code can be shared among various team members before committing the changes. Below is an example of such operation.

$ terraform destroy -target=bigip_ltm_virtual_server.App1_http


Do you really want to destroy?

  Terraform will delete the following infrastructure:

      bigip_ltm_virtual_server.App1_http

  There is no undo. Only 'yes' will be accepted to confirm


  Enter a value: yes


bigip_ltm_virtual_server.App1_http: Refreshing state... (ID: /Common/App1_http_vs)

bigip_ltm_virtual_server.App1_http: Destroying...

bigip_ltm_virtual_server.App1_http: Destruction complete


Destroy complete! Resources: 1 destroyed.

Organizations of all sizes are adopting cloud for application workloads. These organizations are looking to avoid the costs of running and managing their data centers or, more often, to accelerate the application delivery process. Using cloud enables development teams to operate with a much greater degree of independence from the underlying operational constraints of infrastructure. That’s where F5 BIG-IP terraform resources will help organization to adopt agile methods. A complete list of F5 BIG-IP terraform resources can be found at https://github.com/f5devcentral/terraform-provider-bigip.