Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesgriff committed Feb 12, 2025
1 parent c3d9e3b commit c9f0f05
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 0 deletions.
85 changes: 85 additions & 0 deletions terraform/cloudfront__root_domain_redirect.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

data "aws_cloudfront_cache_policy" "cache_policy__aws_managed_caching_optimised" {
name = "Managed-CachingOptimized"
}

locals {
distribution_for_www_domain_redirect__origin_id = "${var.service_name_hyphens}--${var.environment_hyphens}--www-Domain-Redirect-origin"
}

resource "aws_cloudfront_distribution" "distribution__www_domain_redirect" {
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this CloudFront Distribution if "var.create_redirect_from_www_domain" is true

// CloudFront distributions have to be created in the us-east-1 region (for some reason!)
provider = aws.us-east-1

comment = "${var.service_name_hyphens}--${var.environment_hyphens}--www-domain-redirect"

origin {
domain_name = "example.com" // The origin domain doesn't matter because we use a CloudFront Function to redirect all traffic.
// We shouldn't use a real domain in case any traffic is forwarded, but example.com is reserved as an unused domain name (https://en.wikipedia.org/wiki/Example.com)
origin_id = local.distribution_for_www_domain_redirect__origin_id

custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}

price_class = "PriceClass_100"

aliases = ["${var.dns_record_www_domain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}"]

viewer_certificate {
acm_certificate_arn = aws_acm_certificate_validation.certificate_validation_waiter__www_domain_redirect[0].certificate_arn
cloudfront_default_certificate = false
minimum_protocol_version = "TLSv1"
ssl_support_method = "sni-only"
}

enabled = true
is_ipv6_enabled = true

default_cache_behavior {
cache_policy_id = data.aws_cloudfront_cache_policy.cache_policy__aws_managed_caching_optimised.id
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = local.distribution_for_www_domain_redirect__origin_id
viewer_protocol_policy = "redirect-to-https"
compress = true

function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.redirect_www_domain_function[0].arn
}
}

restrictions {
geo_restriction {
restriction_type = "none"
locations = []
}
}
}

resource "aws_cloudfront_function" "redirect_www_domain_function" {
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this CloudFront Function if "var.create_redirect_from_www_domain" is true

name = "${var.service_name_hyphens}--${var.environment_hyphens}--redirect-www-domain-function"
runtime = "cloudfront-js-1.0"
publish = true
code = <<EOT
function handler(event) {
var response = {
statusCode: 302,
statusDescription: 'Found',
headers: {
"location": { "value": "https://${var.dns_record_subdomain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}" + event.request.uri }
}
};
return response;
}
EOT
}
1 change: 1 addition & 0 deletions terraform/dev.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ environment_hyphens = "Dev"
create_dns_record = true
dns_record_subdomain_including_dot = "dev."

create_redirect_from_www_domain = false
52 changes: 52 additions & 0 deletions terraform/https_certificate.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

////////////////////////////////////////////////
// The HTTPS certificate for the main website

resource "aws_acm_certificate" "https_certificate_for_our_domain" {
// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
provider = aws.us-east-1
Expand Down Expand Up @@ -31,3 +34,52 @@ resource "aws_acm_certificate_validation" "certificate_validation_waiter" {
certificate_arn = aws_acm_certificate.https_certificate_for_our_domain.arn
validation_record_fqdns = [for record in aws_route53_record.example : record.fqdn]
}


///////////////////////////////////////////////////////
// The HTTPS certificate for the www domain redirect

resource "aws_acm_certificate" "https_certificate__www_domain_redirect" {
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this HTTPS Certificate if "var.create_redirect_from_www_domain" is true

// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
provider = aws.us-east-1

domain_name = "${var.dns_record_www_domain_including_dot}${data.aws_route53_zone.route_53_zone_for_our_domain.name}"
validation_method = "DNS"
}

locals {
domain_validation_options = flatten([
for https_certificate in aws_acm_certificate.https_certificate__www_domain_redirect : [
for domain_validation_option in https_certificate.domain_validation_options : {
name = domain_validation_option.resource_record_name
record = domain_validation_option.resource_record_value
type = domain_validation_option.resource_record_type
}
]
])
}

resource "aws_route53_record" "dns_records_for_https_certificate_verification__www_domain_redirect" {
for_each = {
for domain_validation_option in local.domain_validation_options : domain_validation_option.name => domain_validation_option
}

allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = data.aws_route53_zone.route_53_zone_for_our_domain.zone_id
}

resource "aws_acm_certificate_validation" "certificate_validation_waiter__www_domain_redirect" {
count = (var.create_redirect_from_www_domain) ? 1 : 0 // Only create this HTTPS Certificate if "var.create_redirect_from_www_domain" is true

// This certificate is for use by CloudFront, so it has to be created in the us-east-1 region (for some reason!)
provider = aws.us-east-1

certificate_arn = aws_acm_certificate.https_certificate__www_domain_redirect[0].arn
validation_record_fqdns = [for record in aws_route53_record.dns_records_for_https_certificate_verification__www_domain_redirect : record.fqdn]
}
9 changes: 9 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ variable "dns_record_subdomain_including_dot" {
description = "The subdomain (including dot - e.g. 'dev.' or just '' for production) for the Route53 alias record"
}

variable "create_redirect_from_www_domain" {
type = bool
description = "Should terraform create a CloudFront distribution to redirect the www. domain to the root domain"
}
variable "dns_record_www_domain_including_dot" {
type = string
description = "The www. domain (including dot - e.g. 'www.dev.' or just 'www.' for production) for the www domain redirect"
}

// SECRETS
// These variables are set in GitHub Actions environment-specific secrets
// Most of these are passed to the application via Elastic Beanstalk environment variables
Expand Down

0 comments on commit c9f0f05

Please sign in to comment.