Skip to content

Commit 409f378

Browse files
committed
Merge remote-tracking branch 'origin/main' into release
2 parents 373817c + 306a73d commit 409f378

10 files changed

+237
-11
lines changed

base-requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ django-waffle==2.2.1
4242

4343
djangorestframework==3.14.0 # 3.14.0 is first version that supports Django 4.1, 4.2 support hasnt been "released"
4444
django-filter==2.4.0
45-
django-ordered-model==3.4.3
45+
django-ordered-model==3.7.4
4646
django-widget-tweaks==1.5.0
4747
django-countries==7.2.1
48-
num2words==0.5.10
48+
num2words==0.5.13
4949
django-polymorphic==3.1.0 # 3.1.0 is first version that supports Django 4.0, unsure if it fully supports 4.2
5050
sorl-thumbnail==12.7.0
5151
django-extensions==3.1.4

infra/.terraform.lock.hcl

+22
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

infra/cdn/README.md

+26-2
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,29 @@ N/A
2929
## Requirements
3030

3131
Tested on
32-
- Tested on Terraform 1.8.5
33-
- Fastly provider 5.13.0
32+
- Tested on Terraform 1.9.5
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+
activate_ngwaf_service = true
48+
...
49+
}
50+
```
51+
52+
## Requirements
53+
54+
Tested on
55+
- Terraform 1.9.5
56+
- Fastly provider 5.13.0
57+
- SigSci provider 3.3.0

infra/cdn/main.tf

+71-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ resource "fastly_service_vcl" "python_org" {
44
http3 = false
55
stale_if_error = false
66
stale_if_error_ttl = 43200
7-
activate = false
7+
activate = true
88

99
domain {
1010
name = var.domain
@@ -342,4 +342,74 @@ resource "fastly_service_vcl" "python_org" {
342342
response = "Forbidden"
343343
status = 403
344344
}
345+
346+
dynamic "dictionary" {
347+
for_each = var.activate_ngwaf_service ? [1] : []
348+
content {
349+
name = var.edge_security_dictionary
350+
force_destroy = true
351+
}
352+
}
353+
354+
dynamic "dynamicsnippet" {
355+
for_each = var.activate_ngwaf_service ? [1] : []
356+
content {
357+
name = "ngwaf_config_init"
358+
type = "init"
359+
priority = 0
360+
}
361+
}
362+
363+
dynamic "dynamicsnippet" {
364+
for_each = var.activate_ngwaf_service ? [1] : []
365+
content {
366+
name = "ngwaf_config_miss"
367+
type = "miss"
368+
priority = 9000
369+
}
370+
}
371+
372+
dynamic "dynamicsnippet" {
373+
for_each = var.activate_ngwaf_service ? [1] : []
374+
content {
375+
name = "ngwaf_config_pass"
376+
type = "pass"
377+
priority = 9000
378+
}
379+
}
380+
381+
dynamic "dynamicsnippet" {
382+
for_each = var.activate_ngwaf_service ? [1] : []
383+
content {
384+
name = "ngwaf_config_deliver"
385+
type = "deliver"
386+
priority = 9000
387+
}
388+
}
389+
390+
lifecycle {
391+
ignore_changes = [
392+
product_enablement,
393+
]
394+
}
395+
}
396+
397+
output "service_id" {
398+
value = fastly_service_vcl.python_org.id
399+
description = "The ID of the Fastly service"
400+
}
401+
402+
output "backend_address" {
403+
value = var.backend_address
404+
description = "The backend address for the service."
405+
}
406+
407+
output "service_name" {
408+
value = var.name
409+
description = "The name of the Fastly service"
410+
}
411+
412+
output "domain" {
413+
value = var.domain
414+
description = "The domain of the Fastly service"
345415
}

infra/cdn/ngwaf.tf

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
resource "fastly_service_dictionary_items" "edge_security_dictionary_items" {
2+
count = var.activate_ngwaf_service ? 1 : 0
3+
service_id = fastly_service_vcl.python_org.id
4+
dictionary_id = one([for d in fastly_service_vcl.python_org.dictionary : d.dictionary_id if d.name == var.edge_security_dictionary])
5+
items = {
6+
Enabled : "100"
7+
}
8+
}
9+
10+
resource "fastly_service_dynamic_snippet_content" "ngwaf_config_snippets" {
11+
for_each = var.activate_ngwaf_service ? toset(["init", "miss", "pass", "deliver"]) : []
12+
service_id = fastly_service_vcl.python_org.id
13+
snippet_id = one([for d in fastly_service_vcl.python_org.dynamicsnippet : d.snippet_id if d.name == "ngwaf_config_${each.key}"])
14+
content = "### Terraform managed ngwaf_config_${each.key}"
15+
manage_snippets = false
16+
}
17+
18+
# NGWAF Edge Deployment on SignalSciences.net
19+
resource "sigsci_edge_deployment" "ngwaf_edge_site_service" {
20+
count = var.activate_ngwaf_service ? 1 : 0
21+
provider = sigsci.firewall
22+
site_short_name = var.ngwaf_site_name
23+
}
24+
25+
resource "sigsci_edge_deployment_service" "ngwaf_edge_service_link" {
26+
count = var.activate_ngwaf_service ? 1 : 0
27+
provider = sigsci.firewall
28+
site_short_name = var.ngwaf_site_name
29+
fastly_sid = fastly_service_vcl.python_org.id
30+
activate_version = var.activate_ngwaf_service
31+
percent_enabled = 100
32+
depends_on = [
33+
sigsci_edge_deployment.ngwaf_edge_site_service,
34+
fastly_service_vcl.python_org,
35+
fastly_service_dictionary_items.edge_security_dictionary_items,
36+
fastly_service_dynamic_snippet_content.ngwaf_config_snippets,
37+
]
38+
}
39+
40+
resource "sigsci_edge_deployment_service_backend" "ngwaf_edge_service_backend_sync" {
41+
count = var.activate_ngwaf_service ? 1 : 0
42+
provider = sigsci.firewall
43+
site_short_name = var.ngwaf_site_name
44+
fastly_sid = fastly_service_vcl.python_org.id
45+
fastly_service_vcl_active_version = fastly_service_vcl.python_org.active_version
46+
depends_on = [
47+
sigsci_edge_deployment_service.ngwaf_edge_service_link,
48+
]
49+
}

infra/cdn/providers.tf

+8
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

+35-1
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 = "Edge_Security"
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

+4
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

+14-4
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]"
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]"
40+
ngwaf_token = var.ngwaf_token
41+
activate_ngwaf_service = true
3242
}

infra/variables.tf

+6-1
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)