Manage F5 BIG-IP Advanced WAF Policies with Terraform (Part 2 - Policy Import)

You may already have multiple F5 BIG-IP Advanced WAF policies protecting your applications and these F5 BIG-IP Advanced WAF policies have evolved over the past months or years. It may be very complicated to do an extensive inventory of each policy, each entity and every attribute. So the goal here is to import the current policy, which will be our current baseline. Every new change, addition of a Server Technology, parameter, attack signature... will be done through Terraform in addition or correction of this new baseline.

 

Table of Content

 

Import workflow

Files creation

Create 3 files:

  • main.tf
  • variables.tf
  • inputs.tfvars

variables.tf

variable bigip {}
variable username {}
variable password {}

 

inputs.tfvars

bigip = "10.1.1.9:443"
username = "admin"
password = "whatIsYourBigIPPassword?"

 

main.tf

terraform {
  required_providers {
    bigip = {
      source = "F5Networks/bigip"
      version = "1.15"
    }
  }
}

provider "bigip" {
  address  = var.bigip
  username = var.username
  password = var.password
}

resource "bigip_waf_policy" "this" {
  partition            = "Common"
  name                 = "scenario2"
  template_name        = "POLICY_TEMPLATE_RAPID_DEPLOYMENT"
}

 

The resource bigip_waf_policy is just a “place holder” for importing the resource.

As you can see, we only define the two required attributes of the bigip_waf_policy terraform resource: name and template_name. It is required to provide them in order to be able to manage the resource.

 

Getting the Policy ID

Just before we go. We need the Policy ID. There are multiple ways we can get it. You can choose any of those:

  • if you have access to the iControl REST API Endpoint: /mgmt/tm/asm/policies?$filter=name+eq+scenario2&$select=id
  • get a script example in the lab/scripts/ folder of the GitHub repo of examples (see Appendix)
  • using the following Go code

 

Here, we are using the Online Go Playground as it is easy and quick to use:

a/ copy the following piece of code in the Go PlayGround

b/ update the value of the following variables located in the main function:

var partition string = "Common"

var policyName string = "scenario2"

c/ Run and get the policy ID.

package main

import (
            "crypto/md5"
            b64 "encoding/base64"
            "fmt"
            "strings"
)

func Hasher(policyName string) string {
            hasher := md5.New()
            hasher.Write([]byte(policyName))
            encodedString := b64.StdEncoding.EncodeToString(hasher.Sum(nil))
            return strings.TrimRight(encodedString, "=")
}

func main() {
            var partition string = "Common"
            var policyName string = "scenario2"

            fullName := "/" + partition + "/" + policyName
            policyId := Hasher(fullName)
            r := strings.NewReplacer("/", "_", "-", "_", "+", "-")
            fmt.Println("Policy Id: ", r.Replace(policyId))
}

 

 

Run the import into the Terraform project

Now, run the following commands, so we can:

  1. Initialize the terraform project
  2. Import the current F5 BIG-IP Advanced WAF policy into our state
  3. Set the JSON F5 BIG-IP Advanced WAF Policy as our new baseline
  4. Configure the lifecycle of our F5 BIG-IP Advanced WAF Policy

 

Now update your terraform main.tf file with the ouputs of the following two commands:

foo@bar:~$ terraform show -json | jq '.values.root_module.resources[].values.policy_export_json | fromjson' > importedWAFPolicy.json

foo@bar:~$ terraform show -no-color
resource "bigip_waf_policy" "this" {
    application_language = "utf-8"
    id                   = "EdchwjSqo9cFtYP-iWUJmw"
    name                 = "scenario2"
    partition            = "Common"
    policy_export_json   = jsonencode([...])
    policy_id            = "EdchwjSqo9cFtYP-iWUJmw"
    template_name        = "POLICY_TEMPLATE_FUNDAMENTAL"
    type                 = "security"
}

 

using the collected data from the terraform import, we are now updating our main.tf file:

resource "bigip_waf_policy" "this" {
    application_language = "utf-8"
    name                 = "scenario2"
    partition            = "Common"
    policy_id            = "EdchwjSqo9cFtYP-iWUJmw"
    template_name        = "POLICY_TEMPLATE_FUNDAMENTAL"
    type                 = "security"
    policy_import_json   = file("${path.module}/importedWAFPolicy.json")
}

 

Demo Video

 

 

Manage F5 BIG-IP Advanced WAF Policies with Terraform (Part 2 - Policy Import)
 

 

Published Sep 27, 2022
Version 1.0

Was this article helpful?

No CommentsBe the first to comment