Skip to content

Commit

Permalink
Remove unused variable; set defaults when null input variables are pr…
Browse files Browse the repository at this point in the history
…ovided; add outputs for each input variable; add unique ID to CloudFront function to prevent conflicts.
  • Loading branch information
KyleKotowick committed Jun 18, 2022
1 parent 7afabfb commit 4f8b2bc
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 29 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ module "domain_redirect" {
// Keep the path and query string of the original request when redirecting
redirect_type = "KEEP_PATH"
// Redirect with a 301 (Moved Permanently) instead of the default 302 (Found)
// Redirect with a 302 (Found) instead of the default 301 (Moved Permanently)
redirect_code = 301
}
```
6 changes: 3 additions & 3 deletions acm.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
locals {
first_from_domain = keys(var.domains_from)[0]
first_from_domain = keys(local.var_domains_from)[0]
}

module "cloudfront_cert" {
Expand All @@ -14,10 +14,10 @@ module "cloudfront_cert" {
]
// The primary domain on the certificate is the first "from" domain
primary_domain = local.first_from_domain
primary_domain_hosted_zone_id = var.domains_from[local.first_from_domain]
primary_domain_hosted_zone_id = local.var_domains_from[local.first_from_domain]
// All other "from" domains are SANs
subject_alternative_names = {
for domain, zone_id in var.domains_from :
for domain, zone_id in local.var_domains_from :
domain => zone_id
if domain != local.first_from_domain
}
Expand Down
20 changes: 10 additions & 10 deletions cloudfront.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@ resource "aws_cloudfront_distribution" "redirect" {

enabled = true
is_ipv6_enabled = true
comment = "CloudFront distribution for redirecting domains."
comment = "CloudFront distribution for redirecting domains to ${local.var_domain_to}."
default_root_object = local.default_root_object

// Configure the CloudFront logging to use the specified S3 bucket
dynamic "logging_config" {
for_each = var.logging_config != null ? [1] : []
for_each = local.var_logging_config != null ? [1] : []
content {
include_cookies = var.logging_config.include_cookies
bucket = var.logging_config.bucket
prefix = var.logging_config.prefix
include_cookies = local.var_logging_config.include_cookies
bucket = local.var_logging_config.bucket
prefix = local.var_logging_config.prefix
}
}

// Set the domain names for the distribution
aliases = keys(var.domains_from)
aliases = keys(local.var_domains_from)

// Cache everything as long as possible, since they all get a redirect
default_cache_behavior {
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["HEAD", "GET", "OPTIONS"]
target_origin_id = "dummy"
viewer_protocol_policy = "allow-all"
min_ttl = var.cache_duration_min
default_ttl = var.cache_duration_default
max_ttl = var.cache_duration_max
min_ttl = local.var_cache_duration_min
default_ttl = local.var_cache_duration_default
max_ttl = local.var_cache_duration_max
compress = false

forwarded_values {
Expand Down Expand Up @@ -76,6 +76,6 @@ resource "aws_cloudfront_distribution" "redirect" {
viewer_certificate {
acm_certificate_arn = module.cloudfront_cert.certificate_arn
ssl_support_method = "sni-only"
minimum_protocol_version = var.ssl_minimum_protocol_version
minimum_protocol_version = local.var_ssl_minimum_protocol_version
}
}
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ resource "random_id" "module_id" {
}

locals {
is_static_redirect = var.redirect_type == "STATIC_PATH"
is_static_redirect = local.var_redirect_type == "STATIC_PATH"
}
51 changes: 51 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,54 @@
//==================================================
// Outputs that match the input variables
//==================================================
output "domains_from" {
description = "The value of the `domains_from` input variable."
value = local.var_domains_from
}
output "domain_to" {
description = "The value of the `domain_to` input variable."
value = local.var_domain_to
}
output "redirect_type" {
description = "The value of the `redirect_type` input variable, or the default value if the input was `null`."
value = local.var_redirect_type
}
output "redirect_static_path" {
description = "The value of the `redirect_static_path` input variable, or the default value if the input was `null`."
value = local.var_redirect_static_path
}
output "redirect_path_prefix" {
description = "The value of the `redirect_path_prefix` input variable, or the default value if the input was `null`."
value = local.var_redirect_path_prefix
}
output "redirect_code" {
description = "The value of the `redirect_code` input variable, or the default value if the input was `null`."
value = local.var_redirect_code
}
output "logging_config" {
description = "The value of the `logging_config` input variable."
value = local.var_logging_config
}
output "cache_duration_min" {
description = "The value of the `cache_duration_min` input variable, or the default value if the input was `null`."
value = local.var_cache_duration_min
}
output "cache_duration_default" {
description = "The value of the `cache_duration_default` input variable, or the default value if the input was `null`."
value = local.var_cache_duration_default
}
output "cache_duration_max" {
description = "The value of the `cache_duration_max` input variable, or the default value if the input was `null`."
value = local.var_cache_duration_max
}
output "ssl_minimum_protocol_version" {
description = "The value of the `ssl_minimum_protocol_version` input variable, or the default value if the input was `null`."
value = local.var_ssl_minimum_protocol_version
}

//==================================================
// Outputs generated by this module
//==================================================
output "cloudfront_distribution" {
description = "The `aws_cloudfront_distribution` resource that was created."
value = aws_cloudfront_distribution.redirect
Expand Down
15 changes: 8 additions & 7 deletions redirect-function.tf
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
// We use this module as a convenient tool for escaping quotes in strings
module "jsonencoded_static_redirect_path" {
source = "Invicton-Labs/jsonencode-no-replacements/null"
version = "~> 0.1.1"
// This trims all leading forward slashes
object = regex("^/*(.*)$", var.redirect_static_path == null ? "/" : var.redirect_static_path)[0]
object = regex("^/*(.*)$", local.var_redirect_static_path == null ? "/" : local.var_redirect_static_path)[0]
}
module "jsonencoded_redirect_path_prefix" {
source = "Invicton-Labs/jsonencode-no-replacements/null"
version = "~> 0.1.1"
// This trims all leading forward slashes
object = regex("^/*(.*)$", var.redirect_path_prefix == null ? "" : var.redirect_path_prefix)[0]
object = regex("^/*(.*)$", local.var_redirect_path_prefix == null ? "" : local.var_redirect_path_prefix)[0]
}

resource "aws_cloudfront_function" "redirect" {
provider = aws.cloudfront
depends_on = [
module.assert_region
]
name = "redirect"
name = "redirect-${random_id.module_id.hex}"
runtime = "cloudfront-js-1.0"
comment = "Redirect all requests"
publish = true
Expand All @@ -32,19 +33,19 @@ function trimLeft(string, charToRemove) {
function handler(event) {
var protocol = event.request.headers['cloudfront-forwarded-proto']['value'];
${local.is_static_redirect ? <<EOF2
var new_uri = protocol + "://${var.domain_to}/" + ${module.jsonencoded_static_redirect_path.encoded};
var new_uri = protocol + "://${local.var_domain_to}/" + ${module.jsonencoded_static_redirect_path.encoded};
EOF2
: <<EOF2
var query_string = Object.keys(event.request.querystring).map(key => key + '=' + event.request.querystring[key]['value']).join('&');
var new_uri = protocol + "://${var.domain_to}/" + ${module.jsonencoded_redirect_path_prefix.encoded} + trimLeft(event.request.uri, "/");
var new_uri = protocol + "://${local.var_domain_to}/" + ${module.jsonencoded_redirect_path_prefix.encoded} + trimLeft(event.request.uri, "/");
if (query_string.length > 0) {
new_uri += "?" + query_string;
}
EOF2
}
return {
statusCode: ${var.redirect_code},
statusDescription: "${var.redirect_code == 301 ? "Moved Permanently" : "Found"}",
statusCode: ${local.var_redirect_code},
statusDescription: "${local.var_redirect_code == 301 ? "Moved Permanently" : "Found"}",
headers: {
"location": {
"value": new_uri
Expand Down
2 changes: 1 addition & 1 deletion route53.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Create a Route53 record for each domain
resource "aws_route53_record" "cloudfront" {
provider = aws.route53
for_each = var.domains_from
for_each = local.var_domains_from
zone_id = each.value
name = each.key
type = "A"
Expand Down
47 changes: 41 additions & 6 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,25 @@ variable "domains_from" {
condition = length(var.domains_from) > 0
error_message = "The `domains_from` variable must include at least 1 element."
}
validation {
condition = var.domains_from != null
error_message = "The `domains_from` variable must not be `null`."
}
}
locals {
var_domains_from = var.domains_from
}

variable "domain_to" {
description = "The domain to redirect requests to."
type = string
validation {
condition = var.domain_to != null
error_message = "The `domain_to` variable must not be `null`."
}
}
locals {
var_domain_to = var.domain_to
}

variable "redirect_type" {
Expand All @@ -21,12 +35,18 @@ variable "redirect_type" {
error_message = "The `redirect_type` variable must be either `KEEP_PATH` or `STATIC_PATH`."
}
}
locals {
var_redirect_type = var.redirect_type != null ? var.redirect_type : "KEEP_PATH"
}

variable "redirect_static_path" {
description = "The fixed, static path to redirect all requests to. It is only used if the `redirect_type` variable is set to `STATIC_PATH`."
type = string
default = "/"
}
locals {
var_redirect_static_path = var.redirect_static_path != null ? var.redirect_static_path : "/"
}

variable "redirect_path_prefix" {
description = <<EOF
Expand All @@ -37,6 +57,9 @@ EOF
type = string
default = ""
}
locals {
var_redirect_path_prefix = var.redirect_path_prefix != null ? var.redirect_path_prefix : ""
}

variable "redirect_code" {
description = "The HTTP code to use for the redirect. Options are `301` (moved permanently) or `302` (moved temporarily)."
Expand All @@ -47,11 +70,8 @@ variable "redirect_code" {
error_message = "The `redirect_code` variable must be either `301` or `302`."
}
}

variable "lambda_log_retention_days" {
description = "The number of days to keep the Lambda@Edge (redirect generation function) logs for."
type = number
default = 14
locals {
var_redirect_code = var.redirect_code != null ? var.redirect_code : 301
}

variable "logging_config" {
Expand All @@ -63,27 +83,42 @@ variable "logging_config" {
})
default = null
}
locals {
var_logging_config = var.logging_config
}

variable "cache_duration_min" {
description = "The minimum number of seconds to use for the CloudFront cache TTL."
type = number
default = 86400
}
locals {
var_cache_duration_min = var.cache_duration_min != null ? var.cache_duration_min : 86400
}

variable "cache_duration_default" {
description = "The default number of seconds to use for the CloudFront cache TTL."
type = number
default = 86400
}
locals {
var_cache_duration_default = var.cache_duration_default != null ? var.cache_duration_default : 86400
}

variable "cache_duration_max" {
description = "The maximum number of seconds to use for the CloudFront cache TTL."
type = number
default = 86400
}
locals {
var_cache_duration_max = var.cache_duration_max != null ? var.cache_duration_max : 86400
}

variable "ssl_minimum_protocol_version" {
description = "The minimum SSL version to support."
type = string
default = "TLSv1.2_2019"
default = "TLSv1.2_2021"
}
locals {
var_ssl_minimum_protocol_version = var.ssl_minimum_protocol_version != null ? var.ssl_minimum_protocol_version : "TLSv1.2_2021"
}

0 comments on commit 4f8b2bc

Please sign in to comment.