Skip to content

Commit

Permalink
Merge pull request #722 from JiscSD/OC-966
Browse files Browse the repository at this point in the history
OC-966: Save failing on publication edits
  • Loading branch information
finlay-jisc authored Nov 20, 2024
2 parents 68a437b + f37f18d commit 1d28d13
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 1 deletion.
1 change: 0 additions & 1 deletion infra/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ There are some parts of this project's infrastructure that are **not** managed/c
- Route 53 config
- Certificates in Certificate Manager
- AWS Amplify config
- Cloudfront distributions that sit between API domains (e.g. int.api.octopus.ac) and the corresponding API gateway
- An IAM identity provider to allow github actions to act on AWS
## Migration to separate int AWS account
Expand Down
12 changes: 12 additions & 0 deletions infra/create-app/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,15 @@ module "sns" {
project_name = local.project_name
}

module "cloudfront" {
source = "../modules/cloudfront"
environment = local.environment
project_name = local.project_name
# Multiple providers are needed to create resources in different regions.
providers = {
# Default provider (default region).
aws = aws
# Us-east-1 provider, required for cloudfront distribution's web ACL.
aws.us-east-1-provider = aws.us-east-1-provider
}
}
8 changes: 8 additions & 0 deletions infra/create-app/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ provider "aws" {
profile = var.profile
}

# Some resources need to be created in the "global" us-east-1 region.
# This aliased provider allows us to use a different region on a per-resource basis.
provider "aws" {
alias = "us-east-1-provider"
region = "us-east-1"
profile = var.profile
}

terraform {
required_version = ">=1.5.1"
backend "s3" {
Expand Down
210 changes: 210 additions & 0 deletions infra/modules/cloudfront/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
configuration_aliases = [aws.us-east-1-provider]
}
}
}

data "aws_ssm_parameter" "api_gateway_endpoint" {
provider = aws
name = "api_gateway_endpoint_${var.environment}_${var.project_name}"
}

data "aws_ssm_parameter" "api_certificate_arn" {
provider = aws
name = "api_certificate_arn_${var.environment}_${var.project_name}"
}

data "aws_cloudfront_cache_policy" "caching_disabled" {
name = "Managed-CachingDisabled"
}

data "aws_cloudfront_origin_request_policy" "all_viewer_except_host_header" {
name = "Managed-AllViewerExceptHostHeader"
}

resource "aws_wafv2_web_acl" "api_web_acl" {
# Web ACLs of scope CLOUDFRONT must be created in the us-east-1 region, so we use this alternative provider.
provider = aws.us-east-1-provider
name = "${var.project_name}-${var.environment}-web-ACL"
scope = "CLOUDFRONT"
default_action {
allow {
}
}
rule {
name = "${var.project_name}-${var.environment}-RateBasedRule-IP-300"
priority = 0
action {
count {
}
}
statement {
rate_based_statement {
aggregate_key_type = "IP"
limit = 300
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "${var.project_name}-${var.environment}-RateBasedRule-IP-300"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesAmazonIpReputationList"
priority = 1
override_action {
none {
}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesAmazonIpReputationList"
vendor_name = "AWS"
version = null
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesAmazonIpReputationList"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesCommonRuleSet"
priority = 2
override_action {
none {
}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
version = null
# Override default rule which rejects requests with bodies over 16KB.
rule_action_override {
action_to_use {
# The "count" action acknowledges the request without blocking it.
count {}
}
name = "SizeRestrictions_BODY"
}
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesCommonRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
priority = 3
override_action {
none {
}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesKnownBadInputsRuleSet"
vendor_name = "AWS"
version = null
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesSQLiRuleSet"
priority = 4
override_action {
none {
}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesSQLiRuleSet"
vendor_name = "AWS"
version = null
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesSQLiRuleSet"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "${var.project_name}-${var.environment}-web-ACL"
sampled_requests_enabled = true
}
}

resource "aws_cloudfront_distribution" "api" {
aliases = ["${var.environment}.api.octopus.ac"]
comment = "Route traffic from ${var.environment}.api.octopus.ac to API gateway."
enabled = true
http_version = "http2"
is_ipv6_enabled = true
price_class = "PriceClass_All"
retain_on_delete = false
staging = false
wait_for_deployment = true
web_acl_id = aws_wafv2_web_acl.api_web_acl.arn
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cache_policy_id = data.aws_cloudfront_cache_policy.caching_disabled.id
cached_methods = ["GET", "HEAD"]
compress = true
default_ttl = 0
field_level_encryption_id = null
max_ttl = 0
min_ttl = 0
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.all_viewer_except_host_header.id
realtime_log_config_arn = null
response_headers_policy_id = null
smooth_streaming = false
target_origin_id = "${var.environment} API gateway"
trusted_key_groups = []
trusted_signers = []
viewer_protocol_policy = "redirect-to-https"
}
origin {
connection_attempts = 3
connection_timeout = 10
domain_name = data.aws_ssm_parameter.api_gateway_endpoint.value
origin_access_control_id = null
origin_id = "${var.environment} API gateway"
origin_path = "/${var.environment}"
custom_origin_config {
http_port = 80
https_port = 443
origin_keepalive_timeout = 5
origin_protocol_policy = "https-only"
origin_read_timeout = 30
origin_ssl_protocols = ["TLSv1.2"]
}
}
restrictions {
geo_restriction {
locations = []
restriction_type = "none"
}
}
viewer_certificate {
acm_certificate_arn = data.aws_ssm_parameter.api_certificate_arn.value
cloudfront_default_certificate = false
iam_certificate_id = null
minimum_protocol_version = "TLSv1.2_2021"
ssl_support_method = "sni-only"
}
}

8 changes: 8 additions & 0 deletions infra/modules/cloudfront/vars.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
variable "environment" {
type = string
}

variable "project_name" {
type = string
description = "The name of the project"
}

0 comments on commit 1d28d13

Please sign in to comment.