Skip to content

Commit

Permalink
feat: add ngwaf with successful tfplan
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobCoffee committed Sep 10, 2024
1 parent f72533b commit c8cfda8
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 7 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.

26 changes: 25 additions & 1 deletion infra/cdn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,28 @@ N/A

Tested on
- Tested on Terraform 1.8.5
- Fastly provider 5.13.0
- 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"
...
enable_ngwaf = true
...
}
```

## Requirements

Tested on
- Terraform 1.8.5
- Fastly provider 5.13.0
- SigSci provider 3.3.0
20 changes: 20 additions & 0 deletions infra/cdn/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,23 @@ resource "fastly_service_vcl" "python_org" {
status = 403
}
}

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"
}
140 changes: 140 additions & 0 deletions infra/cdn/ngwaf.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
resource "fastly_service_vcl" "ngwaf_service" {
count = var.activate_ngwaf_service ? 1 : 0
name = "${var.name}-ngwaf"
activate = var.activate_ngwaf_service

domain {
name = var.domain
comment = "NGWAF domain"
}

backend {
address = var.backend_address
name = "ngwaf_backend"
port = 443
use_ssl = true
ssl_cert_hostname = var.backend_address
ssl_sni_hostname = var.backend_address
override_host = var.backend_address
}

# NGWAF Dynamic Snippets
dynamicsnippet {
name = "ngwaf_config_init"
type = "init"
priority = 0
}

dynamicsnippet {
name = "ngwaf_config_miss"
type = "miss"
priority = 9000
}

dynamicsnippet {
name = "ngwaf_config_pass"
type = "pass"
priority = 9000
}

dynamicsnippet {
name = "ngwaf_config_deliver"
type = "deliver"
priority = 9000
}

dictionary {
name = var.edge_security_dictionary
}

product_enablement {
bot_management = true
}

lifecycle {
ignore_changes = [product_enablement]
}
}

output "ngwaf_service_id" {
value = var.activate_ngwaf_service ? fastly_service_vcl.ngwaf_service[0].id : null
}

# Fastly Service Dictionary Items
resource "fastly_service_dictionary_items" "edge_security_dictionary_items" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.ngwaf_service[0].id
dictionary_id = [for d in fastly_service_vcl.ngwaf_service[0].dictionary : d.dictionary_id if d.name == var.edge_security_dictionary][0]
items = {
Enabled : "100"
}
}

# Fastly Service Dynamic Snippet Contents
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_init" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.ngwaf_service[0].id
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_init"][0]
content = "### Fastly managed ngwaf_config_init"
manage_snippets = false
}

resource "fastly_service_dynamic_snippet_content" "ngwaf_config_miss" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.ngwaf_service[0].id
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_miss"][0]
content = "### Fastly managed ngwaf_config_miss"
manage_snippets = false
}

resource "fastly_service_dynamic_snippet_content" "ngwaf_config_pass" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.ngwaf_service[0].id
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_pass"][0]
content = "### Fastly managed ngwaf_config_pass"
manage_snippets = false
}

resource "fastly_service_dynamic_snippet_content" "ngwaf_config_deliver" {
count = var.activate_ngwaf_service ? 1 : 0
service_id = fastly_service_vcl.ngwaf_service[0].id
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_deliver"][0]
content = "### Fastly managed ngwaf_config_deliver"
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.ngwaf_service[0].id
activate_version = var.activate_ngwaf_service
percent_enabled = 100
depends_on = [
sigsci_edge_deployment.ngwaf_edge_site_service,
fastly_service_vcl.ngwaf_service,
fastly_service_dictionary_items.edge_security_dictionary_items,
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,
]
}

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.ngwaf_service[0].id
fastly_service_vcl_active_version = fastly_service_vcl.ngwaf_service[0].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]" # TODO
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]" # TODO
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 c8cfda8

Please sign in to comment.