Skip to content

Commit

Permalink
feat: add ngwaf (#2527)
Browse files Browse the repository at this point in the history
* feat: add ngwaf with successful tfplan

* docs: update to latest var name

* chore: apply formatting

* feat: make ngwaf bits enabled via var

* fix: use var fvor activation

* fix: fix invalid syntax

* fix: fix invalid syntax again

* chore: use service account

* chore: cleanup cruft

* fix: apply patch for dynamic dynamic things

* Update infra/cdn/README.md

* Update infra/cdn/README.md
  • Loading branch information
JacobCoffee authored Sep 16, 2024
1 parent 0969d72 commit 1795b1f
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 8 deletions.
22 changes: 22 additions & 0 deletions infra/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 26 additions & 2 deletions infra/cdn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,29 @@ N/A
## Requirements

Tested on
- Tested on Terraform 1.8.5
- Fastly provider 5.13.0
- Tested on Terraform 1.9.5
- Fastly provider 5.13.0

# Fastly's NGWAF

This module also conditionally can set up the Fastly Next-Gen Web Application Firewall (NGWAF)
for our Fastly services related to python.org / test.python.org.

## Usage

```hcl
module "fastly_production" {
source = "./cdn"
...
activate_ngwaf_service = true
...
}
```

## Requirements

Tested on
- Terraform 1.9.5
- Fastly provider 5.13.0
- SigSci provider 3.3.0
69 changes: 69 additions & 0 deletions infra/cdn/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -342,4 +342,73 @@ resource "fastly_service_vcl" "python_org" {
response = "Forbidden"
status = 403
}

dynamic "dictionary" {
for_each = var.activate_ngwaf_service ? [1] : []
content {
name = var.edge_security_dictionary
}
}

dynamic "dynamicsnippet" {
for_each = var.activate_ngwaf_service ? [1] : []
content {
name = "ngwaf_config_init"
type = "init"
priority = 0
}
}

dynamic "dynamicsnippet" {
for_each = var.activate_ngwaf_service ? [1] : []
content {
name = "ngwaf_config_miss"
type = "miss"
priority = 9000
}
}

dynamic "dynamicsnippet" {
for_each = var.activate_ngwaf_service ? [1] : []
content {
name = "ngwaf_config_pass"
type = "pass"
priority = 9000
}
}

dynamic "dynamicsnippet" {
for_each = var.activate_ngwaf_service ? [1] : []
content {
name = "ngwaf_config_deliver"
type = "deliver"
priority = 9000
}
}

lifecycle {
ignore_changes = [
product_enablement,
]
}
}

output "service_id" {
value = fastly_service_vcl.python_org.id
description = "The ID of the Fastly service"
}

output "backend_address" {
value = var.backend_address
description = "The backend address for the service."
}

output "service_name" {
value = var.name
description = "The name of the Fastly service"
}

output "domain" {
value = var.domain
description = "The domain of the Fastly service"
}
49 changes: 49 additions & 0 deletions infra/cdn/ngwaf.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
resource "fastly_service_dictionary_items" "edge_security_dictionary_items" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.python_org.id
dictionary_id = one([for d in fastly_service_vcl.python_org.dictionary : d.dictionary_id if d.name == var.edge_security_dictionary])
items = {
Enabled : "100"
}
}

