Skip to content

Commit c8cfda8

Browse files
committed
feat: add ngwaf with successful tfplan
1 parent f72533b commit c8cfda8

File tree

9 files changed

+274
-7
lines changed

9 files changed

+274
-7
lines changed

infra/.terraform.lock.hcl

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/cdn/README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,28 @@ N/A
3030

3131
Tested on
3232
- Tested on Terraform 1.8.5
33-
- Fastly provider 5.13.0
33+
- Fastly provider 5.13.0
34+
35+
# Fastly's NGWAF
36+
37+
This module also conditionally can set up the Fastly Next-Gen Web Application Firewall (NGWAF)
38+
for our Fastly services related to python.org / test.python.org.
39+
40+
## Usage
41+
42+
```hcl
43+
module "fastly_production" {
44+
source = "./cdn"
45+
46+
...
47+
enable_ngwaf = true
48+
...
49+
}
50+
```
51+
52+
## Requirements
53+
54+
Tested on
55+
- Terraform 1.8.5
56+
- Fastly provider 5.13.0
57+
- SigSci provider 3.3.0

infra/cdn/main.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,23 @@ resource "fastly_service_vcl" "python_org" {
343343
status = 403
344344
}
345345
}
346+
347+
output "service_id" {
348+
value = fastly_service_vcl.python_org.id
349+
description = "The ID of the Fastly service"
350+
}
351+
352+
output "backend_address" {
353+
value = var.backend_address
354+
description = "The backend address for the service."
355+
}
356+
357+
output "service_name" {
358+
value = var.name
359+
description = "The name of the Fastly service"
360+
}
361+
362+
output "domain" {
363+
value = var.domain
364+
description = "The domain of the Fastly service"
365+
}

infra/cdn/ngwaf.tf

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
resource "fastly_service_vcl" "ngwaf_service" {
2+
count = var.activate_ngwaf_service ? 1 : 0
3+
name = "${var.name}-ngwaf"
4+
activate = var.activate_ngwaf_service
5+
6+
domain {
7+
name = var.domain
8+
comment = "NGWAF domain"
9+
}
10+
11+
backend {
12+
address = var.backend_address
13+
name = "ngwaf_backend"
14+
port = 443
15+
use_ssl = true
16+
ssl_cert_hostname = var.backend_address
17+
ssl_sni_hostname = var.backend_address
18+
override_host = var.backend_address
19+
}
20+
21+
# NGWAF Dynamic Snippets
22+
dynamicsnippet {
23+
name = "ngwaf_config_init"
24+
type = "init"
25+
priority = 0
26+
}
27+
28+
dynamicsnippet {
29+
name = "ngwaf_config_miss"
30+
type = "miss"
31+
priority = 9000
32+
}
33+
34+
dynamicsnippet {
35+
name = "ngwaf_config_pass"
36+
type = "pass"
37+
priority = 9000
38+
}
39+
40+
dynamicsnippet {
41+
name = "ngwaf_config_deliver"
42+
type = "deliver"
43+
priority = 9000
44+
}
45+
46+
dictionary {
47+
name = var.edge_security_dictionary
48+
}
49+
50+
product_enablement {
51+
bot_management = true
52+
}
53+
54+
lifecycle {
55+
ignore_changes = [product_enablement]
56+
}
57+
}
58+
59+
output "ngwaf_service_id" {
60+
value = var.activate_ngwaf_service ? fastly_service_vcl.ngwaf_service[0].id : null
61+
}
62+
63+
# Fastly Service Dictionary Items
64+
resource "fastly_service_dictionary_items" "edge_security_dictionary_items" {
65+
count = var.activate_ngwaf_service ? 1 : 0
66+
service_id = fastly_service_vcl.ngwaf_service[0].id
67+
dictionary_id = [for d in fastly_service_vcl.ngwaf_service[0].dictionary : d.dictionary_id if d.name == var.edge_security_dictionary][0]
68+
items = {
69+
Enabled : "100"
70+
}
71+
}
72+
73+
# Fastly Service Dynamic Snippet Contents
74+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_init" {
75+
count = var.activate_ngwaf_service ? 1 : 0
76+
service_id = fastly_service_vcl.ngwaf_service[0].id
77+
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_init"][0]
78+
content = "### Fastly managed ngwaf_config_init"
79+
manage_snippets = false
80+
}
81+
82+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_miss" {
83+
count = var.activate_ngwaf_service ? 1 : 0
84+
service_id = fastly_service_vcl.ngwaf_service[0].id
85+
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_miss"][0]
86+
content = "### Fastly managed ngwaf_config_miss"
87+
manage_snippets = false
88+
}
89+
90+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_pass" {
91+
count = var.activate_ngwaf_service ? 1 : 0
92+
service_id = fastly_service_vcl.ngwaf_service[0].id
93+
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_pass"][0]
94+
content = "### Fastly managed ngwaf_config_pass"
95+
manage_snippets = false
96+
}
97+
98+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_deliver" {
99+
count = var.activate_ngwaf_service ? 1 : 0
100+
service_id = fastly_service_vcl.ngwaf_service[0].id
101+
snippet_id = [for d in fastly_service_vcl.ngwaf_service[0].dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_deliver"][0]
102+
content = "### Fastly managed ngwaf_config_deliver"
103+
manage_snippets = false
104+
}
105+
106+
# NGWAF Edge Deployment on SignalSciences.net
107+
resource "sigsci_edge_deployment" "ngwaf_edge_site_service" {
108+
count = var.activate_ngwaf_service ? 1 : 0
109+
provider = sigsci.firewall
110+
site_short_name = var.ngwaf_site_name
111+
}
112+
113+
resource "sigsci_edge_deployment_service" "ngwaf_edge_service_link" {
114+
count = var.activate_ngwaf_service ? 1 : 0
115+
provider = sigsci.firewall
116+
site_short_name = var.ngwaf_site_name
117+
fastly_sid = fastly_service_vcl.ngwaf_service[0].id
118+
activate_version = var.activate_ngwaf_service
119+
percent_enabled = 100
120+
depends_on = [
121+
sigsci_edge_deployment.ngwaf_edge_site_service,
122+
fastly_service_vcl.ngwaf_service,
123+
fastly_service_dictionary_items.edge_security_dictionary_items,
124+
fastly_service_dynamic_snippet_content.ngwaf_config_init,
125+
fastly_service_dynamic_snippet_content.ngwaf_config_miss,
126+
fastly_service_dynamic_snippet_content.ngwaf_config_pass,
127+
fastly_service_dynamic_snippet_content.ngwaf_config_deliver,
128+
]
129+
}
130+
131+
resource "sigsci_edge_deployment_service_backend" "ngwaf_edge_service_backend_sync" {
132+
count = var.activate_ngwaf_service ? 1 : 0
133+
provider = sigsci.firewall
134+
site_short_name = var.ngwaf_site_name
135+
fastly_sid = fastly_service_vcl.ngwaf_service[0].id
136+
fastly_service_vcl_active_version = fastly_service_vcl.ngwaf_service[0].active_version
137+
depends_on = [
138+
sigsci_edge_deployment_service.ngwaf_edge_service_link,
139+
]
140+
}

