on 02-Oct-2022 18:00
In this article, i will present a suite of use cases using the F5 BIG-IP Advanced WAF Terraform resources introduced on the F5 BIG-IP Terraform Provider on version 1.15.
“HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. »
https://www.terraform.io/intro
"… but wait! Terraform is not a Configuration Management tool. I should use Ansible for that!”
True.
Terraform is not a config management tool and I would say: “use whatever you feel comfortable and happy working with”… but keep also that in mind:
We provide a comprehensive declarative REST API to provision, manage the whole lifecycle management of a F5 BIG-IP Advanced WAF policy and facilitate its integration into CI/CD pipelines.
The documentation of the API is located here.
The F5 BIG-IP Terraform resources leverage our AWAF Declarative API.
Basically, the terraform workflow is very closed to what you used to with the traditional (UI) F5 BIG-IP Advanced WAF Policy workflow:
Manually Managed
1. if a request is blocked, you check on the events and filter on a Support ID.
3. If this was a False positive generated by an attack signature, you just can just take the signature Id, and the level of the exception (globally, parameter, URL)
4. Create the terraform data source and attach it to the Policy
data "bigip_waf_entity_parameter" "P1" {
name = "Parameter2"
type = "wildcard"
data_type = "alpha-numeric"
perform_staging = false
signature_overrides_disable = [200001494]
sensitive_parameter = true
}
resource "bigip_waf_policy" "this" {
name = "myPolicy"
partition = "Common"
template_name = "POLICY_TEMPLATE_RAPID_DEPLOYMENT"
application_language = "utf-8"
enforcement_mode = "blocking"
server_technologies = ["Apache Tomcat", "MySQL", "Unix/Linux", "MongoDB"]
parameters = [data.bigip_waf_entity_parameter.P1.json]
}
Managed with Policy Builder suggestions
1. You can regularly check on the learning suggestions dashboard for potential False Positive (cleaning phase). At this point, don't accept suggestions otherwise it will enforce the change and you will have to manage the drift.
2. Once the cleaning is done, you can request all the policy builder learning suggestions having a desired minimum scoring (can be whatever between 10% to 100%) using the bigip_waf_pb_suggestions data source.
data "bigip_waf_pb_suggestions" "AUG3rd20221715" {
provider = bigip.prod
policy_name = "scenario5"
partition = "Common"
minimum_learning_score = 100
}
resource "bigip_waf_policy" "this" {
provider = bigip.prod
application_language = "utf-8"
partition = "Common"
name = "scenario5"
template_name = "POLICY_TEMPLATE_FUNDAMENTAL"
type = "security"
policy_import_json = data.http.scenario5.body
modifications = [data.bigip_waf_pb_suggestions.AUG3rd20221715.json]
}
One of the first rules we had in mind when we created these terraform resources is that we should always consider someone will perform manual changes through the F5 BIG-IP WebUI.
The main reason is because we have a great and very convenient graphical user interface and great dashboards exposing a lot of valuable information. How would you expose all of that in HCL?
Then, we had to make choices and release a first iteration that covers 90% of the use cases. Yet, there will always be some features that are not yet exposed.
When you try mixing automation and manual changes is usually when problems occur...
This is called configuration drifts and we hate config drifts because it means we have to resolve something and make hard choices!
So... in case of a drift, you either override any changes that have been made manually or you accept the changes, but how do you keep track of these changes in your state?
let's take an example: you are the terraform admin and you have to go on very well deserved PTO. During your vacations, one of your colleague have to make changes into the WAF Policy: enforcing a new CVE protection, adding some potential exception because the application changed,...
When you are back, by planning the next terraform changes you realize there is a configuration drift between your local terraform state and the remote state on the BIG-IP. In that case, you just have to import the current state from the BIG-IP (terraform import) or point to an external repo of your new policy and use it as the policy_json attribute of your bigip_waf_policy terraform resource.