resource "fastly_service_dynamic_snippet_content" "ngwaf_config_snippets" {
for_each = var.activate_ngwaf_service ? toset(["init", "miss", "pass", "deliver"]) : []
service_id = fastly_service_vcl.python_org.id
snippet_id = one([for d in fastly_service_vcl.python_org.dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_${each.key}"])
content = "### Terraform managed ngwaf_config_${each.key}"
manage_snippets = false
}

# NGWAF Edge Deployment on SignalSciences.net
resource "sigsci_edge_deployment" "ngwaf_edge_site_service" {
count = var.activate_ngwaf_service ? 1 : 0
provider = sigsci.firewall
site_short_name = var.ngwaf_site_name
}

resource "sigsci_edge_deployment_service" "ngwaf_edge_service_link" {
count = var.activate_ngwaf_service ? 1 : 0
provider = sigsci.firewall
site_short_name = var.ngwaf_site_name
fastly_sid = fastly_service_vcl.python_org.id
activate_version = var.activate_ngwaf_service
percent_enabled = 100
depends_on = [
sigsci_edge_deployment.ngwaf_edge_site_service,
fastly_service_vcl.python_org,
fastly_service_dictionary_items.edge_security_dictionary_items,
fastly_service_dynamic_snippet_content.ngwaf_config_snippets,
]
}

resource "sigsci_edge_deployment_service_backend" "ngwaf_edge_service_backend_sync" {
count = var.activate_ngwaf_service ? 1 : 0
provider = sigsci.firewall
site_short_name = var.ngwaf_site_name
fastly_sid = fastly_service_vcl.python_org.id
fastly_service_vcl_active_version = fastly_service_vcl.python_org.active_version
depends_on = [
sigsci_edge_deployment_service.ngwaf_edge_service_link,
]
}
8 changes: 8 additions & 0 deletions infra/cdn/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@ provider "fastly" {
alias = "cdn"
api_key = var.fastly_key
}

provider "sigsci" {
alias = "firewall"
corp = var.ngwaf_corp_name
email = var.ngwaf_email
auth_token = var.ngwaf_token
fastly_api_key = var.fastly_key
}
36 changes: 35 additions & 1 deletion infra/cdn/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,38 @@ variable "backend_address" {
variable "default_ttl" {
type = number
description = "The default TTL for the service."
}
}

## NGWAF
variable "activate_ngwaf_service" {
type = bool
description = "Whether to activate the NGWAF service."
}
variable "edge_security_dictionary" {
type = string
description = "The dictionary name for the Edge Security product."
default = ""
}
variable "ngwaf_corp_name" {
type = string
description = "Corp name for NGWAF"
default = "python"
}
variable "ngwaf_site_name" {
type = string
description = "Site SHORT name for NGWAF"

validation {
condition = can(regex("^(test|stage|prod)$", var.ngwaf_site_name))
error_message = "'ngwaf_site_name' must be one of the following: test, stage, or prod"
}
}
variable "ngwaf_email" {
type = string
description = "Email address associated with the token for the NGWAF API."
}
variable "ngwaf_token" {
type = string
description = "Secret token for the NGWAF API."
sensitive = true
}
4 changes: 4 additions & 0 deletions infra/cdn/versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@ terraform {
source = "fastly/fastly"
version = "5.13.0"
}
sigsci = {
source = "signalsciences/sigsci"
version = "3.3.0"
}
}
}
18 changes: 14 additions & 4 deletions infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,20 @@ module "fastly_production" {
fastly_key = var.FASTLY_API_KEY
fastly_header_token = var.FASTLY_HEADER_TOKEN
s3_logging_keys = var.fastly_s3_logging

ngwaf_site_name = "prod"
ngwaf_email = "[email protected]"
ngwaf_token = var.ngwaf_token
activate_ngwaf_service = false
}

module "fastly_staging" {
source = "./cdn"

name = "test.python.org"
domain = "test.python.org"
subdomain = "www.test.python.org"
extra_domains = ["www.test.python.org"]
name = "test.python.org"
domain = "test.python.org"
subdomain = "www.test.python.org"
extra_domains = ["www.test.python.org"]
# TODO: adjust to test-pythondotorg when done testing NGWAF
backend_address = "pythondotorg.ingress.us-east-2.psfhosted.computer"
default_ttl = 3600
Expand All @@ -29,4 +34,9 @@ module "fastly_staging" {
fastly_key = var.FASTLY_API_KEY
fastly_header_token = var.FASTLY_HEADER_TOKEN
s3_logging_keys = var.fastly_s3_logging

ngwaf_site_name = "test"
ngwaf_email = "[email protected]"
ngwaf_token = var.ngwaf_token
activate_ngwaf_service = true
}
7 changes: 6 additions & 1 deletion infra/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ variable "fastly_s3_logging" {
type = map(string)
description = "S3 bucket keys for Fastly logging"
sensitive = true
}
}
variable "ngwaf_token" {
type = string
description = "Secret token for the NGWAF API."
sensitive = true
}

0 comments on commit 1795b1f

Please sign in to comment.