infra/cdn/providers.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,11 @@ provider "fastly" {
22
alias = "cdn"
33
api_key = var.fastly_key
44
}
5+
6+
provider "sigsci" {
7+
alias = "firewall"
8+
corp = var.ngwaf_corp_name
9+
email = var.ngwaf_email
10+
auth_token = var.ngwaf_token
11+
fastly_api_key = var.fastly_key
12+
}

infra/cdn/variables.tf

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,38 @@ variable "backend_address" {
4040
variable "default_ttl" {
4141
type = number
4242
description = "The default TTL for the service."
43-
}
43+
}
44+
45+
## NGWAF
46+
variable "activate_ngwaf_service" {
47+
type = bool
48+
description = "Whether to activate the NGWAF service."
49+
}
50+
variable "edge_security_dictionary" {
51+
type = string
52+
description = "The dictionary name for the Edge Security product."
53+
default = ""
54+
}
55+
variable "ngwaf_corp_name" {
56+
type = string
57+
description = "Corp name for NGWAF"
58+
default = "python"
59+
}
60+
variable "ngwaf_site_name" {
61+
type = string
62+
description = "Site SHORT name for NGWAF"
63+
64+
validation {
65+
condition = can(regex("^(test|stage|prod)$", var.ngwaf_site_name))
66+
error_message = "'ngwaf_site_name' must be one of the following: test, stage, or prod"
67+
}
68+
}
69+
variable "ngwaf_email" {
70+
type = string
71+
description = "Email address associated with the token for the NGWAF API."
72+
}
73+
variable "ngwaf_token" {
74+
type = string
75+
description = "Secret token for the NGWAF API."
76+
sensitive = true
77+
}

infra/cdn/versions.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ terraform {
44
source = "fastly/fastly"
55
version = "5.13.0"
66
}
7+
sigsci = {
8+
source = "signalsciences/sigsci"
9+
version = "3.3.0"
10+
}
711
}
812
}

infra/main.tf

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,20 @@ module "fastly_production" {
1212
fastly_key = var.FASTLY_API_KEY
1313
fastly_header_token = var.FASTLY_HEADER_TOKEN
1414
s3_logging_keys = var.fastly_s3_logging
15+
16+
ngwaf_site_name = "prod"
17+
ngwaf_email = "[email protected]" # TODO
18+
ngwaf_token = var.ngwaf_token
19+
activate_ngwaf_service = false
1520
}
1621

1722
module "fastly_staging" {
1823
source = "./cdn"
1924

20-
name = "test.python.org"
21-
domain = "test.python.org"
22-
subdomain = "www.test.python.org"
23-
extra_domains = ["www.test.python.org"]
25+
name = "test.python.org"
26+
domain = "test.python.org"
27+
subdomain = "www.test.python.org"
28+
extra_domains = ["www.test.python.org"]
2429
# TODO: adjust to test-pythondotorg when done testing NGWAF
2530
backend_address = "pythondotorg.ingress.us-east-2.psfhosted.computer"
2631
default_ttl = 3600
@@ -29,4 +34,9 @@ module "fastly_staging" {
2934
fastly_key = var.FASTLY_API_KEY
3035
fastly_header_token = var.FASTLY_HEADER_TOKEN
3136
s3_logging_keys = var.fastly_s3_logging
37+
38+
ngwaf_site_name = "test"
39+
ngwaf_email = "[email protected]" # TODO
40+
ngwaf_token = var.ngwaf_token
41+
activate_ngwaf_service = true
3242
}

infra/variables.tf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ variable "fastly_s3_logging" {
1717
type = map(string)
1818
description = "S3 bucket keys for Fastly logging"
1919
sensitive = true
20-
}
20+
}
21+
variable "ngwaf_token" {
22+
type = string
23+
description = "Secret token for the NGWAF API."
24+
sensitive = true
25+
}

0 commit comments

Comments
 (0)