diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e4dc1289d..78819bf92 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,6 +9,7 @@ .github/workflows/ @AA-Turner @CAM-Gerlach Makefile @AA-Turner requirements.txt @AA-Turner +infra/ @ewdurbin pep_sphinx_extensions/ @AA-Turner AUTHOR_OVERRIDES.csv @AA-Turner diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 000000000..5dfe3103b --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,2 @@ +.terraform* +terraform.tfstate* diff --git a/infra/config.tf b/infra/config.tf new file mode 100644 index 000000000..2cc663d31 --- /dev/null +++ b/infra/config.tf @@ -0,0 +1,22 @@ +terraform { + required_providers { + fastly = { + source = "fastly/fastly" + version = "1.1.2" + } + } + required_version = ">= 1.1.8" + cloud { + organization = "psf" + workspaces { + name = "peps" + } + } +} +variable "fastly_token" { + type = string + sensitive = true +} +provider "fastly" { + api_key = var.fastly_token +} diff --git a/infra/main.tf b/infra/main.tf new file mode 100644 index 000000000..f1afdc802 --- /dev/null +++ b/infra/main.tf @@ -0,0 +1,73 @@ +resource "fastly_service_vcl" "peps" { + name = "peps.python.org" + activate = true + domain { name = "peps.python.org" } + + backend { + name = "GitHub Pages" + address = "python.github.io" + port = 443 + override_host = "peps.python.org" + + use_ssl = true + ssl_check_cert = true + ssl_cert_hostname = "python.github.io" + ssl_sni_hostname = "python.github.io" + } + + header { + name = "HSTS" + type = "response" + action = "set" + destination = "http.Strict-Transport-Security" + ignore_if_set = false + source = "\"max-age=300\"" + } + + request_setting { + name = "Force TLS" + force_ssl = true + } + + snippet { + name = "serve-rss" + type = "recv" + content = <<-EOT + if (req.url == "/peps.rss/") { + set req.url = "/peps.rss"; + } + EOT + } + + snippet { + name = "redirect" + type = "error" + content = <<-EOT + if (obj.status == 618) { + set obj.status = 302; + set obj.http.Location = "https://" + req.http.host + req.http.Location; + return(deliver); + } + EOT + } + snippet { + name = "redirect-numbers" + type = "recv" + content = <<-EOT + if (req.url ~ "^/(\d|\d\d|\d\d\d|\d\d\d\d)/?$") { + set req.http.Location = "/pep-" + std.strpad(re.group.1, 4, "0") + "/"; + error 618; + } + EOT + } + snippet { + name = "left-pad-pep-numbers" + type = "recv" + content = <<-EOT + if (req.url ~ "^/pep-(\d|\d\d|\d\d\d)/?$") { + set req.http.Location = "/pep-" + std.strpad(re.group.1, 4, "0") + "/"; + error 618; + } + EOT + } +}