Skip to content

Commit

Permalink
Enable edge rate limiting
Browse files Browse the repository at this point in the history
The allows us to rate limit requests at edge.
  • Loading branch information
theseanything committed Jul 11, 2024
1 parent 130b19e commit f06cff9
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 105 deletions.
100 changes: 59 additions & 41 deletions modules/assets/service.tf
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
locals {
template_values = merge(
{ # some defaults
aws_origin_port = 443
minimum_tls_version = "1.2"
ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384"
aws_origin_port = 443
minimum_tls_version = "1.2"
ssl_ciphers = "ECDHE-RSA-AES256-GCM-SHA384"
basic_authentication = null
probe_dns_only = false
probe_dns_only = false

# these values are needed even if mirrors aren't enabled in an environment
s3_mirror_hostname = null
s3_mirror_prefix = null
s3_mirror_probe = null
s3_mirror_port = 443
s3_mirror_hostname = null
s3_mirror_prefix = null
s3_mirror_probe = null
s3_mirror_port = 443
s3_mirror_replica_hostname = null
s3_mirror_replica_prefix = null
s3_mirror_replica_probe = null
s3_mirror_replica_port = 443
gcs_mirror_hostname = null
gcs_mirror_access_id = null
gcs_mirror_secret_key = null
gcs_mirror_bucket_name = null
gcs_mirror_prefix = null
gcs_mirror_probe = null
gcs_mirror_port = 443
s3_mirror_replica_prefix = null
s3_mirror_replica_probe = null
s3_mirror_replica_port = 443
gcs_mirror_hostname = null
gcs_mirror_access_id = null
gcs_mirror_secret_key = null
gcs_mirror_bucket_name = null
gcs_mirror_prefix = null
gcs_mirror_probe = null
gcs_mirror_port = 443
},
{ # computed values
module_path = "${path.module}"
Expand All @@ -43,8 +43,8 @@ resource "fastly_service_vcl" "service" {
}

vcl {
main = true
name = "main"
main = true
name = "main"
content = templatefile("${path.module}/${var.vcl_template_file}", local.template_values)
}

Expand All @@ -54,10 +54,10 @@ resource "fastly_service_vcl" "service" {
}
iterator = each
content {
name = each.key
priority = each.value.priority
name = each.key
priority = each.value.priority
statement = each.value.statement
type = each.value.type
type = each.value.type
}
}

Expand Down Expand Up @@ -94,6 +94,24 @@ resource "fastly_service_vcl" "service" {
}
}

rate_limiter {
name = "rate_limiter"

rps_limit = 500
window_size = 10
penalty_box_duration = 5

client_key = "req.http.Fastly-Client-IP"
http_methods = "GET,PUT,TRACE,POST,HEAD,DELETE,PATCH,OPTIONS"

action = "response"
response {
content = "Too many requests"
content_type = "plain/text"
status = 429
}
}

dynamic "logging_splunk" {
for_each = {
for splunk in lookup(var.secrets, "splunk", []) : splunk.name => splunk
Expand All @@ -114,10 +132,10 @@ resource "fastly_service_vcl" "service" {
}
EOT
))
tls_hostname = each.value.hostname
token = each.value.token
url = each.value.url
use_tls = true
tls_hostname = each.value.hostname
token = each.value.token
url = each.value.url
use_tls = true
response_condition = lookup(each.value, "response_condition", null)
}
}
Expand All @@ -128,19 +146,19 @@ resource "fastly_service_vcl" "service" {
}
iterator = each
content {
name = each.key
bucket_name = each.value.bucket_name
domain = each.value.domain
path = each.value.path
period = each.value.period
redundancy = each.value.redundancy
s3_access_key = each.value.access_key_id
s3_secret_key = each.value.secret_access_key
name = each.key
bucket_name = each.value.bucket_name
domain = each.value.domain
path = each.value.path
period = each.value.period
redundancy = each.value.redundancy
s3_access_key = each.value.access_key_id
s3_secret_key = each.value.secret_access_key
response_condition = lookup(each.value, "response_condition", null)

format_version = 2
message_type = "blank"
gzip_level = 9
format_version = 2
message_type = "blank"
gzip_level = 9
timestamp_format = "%Y-%m-%dT%H:%M:%S.000"

format = lookup(each.value, "format", chomp(
Expand Down Expand Up @@ -176,8 +194,8 @@ resource "fastly_service_dictionary_items" "items" {
for_each = {
for d in fastly_service_vcl.service.dictionary : d.name => d
}
service_id = fastly_service_vcl.service.id
service_id = fastly_service_vcl.service.id
dictionary_id = each.value.dictionary_id
items = var.dictionaries[each.key]
manage_items = true
items = var.dictionaries[each.key]
manage_items = true
}
52 changes: 35 additions & 17 deletions modules/bouncer/service.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ data "http" "domains" {
url = "https://transition.publishing.service.gov.uk/hosts.json"
}

locals {
locals {
domains_json = jsondecode(data.http.domains.response_body)
domains = {
for d in local.domains_json.results:
d.hostname => ""
for d in local.domains_json.results :
d.hostname => ""
}
}

resource "fastly_service_vcl" "service" {
name = "${title(var.environment)} Bouncer"
name = "${title(var.environment)} Bouncer"
comment = ""

dynamic "domain" {
for_each = local.domains
iterator = each
content {
name = each.key
name = each.key
comment = ""
}
}
Expand All @@ -27,30 +27,48 @@ resource "fastly_service_vcl" "service" {
main = true
name = "main"
content = templatefile("${path.module}/${var.vcl_template_file}", {
domain = var.domain,
domain = var.domain,
module_path = "${path.module}"
})
}

rate_limiter {
name = "rate_limiter"

rps_limit = 500
window_size = 10
penalty_box_duration = 5

client_key = "req.http.Fastly-Client-IP"
http_methods = "GET,PUT,TRACE,POST,HEAD,DELETE,PATCH,OPTIONS"

action = "response"
response {
content = "Too many requests"
content_type = "plain/text"
status = 429
}
}

dynamic "logging_s3" {
for_each = {
for s3 in lookup(var.secrets, "s3", []) : s3.name => s3
}
iterator = each
content {
name = each.key
bucket_name = each.value.bucket_name
domain = each.value.domain
path = each.value.path
period = each.value.period
redundancy = each.value.redundancy
s3_access_key = each.value.access_key_id
s3_secret_key = each.value.secret_access_key
name = each.key
bucket_name = each.value.bucket_name
domain = each.value.domain
path = each.value.path
period = each.value.period
redundancy = each.value.redundancy
s3_access_key = each.value.access_key_id
s3_secret_key = each.value.secret_access_key
response_condition = lookup(each.value, "response_condition", null)

format_version = 2
message_type = "blank"
gzip_level = 9
format_version = 2
message_type = "blank"
gzip_level = 9
timestamp_format = "%Y-%m-%dT%H:%M:%S.000"

format = lookup(each.value, "format", chomp(
Expand Down
Loading

0 comments on commit f06cff9

Please sign in to comment.