Deploying Next-Gen WAF with Terraform
IMPORTANT: This feature is only available to Next-Gen WAF customers with access to theNext-Gen WAF control panel.
This tutorial guides you through deploying Fastly's Next-Gen Web Application Firewall (Next-Gen WAF) for web and API endpoint security using theEdge Deployment method, which allows you to add an edge security service onto our Edge Cloud Platform without needing to make any modifications to your own hosting environment.
You will use the following Terraform providers:
Prerequisites
Before deploying the Next-Gen WAF, ensure you have the following:
- AFastly Edge API key with service creation and management permissions;
- ANext-Gen WAF API key with Corp Admin permissions;
- An established Next-Gen WAF corp andsite.
1. Configure Terraform providers
Ensure Terraform 0.13+ is configured with the required providers for Fastly:
terraform{required_providers{fastly={source="fastly/fastly"version=">= 5.7.1"}sigsci={source="signalsciences/sigsci"version=">= 3.0.0"}http={source="hashicorp/http"}}}2. Define variables
Declare the necessary variables and resources for the Fastly Edge VCL configuration, Next-Gen WAF settings, and dynamic snippets. This includes specifying domain names, backend hostnames, and API keys.
variable "FASTLY_API_KEY"{type= stringdescription="This is API key for the Fastly VCL edge configuration."}variable "USER_VCL_SERVICE_DOMAIN_NAME"{type= stringdescription="Frontend domain for your service."default="ngwaf-tf-demo.global.ssl.fastly.net"}variable "USER_VCL_SERVICE_BACKEND_HOSTNAME"{type= stringdescription="hostname used for backend."default="http-me.fastly.dev"}variable "NGWAF_CORP"{type= stringdescription="Corp name for NGWAF"}variable "NGWAF_SITE"{type= stringdescription="Site name for NGWAF"}variable "NGWAF_EMAIL"{type= stringdescription="Email address associated with the token for the NGWAF API."}variable "NGWAF_TOKEN"{type= stringdescription="Secret token for the NGWAF API."sensitive=true}3. Set values for variables
The values for the declared variables must be available to the environment where Terraform is running following HashiCorp's guidance formanaging variables.
4. Update the Fastly VCL service
Before linking the Next-Gen WAF edge deployment to the VCL service, you must add placeholders fordynamic snippets and adictionary that will be used by the Next-Gen WAF integration. If the configurations are not added by Terraform, then Terraform will attempt to remove or replace the settings needed for the Next-Gen WAF Edge implementation. This behavior exists because the Next-Gen WAF Edge implementation uses the Terraform provider to make updates which impact the resources defined by the Fastly provider. Populating the dictionary and dynamic snippets with the desired values for the Next-Gen WAF edge deployment will be handled via the Terraform provider.
The dynamic snippets are simply commented VCL and act as a placeholder for the modifications that will occur via the Next-Gen WAF edge deployment. It is worth noting that both the dictionary and dynamic snippets are versionless. This means when modifications are made (even in subsequent service versions), those modifications will persist.
The priority of the snippetsngwaf_config_miss andngwaf_config_pass are intentionally high, to avoid conflicts with any existing VCL logic.
resource"fastly_service_dynamic_snippet_content""ngwaf_config_init"{for_each={ for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet :d.name=> d if d.name=="ngwaf_config_init"}service_id= fastly_service_vcl.frontend-vcl-service.idsnippet_id= each.value.snippet_idcontent="### Fastly managed ngwaf_config_init"manage_snippets=false}resource"fastly_service_dynamic_snippet_content""ngwaf_config_miss"{for_each={ for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet :d.name=> d if d.name=="ngwaf_config_miss"}service_id= fastly_service_vcl.frontend-vcl-service.idsnippet_id= each.value.snippet_idcontent="### Fastly managed ngwaf_config_miss"manage_snippets=false}resource"fastly_service_dynamic_snippet_content""ngwaf_config_pass"{for_each={ for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet :d.name=> d if d.name=="ngwaf_config_pass"}service_id= fastly_service_vcl.frontend-vcl-service.idsnippet_id= each.value.snippet_idcontent="### Fastly managed ngwaf_config_pass"manage_snippets=false}resource"fastly_service_dynamic_snippet_content""ngwaf_config_deliver"{for_each={ for d in fastly_service_vcl.frontend-vcl-service.dynamicsnippet :d.name=> d if d.name=="ngwaf_config_deliver"}service_id= fastly_service_vcl.frontend-vcl-service.idsnippet_id= each.value.snippet_idcontent="### Fastly managed ngwaf_config_deliver"manage_snippets=false}5. Integrate the Next-Gen WAF Edge deployment
Use the Signal Sciences provider to create the Next-Gen WAF Edge Service and link it to the Fastly VCL service. This step involves setting up a dictionary and updating dynamic snippets maintained by Fastly.
NOTE: The updated dynamic snippets will not be overwritten by subsequent terraform updates because of themanage_snippets = false setting in the dynamic snippet Terraform configuration. Ifmanage_snippets is not set tofalse, then the dynamic snippets will be overwritten and traffic for your service will not be protected by the edge Next-Gen WAF deployment.
provider "sigsci"{corp= var.NGWAF_CORPemail= var.NGWAF_EMAILauth_token= var.NGWAF_TOKENfastly_api_key= var.FASTLY_API_KEY}resource"sigsci_edge_deployment""ngwaf_edge_site_service"{# https://registry.terraform.io/providers/signalsciences/sigsci/latest/docs/resources/edge_deploymentsite_short_name= sigsci_site.ngwaf_edge_site.short_name}resource"sigsci_edge_deployment_service""ngwaf_edge_service_link"{# https://registry.terraform.io/providers/signalsciences/sigsci/latest/docs/resources/edge_deployment_servicesite_short_name= sigsci_site.ngwaf_edge_site.short_namefastly_sid= fastly_service_vcl.frontend-vcl-service.idactivate_version=truepercent_enabled=100depends_on=[ sigsci_edge_deployment.ngwaf_edge_site_service, fastly_service_vcl.frontend-vcl-service, fastly_service_dynamic_snippet_content.ngwaf_config_init, fastly_service_dynamic_snippet_content.ngwaf_config_miss, fastly_service_dynamic_snippet_content.ngwaf_config_pass, fastly_service_dynamic_snippet_content.ngwaf_config_deliver,]}Additionally, if you don't havedynamic backends enabled, you need to add the following:
resource"sigsci_edge_deployment_service_backend""example"{site_short_name= sigsci_site.ngwaf_edge_site.short_namefastly_sid= fastly_service_vcl.frontend-vcl-service.idfastly_service_vcl_active_version= fastly_service_vcl.frontend-vcl-service.active_versiondepends_on=[ sigsci_edge_deployment_service.ngwaf_edge_service_link,]}6. Apply configuration
Apply the Terraform configuration using the following command.
terraform apply -parallelism=1-parallelism=1 is required based on guidance from the Signal Sciences Terraform provider.In case of errors…
When the configuration is applied, the dynamic snippets will be added in a VCL version. The Signal Sciences provider will then do the following:
- Clone the existing active configuration.
- Populate the dynamic snippets and Dictionary with the values needed for the Next-Gen WAF integration.
- Activate the new version.
TIP: Your local Terraform state for the VCL service won't reflect this newly incremented version of the VCL service. Runterraform apply -parallelism=1 again in order to match the local state to the remote state. This
terraform applyshould not make any changes to the VCL service. After a successful run, you should see outputs like the following:
Outputs:live_waf_love_output = <<EOT #### Click the URL to go to the Fastly VCL service #### https://cfg.fastly.com/LINKEDSERVICEID #### Click the URL to go to the Fastly NGWAF service #### https://dashboard.signalsciences.net/corps/my_corp_name/sites/my_site_name #### Send a test request with curl. #### curl -i "https://devhub-ngwaf-terraform-tutorial.global.ssl.fastly.net/anything/whydopirates?likeurls=theargs" -d foo=bar #### Send a test as traversal with curl. #### curl -i "https://devhub-ngwaf-terraform-tutorial.global.ssl.fastly.net/anything/myattackreq?i=../../../../etc/passwd" -d foo=bar #### Send a test as XSS with curl. #### curl -i "https://devhub-ngwaf-terraform-tutorial.global.ssl.fastly.net/anything/myattackreq?foo=%3Cscript%3E" -d foo=bar #### Troubleshoot the logging configuration if necessary. #### https://www.fastly.com/documentation/guides/integrations/streaming-logs/setting-up-remote-log-streaming/#troubleshooting-common-logging-errors curl https://api.fastly.com/service/OuEbVB7UoymNTqI9ghCpE5/logging_status -H fastly-key:$FASTLY_API_KEYEOTresponse_body = [ "LINKEDSERVICEID",]Deployment considerations
Different designs using Terraform will require different approaches. This the following sections contain a few considerations.
Deploying Next-Gen WAF edge to an a new VCL service
For new implementations, you may use the complete Terraform implementation. When running the commandterraform apply -parallelism=1, the implicit dependencies and thedepends_on blocks within the resources ensure that the resources are created in the correct order.
Deploying Next-Gen WAF edge to an existing VCL service
The above methodology can work for an existing VCL service as well. It's very important to follow the guidance forupdating the Fastly VCL service which makes Terraform aware of the dynamic snippets and dictionary. This configurationmust occur before using thesigsci_edge_deployment_service Terraform resource. Otherwise, the dynamic snippets will be overwritten or deleted by subsequentterraform apply runs. For more information on themanage_snippets false configuration, please see our Fastly Terraform provider documentation for the resourcefastly_service_dynamic_snippet_content.
You may complete the Next-Gen WAF edge implementation without sending traffic to the WAF. This can be helpful to test or gradually ramp traffic to the WAF edge implementation. TheEdge_Security Dictionary may also be set to the value0 within the Terraform resourcesigsci_edge_deployment_service using thepercent_enabled field. OurTraffic Ramping documentation has details for thepercent_enabled field.
Deploying Next-Gen WAF edge to an existing Next-Gen WAF site
If you already have a Next-Gen WAF site you wish to use with the Next-Gen WAF edge implementation, then you may remove the Terraform resource blocksigsci_site:
resource"sigsci_site""ngwaf_edge_site"{short_name= var.NGWAF_SITEdisplay_name= var.NGWAF_SITEblock_duration_seconds=86400agent_anon_mode=""agent_level="log"}You must then update all Terraform resources that depend on thesigsci_site resource, by replacing all references tosigsci_site.ngwaf_edge_site.short_name with the valuevar.NGWAF_SITE.
Optional: Identifying Fastly Delivery services linked with Next-Gen WAF edge deployments
Terraform can provide helpful outputs when doing a deployment. The example below shows you how to identify different Delivery services linked to a Next-Gen WAF edge deployment.
provider "http"{}data"http""linked_fastly_services"{url="https://dashboard.signalsciences.net/api/v0/corps/${var.NGWAF_CORP}/sites/${var.NGWAF_SITE}/edgeDeployment"request_headers={x-api-user= var.NGWAF_EMAILx-api-token= var.NGWAF_TOKENContent-Type="application/json"}}output "response_body"{value=[for item in jsondecode(data.http.linked_fastly_services.response_body)["ServicesAttached"] : item.id]}Full reference implementation
Thefastly/ngwaf-terraform-edge-deploy repository closely follows the recommendations in this tutorial.