diff --git a/infrastructure/terraform/components/cdn/cloudfront_distribution_cdn.tf b/infrastructure/terraform/components/cdn/cloudfront_distribution_cdn.tf index f680c37..f706415 100644 --- a/infrastructure/terraform/components/cdn/cloudfront_distribution_cdn.tf +++ b/infrastructure/terraform/components/cdn/cloudfront_distribution_cdn.tf @@ -10,8 +10,8 @@ resource "aws_cloudfront_distribution" "main" { restrictions { geo_restriction { - restriction_type = "whitelist" - locations = ["GB"] + restriction_type = "none" # Moved to WAF + locations = [] # Moved to WAF } } diff --git a/infrastructure/terraform/components/cdn/github_ip_ranges.tf b/infrastructure/terraform/components/cdn/github_ip_ranges.tf new file mode 100644 index 0000000..0540d96 --- /dev/null +++ b/infrastructure/terraform/components/cdn/github_ip_ranges.tf @@ -0,0 +1 @@ +data "github_ip_ranges" "main" {} diff --git a/infrastructure/terraform/components/cdn/provider.tf b/infrastructure/terraform/components/cdn/provider.tf index da1e208..b40fb10 100644 --- a/infrastructure/terraform/components/cdn/provider.tf +++ b/infrastructure/terraform/components/cdn/provider.tf @@ -16,3 +16,5 @@ provider "aws" { tags = local.default_tags } } + +provider "github" {} diff --git a/infrastructure/terraform/components/cdn/variables.tf b/infrastructure/terraform/components/cdn/variables.tf index 724b8a3..02554c4 100644 --- a/infrastructure/terraform/components/cdn/variables.tf +++ b/infrastructure/terraform/components/cdn/variables.tf @@ -63,6 +63,12 @@ variable "log_level" { default = "INFO" } +variable "enable_github_actions_ip_access" { + type = bool + description = "Should the Github actions runner IP addresses be permitted access to this distribution. This should not be enabled in production environments" + default = false +} + variable "log_retention_in_days" { type = number description = "The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite" diff --git a/infrastructure/terraform/components/cdn/versions.tf b/infrastructure/terraform/components/cdn/versions.tf index 5fba18d..f113bd7 100644 --- a/infrastructure/terraform/components/cdn/versions.tf +++ b/infrastructure/terraform/components/cdn/versions.tf @@ -4,6 +4,11 @@ terraform { source = "hashicorp/aws" version = "~> 5.50" } + github = { + source = "integrations/github" + version = "~> 6.0" + } + } required_version = ">= 1.9.0" diff --git a/infrastructure/terraform/components/cdn/wafv2_ip_set.tf b/infrastructure/terraform/components/cdn/wafv2_ip_set.tf new file mode 100644 index 0000000..0316882 --- /dev/null +++ b/infrastructure/terraform/components/cdn/wafv2_ip_set.tf @@ -0,0 +1,23 @@ +resource "aws_wafv2_ip_set" "github_actions_ipv4" { + count = var.enable_github_actions_ip_access ? 1:0 + + provider = aws.us-east-1 + + name = "${local.csi}-github-actions-ipv4" + description = "Public references for github actions runner IP addresses" + scope = "CLOUDFRONT" + ip_address_version = "IPV4" + addresses = data.github_ip_ranges.main.actions_ipv4 +} + +resource "aws_wafv2_ip_set" "github_actions_ipv6" { + count = var.enable_github_actions_ip_access ? 1:0 + + provider = aws.us-east-1 + + name = "${local.csi}-github-actions-ipv6" + description = "Public references for github actions runner IP addresses" + scope = "CLOUDFRONT" + ip_address_version = "IPV6" + addresses = data.github_ip_ranges.main.actions_ipv6 +} diff --git a/infrastructure/terraform/components/cdn/wafv2_web_acl.tf b/infrastructure/terraform/components/cdn/wafv2_web_acl.tf index fe6796d..93e178c 100644 --- a/infrastructure/terraform/components/cdn/wafv2_web_acl.tf +++ b/infrastructure/terraform/components/cdn/wafv2_web_acl.tf @@ -2,16 +2,76 @@ resource "aws_wafv2_web_acl" "main" { provider = aws.us-east-1 name = local.csi - description = "${var.environment} with no IP Allowlist" + description = "${var.environment} WAF" scope = "CLOUDFRONT" default_action { allow {} } + dynamic "rule" { + for_each = var.enable_github_actions_ip_access ? [1] : [] + + content { + name = "GithubActionsIPRestriction" + priority = 10 + + action { + allow {} + } + + statement { + or_statement { + statement { + ip_set_reference_statement { + arn = aws_wafv2_ip_set.github_actions_ipv4[0].arn + } + } + + statement { + ip_set_reference_statement { + arn = aws_wafv2_ip_set.github_actions_ipv6[0].arn + } + } + } + } + + visibility_config { + metric_name = "${local.csi}_gha_ip_restrictions_metric" + cloudwatch_metrics_enabled = true + sampled_requests_enabled = true + } + } + } + + rule { + name = "GeoLocationTrafficWhitelist" + priority = 20 + + action { + block {} + } + + statement { + not_statement { + statement { + geo_match_statement { + country_codes = ["GB"] + } + } + } + } + + visibility_config { + cloudwatch_metrics_enabled = true + sampled_requests_enabled = true + metric_name = "${local.csi}_geo_location_whitelist" + } + } + rule { name = "AWSManagedRulesCommonRuleSet" - priority = 10 + priority = 30 override_action { none {} } @@ -37,7 +97,7 @@ resource "aws_wafv2_web_acl" "main" { rule { name = "AWSManagedRulesKnownBadInputsRuleSet" - priority = 20 + priority = 40 override_action { none {} } @@ -56,7 +116,7 @@ resource "aws_wafv2_web_acl" "main" { rule { name = "AWSManagedRulesSQLiRuleSet" - priority = 30 + priority = 50 override_action { none {} } @@ -75,7 +135,7 @@ resource "aws_wafv2_web_acl" "main" { rule { name = "AWSManagedRulesAmazonIpReputationList" - priority = 40 + priority = 60 override_action { none {} } @@ -93,8 +153,8 @@ resource "aws_wafv2_web_acl" "main" { } rule { - name = "rate-limit" - priority = 50 + name = "RateLimit" + priority = 100 action { block {} }