diff --git a/terraform/shortdns.js b/terraform/shortdns.js new file mode 100644 index 0000000..532035a --- /dev/null +++ b/terraform/shortdns.js @@ -0,0 +1,25 @@ +exports.handler = async () => { + + const body = ` + + +301 Moved Permanently + +

301 Moved Permanently

+
CloudFront Lambda@Edge
+ + +`; + + return { + status: '301', + statusDescription: `Redirecting to www domain`, + headers: { + location: [ { + key: 'Location', + value: `https://genderdysphoria.fyi`, + } ], + }, + body, + }; +}; diff --git a/terraform/shortdns.tf b/terraform/shortdns.tf new file mode 100644 index 0000000..da272d8 --- /dev/null +++ b/terraform/shortdns.tf @@ -0,0 +1,227 @@ + +# Site DNS Zone and extra domains +# ----------------------------------------------------------------------------------------------------------- + +# aws_route53_zone.zone +resource "aws_route53_zone" "short_redirect" { + name = var.shortdomain + + tags = { + Site = var.site + Category = "DNS" + } +} + +# namecheap_domain_records.zone +resource "namecheap_domain_records" "short_redirect" { + domain = var.shortdomain + mode = "OVERWRITE" + + nameservers = aws_route53_zone.short_redirect.name_servers +} + + +# ----------------------------------------------------------------------------------------------------------- +# SSL Certificate + +# aws_acm_certificate.cert +resource "aws_acm_certificate" "shortcert" { + domain_name = var.shortdomain + validation_method = "DNS" + + subject_alternative_names = [ + "www.${var.shortdomain}", + ] + + tags = { + Name = "Site Certificate" + Site = var.site + Category = "SSL" + } + + lifecycle { + create_before_destroy = true + } + + depends_on = [ + namecheap_domain_records.short_redirect, + ] +} + +resource "aws_route53_record" "shortcert" { + count = length(aws_acm_certificate.shortcert.domain_validation_options) + + zone_id = aws_route53_zone.short_redirect.id + name = element(aws_acm_certificate.shortcert.domain_validation_options.*.resource_record_name, count.index) + type = element(aws_acm_certificate.shortcert.domain_validation_options.*.resource_record_type, count.index) + records = [element(aws_acm_certificate.shortcert.domain_validation_options.*.resource_record_value, count.index)] + ttl = 60 +} + +resource "aws_acm_certificate_validation" "shortcert" { + certificate_arn = aws_acm_certificate.shortcert.arn + validation_record_fqdns = aws_route53_record.shortcert.*.fqdn +} + +# ----------------------------------------------------------------------------------------------------------- +# Redirection Bucket + + +data "aws_iam_policy_document" "cloudfront_access" { + statement { + sid = "AllowCFOriginAccess" + + actions = [ + "s3:GetObject", + ] + + resources = [ + "${aws_s3_bucket.short_redirect.arn}/*", + ] + + principals { + type = "*" + identifiers = ["*"] + } + } +} + +resource "aws_s3_bucket_policy" "cloudfront_access" { + bucket = aws_s3_bucket.short_redirect.id + policy = data.aws_iam_policy_document.cloudfront_access.json +} + +resource "aws_s3_bucket" "short_redirect" { + bucket = "${var.shortdomain}" +} + + +resource "aws_s3_bucket_acl" "short_redirect" { + bucket = aws_s3_bucket.short_redirect.id + acl = "public-read" +} + +resource "aws_s3_bucket_website_configuration" "short_redirect" { + bucket = aws_s3_bucket.short_redirect.bucket + + redirect_all_requests_to { + host_name = var.domain + protocol = "https" + } +} + + +resource "aws_cloudfront_distribution" "short_redirect" { + origin { + domain_name = aws_s3_bucket.short_redirect.bucket_regional_domain_name + origin_id = aws_s3_bucket.short_redirect.bucket + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = ["SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2"] + } + } + + comment = aws_s3_bucket.short_redirect.bucket + enabled = true + is_ipv6_enabled = false + + aliases = ["www.${var.shortdomain}", var.shortdomain] + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + default_cache_behavior { + allowed_methods = ["GET", "HEAD"] + cached_methods = ["GET", "HEAD"] + target_origin_id = aws_s3_bucket.short_redirect.bucket + compress = true + + min_ttl = 31536000 + max_ttl = 31536000 + default_ttl = 31536000 + + forwarded_values { + query_string = false + + cookies { + forward = "none" + } + } + + lambda_function_association { + event_type = "viewer-request" + lambda_arn = aws_lambda_function.short_redirect.qualified_arn + include_body = false + } + + viewer_protocol_policy = "allow-all" + } + + viewer_certificate { + acm_certificate_arn = aws_acm_certificate.shortcert.arn + ssl_support_method = "sni-only" + } + + wait_for_deployment = false + depends_on = [aws_acm_certificate_validation.shortcert] +} + +resource "aws_route53_record" "short_redirect_site" { + name = var.shortdomain + zone_id = aws_route53_zone.short_redirect.zone_id + type = "A" + + alias { + name = aws_cloudfront_distribution.short_redirect.domain_name + zone_id = aws_cloudfront_distribution.short_redirect.hosted_zone_id + evaluate_target_health = false + } +} + +resource "aws_route53_record" "short_redirect_www" { + name = "www.${var.shortdomain}" + zone_id = aws_route53_zone.short_redirect.zone_id + type = "A" + + alias { + name = aws_cloudfront_distribution.short_redirect.domain_name + zone_id = aws_cloudfront_distribution.short_redirect.hosted_zone_id + evaluate_target_health = false + } +} + + + +# ----------------------------------------------------------------------------------------------------------- +# Lambda Redirect + +data "archive_file" "short_redirect" { + type = "zip" + output_path = ".terraform/tmp/lambda/shortdns.zip" + source_file = "${path.module}/shortdns.js" +} + +resource "aws_lambda_function" "short_redirect" { + description = "index.html subdirectory redirect" + function_name = "${var.site}-short-redirect" + handler = "shortdns.handler" + + filename = data.archive_file.short_redirect.output_path + source_code_hash = data.archive_file.short_redirect.output_base64sha256 + + publish = true + role = aws_iam_role.lambda_redirect.arn + runtime = "nodejs16.x" + + tags = { + Name = "${var.site}-short" + Site = var.site + } +} + diff --git a/terraform/vars.tf b/terraform/vars.tf index 6346bba..a0b1c10 100644 --- a/terraform/vars.tf +++ b/terraform/vars.tf @@ -17,6 +17,11 @@ variable "domain" { default = "genderdysphoria.fyi" } +variable "shortdomain" { + type = string + default = "gdb.fyi" +} + variable "subdomains" { type = list default = [