Skip to content

Commit

Permalink
feat(networking): create cloudfront-redirect module
Browse files Browse the repository at this point in the history
  • Loading branch information
p5 committed Aug 30, 2024
1 parent dfea7c1 commit 502c7af
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 0 deletions.
94 changes: 94 additions & 0 deletions modules/aws/networking/cloudfront-redirect/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
data "aws_route53_zone" "zone" {
for_each = local.redirects

name = each.value.hosted_zone_name
}

locals {
default_root_object_prefix = "domain-redirect-"

status_code_descriptions = {
301 = "Moved Permanently"
302 = "Found"
}

redirects = {
for redirect in var.redirects : replace(redirect.source_domains[0], ".", "_") => redirect
}
}

resource "aws_cloudfront_distribution" "distribution" {
for_each = local.redirects

enabled = true
comment = "Redirect ${each.value.source_domains[0]} to ${each.value.target_url}"
default_root_object = "${local.default_root_object_prefix}${each.value.source_domains[0]}"
aliases = each.value.source_domains

origin {
connection_attempts = 3
connection_timeout = 2
domain_name = each.value.source_domains[0]
origin_id = each.key

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

default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = each.key
viewer_protocol_policy = "redirect-to-https"
compress = false

forwarded_values {
query_string = false
cookies {
forward = "none"
}
}

function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.redirect[each.key].arn
}
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
acm_certificate_arn = each.value.ssl_certificate_arn
ssl_support_method = "sni-only"
}

tags = var.tags_all
}

resource "aws_cloudfront_function" "redirect" {
for_each = local.redirects

name = "${each.key}-redirect"
# Remove the https:// from the target URL
comment = "Redirect ${each.key} to ${trimprefix(each.value.target_url, "https://")}"
runtime = "cloudfront-js-1.0"

code = templatefile("${path.module}/redirect.js.tpl", {
redirect_url = each.value.target_url
redirect_status_code = each.value.status_code
redirect_status_description = local.status_code_descriptions[each.value.status_code]
})

lifecycle {
# Functions cannot be destroyed if they are still associated with a distribution
create_before_destroy = true
}
}
17 changes: 17 additions & 0 deletions modules/aws/networking/cloudfront-redirect/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
output "distribution_arns" {
value = {
for redirect_key, redirect_value in local.redirects : redirect_key => aws_cloudfront_distribution.distribution[redirect_key].arn
}
}

output "distribution_ids" {
value = {
for redirect_key, redirect_value in local.redirects : redirect_key => aws_cloudfront_distribution.distribution[redirect_key].id
}
}

output "function_arns" {
value = {
for redirect_key, redirect_value in local.redirects : redirect_key => aws_cloudfront_function.redirect[redirect_key].arn
}
}
17 changes: 17 additions & 0 deletions modules/aws/networking/cloudfront-redirect/redirect.js.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function handler(event) {
var newUrl = "${redirect_url}"
var statusDescription = "${redirect_status_description}"
var statusCode = ${redirect_status_code}

var response = {
statusCode: statusCode,
statusDescription: statusDescription,
headers:
{
"location": {
"value": newUrl
}
}
}
return response;
}
27 changes: 27 additions & 0 deletions modules/aws/networking/cloudfront-redirect/route53.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
locals {
source_urls = merge([
for redirect_key, redirect_value in local.redirects : {
for source_domain in redirect_value.source_domains :
source_domain => {
redirect_key = redirect_key
target_url = redirect_value.target_url
status_code = redirect_value.status_code
hosted_zone_name = redirect_value.hosted_zone_name
}
}
]...)
}

resource "aws_route53_record" "record" {
for_each = local.source_urls

name = each.key
zone_id = data.aws_route53_zone.zone[each.value.redirect_key].zone_id

type = "A"
alias {
name = aws_cloudfront_distribution.distribution[each.value.redirect_key].domain_name
zone_id = aws_cloudfront_distribution.distribution[each.value.redirect_key].hosted_zone_id
evaluate_target_health = false
}
}
16 changes: 16 additions & 0 deletions modules/aws/networking/cloudfront-redirect/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
variable "redirects" {
type = list(object({
source_domains = list(string)
target_url = string
status_code = optional(number, 301)
hosted_zone_name = string
ssl_certificate_arn = string
}))
description = "A list of redirects to create"
}

variable "tags_all" {
type = map(string)
default = {}
description = "A map of tags to add to all resources"
}
10 changes: 10 additions & 0 deletions modules/aws/networking/cloudfront-redirect/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">=1.3"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">=4.0"
}
}
}

0 comments on commit 502c7af

Please sign in to comment.