From d47b2e90eae571d2b53aa4561730ba3f11ebf1e4 Mon Sep 17 00:00:00 2001 From: Gabriel Simmer Date: Fri, 14 Jul 2023 16:53:41 +0100 Subject: [PATCH] Various AWS upgrades, static S3 bucket site --- terraform/cloudfront.tf | 16 +-- terraform/gabrielsimmer.com.tf | 29 +++- terraform/gmem.ca.tf | 253 +++++++++++++++++++++++++++------ terraform/main.tf | 8 +- 4 files changed, 244 insertions(+), 62 deletions(-) diff --git a/terraform/cloudfront.tf b/terraform/cloudfront.tf index abac5a5..0a44471 100644 --- a/terraform/cloudfront.tf +++ b/terraform/cloudfront.tf @@ -26,7 +26,7 @@ resource "aws_cloudfront_distribution" "api-by-becki" { enabled = true is_ipv6_enabled = true - aliases = ["api-by-becki.gmem.ca", "api.artbybecki.com"] + aliases = ["api.artbybecki.com"] viewer_certificate { acm_certificate_arn = aws_acm_certificate.api-artbybecki-com.arn ssl_support_method = "sni-only" @@ -61,21 +61,9 @@ resource "aws_cloudfront_cache_policy" "api" { } -resource "aws_acm_certificate" "api-by-becki" { - domain_name = "api-by-becki.gmem.ca" - validation_method = "DNS" - provider = aws.virginia -} - resource "aws_acm_certificate" "api-artbybecki-com" { domain_name = "api.artbybecki.com" validation_method = "DNS" provider = aws.virginia - subject_alternative_names = ["api-by-becki.gmem.ca"] -} - -resource "aws_acm_certificate_validation" "api-by-becki" { - certificate_arn = aws_acm_certificate.api-artbybecki-com.arn - validation_record_fqdns = flatten([[for record in aws_route53_record.api-by-becki-acm : record.fqdn], [for record in cloudflare_record.api-artbybecki-acm : record.hostname]]) - provider = aws.virginia + subject_alternative_names = ["art-by-becki.gmem.ca"] } diff --git a/terraform/gabrielsimmer.com.tf b/terraform/gabrielsimmer.com.tf index ff7dbbf..be7e0a4 100644 --- a/terraform/gabrielsimmer.com.tf +++ b/terraform/gabrielsimmer.com.tf @@ -60,12 +60,35 @@ resource "aws_route53_record" "gabrielsimmercom-github-verification" { ] } -resource "aws_route53_record" "gabrielsimmercom-keybase-verification" { +resource "aws_route53_record" "gabrielsimmercom-txt-verifications" { zone_id = aws_route53_zone.gabrielsimmercom.zone_id name = "gabrielsimmer.com" type = "TXT" ttl = 300 records = [ - "keybase-site-verification=f2MAsoM3HCGQAsYNcWzCy4Ul2kvh79j6etJbL7aQwv8" + "keybase-site-verification=f2MAsoM3HCGQAsYNcWzCy4Ul2kvh79j6etJbL7aQwv8", + "v=spf1 include:spf.messagingengine.com ?all" ] -} \ No newline at end of file +} + +resource "aws_route53_record" "gabrielsimmer-com-mx" { + zone_id = aws_route53_zone.gabrielsimmercom.zone_id + name = "gabrielsimmer.com" + type = "MX" + records = ["10 in1-smtp.messagingengine.com", "20 in2-smtp.messagingengine.com"] + ttl = 300 +} + +resource "aws_route53_record" "gabrielsimmer-com-mail-cname" { + for_each = { + "fm1._domainkey" = "fm1.gabrielsimmer.com.dkim.fmhosted.com" + "fm2._domainkey" = "fm2.gabrielsimmer.com.dkim.fmhosted.com" + "fm3._domainkey" = "fm3.gabrielsimmer.com.dkim.fmhosted.com" + } + + zone_id = aws_route53_zone.gabrielsimmercom.zone_id + name = each.key + records = [each.value] + type = "CNAME" + ttl = 300 +} diff --git a/terraform/gmem.ca.tf b/terraform/gmem.ca.tf index 1d8d19c..78a271b 100644 --- a/terraform/gmem.ca.tf +++ b/terraform/gmem.ca.tf @@ -2,12 +2,37 @@ resource "aws_route53_zone" "gmemca" { name = "gmem.ca" } +resource "aws_route53_record" "fursona" { + zone_id = aws_route53_zone.gmemca.zone_id + name = "fursona" + type = "CNAME" + ttl = 300 + records = ["cname.vercel-dns.com."] +} + +resource "aws_route53_record" "atuin" { + zone_id = aws_route53_zone.gmemca.zone_id + name = "atuin" + type = "A" + ttl = 3600 + records = ["100.77.43.133"] + +} + +resource "aws_route53_record" "n8n" { + zone_id = aws_route53_zone.gmemca.zone_id + name = "n8n" + type = "A" + ttl = 3600 + records = ["100.116.48.47"] +} + resource "aws_route53_record" "hb" { zone_id = aws_route53_zone.gmemca.zone_id name = "hb" type = "A" ttl = 300 - records = ["100.120.232.77"] + records = ["100.77.43.133"] } resource "aws_route53_record" "freshrss" { @@ -15,7 +40,7 @@ resource "aws_route53_record" "freshrss" { name = "freshrss" type = "A" ttl = 300 - records = ["100.120.232.77"] + records = ["100.77.43.133"] } resource "aws_route53_record" "ntfy" { @@ -23,7 +48,7 @@ resource "aws_route53_record" "ntfy" { name = "ntfy" type = "A" ttl = 300 - records = ["100.120.232.77"] + records = ["100.77.43.133"] } resource "aws_route53_record" "dref" { @@ -31,44 +56,7 @@ resource "aws_route53_record" "dref" { name = "dref" type = "A" ttl = 300 - records = ["100.120.232.77"] -} - -resource "aws_route53_record" "api-by-becki" { - zone_id = aws_route53_zone.gmemca.zone_id - name = "abb" - type = "A" - ttl = 300 - records = ["168.119.154.189"] -} - -resource "aws_route53_record" "api-by-becki-primary" { - zone_id = aws_route53_zone.gmemca.zone_id - name = "api-by-becki" - type = "A" - - alias { - name = aws_cloudfront_distribution.api-by-becki.domain_name - zone_id = aws_cloudfront_distribution.api-by-becki.hosted_zone_id - evaluate_target_health = false - } -} - -resource "aws_route53_record" "api-by-becki-acm" { - for_each = { - for dvo in aws_acm_certificate.api-artbybecki-com.domain_validation_options : dvo.domain_name => { - name = dvo.resource_record_name - record = dvo.resource_record_value - type = dvo.resource_record_type - } - } - - allow_overwrite = true - name = each.value.name - records = [each.value.record] - ttl = 60 - type = each.value.type - zone_id = aws_route53_zone.gmemca.zone_id + records = ["100.77.43.133"] } resource "aws_route53_record" "gmem-ca-mx" { @@ -99,3 +87,186 @@ resource "aws_route53_record" "gmem-ca-mail-txt" { records = ["v=spf1 include:spf.messagingengine.com ?all"] ttl = 300 } + +# S3 bucket static site +resource "aws_s3_bucket" "gmem-ca-static_site" { + bucket = "gmem.ca" + + tags = { + Name = "gmem.ca" + } + +} + +resource "aws_cloudfront_origin_access_identity" "oai" { + comment = "OAI for the static site" +} + + +resource "aws_s3_bucket_policy" "gmem-ca-static_site" { + bucket = aws_s3_bucket.gmem-ca-static_site.id + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Sid = "Restrict access to CloudFront OAI" + Effect = "Allow" + Principal = { + AWS = "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${aws_cloudfront_origin_access_identity.oai.id}" + } + Action = "s3:GetObject" + Resource = "arn:aws:s3:::${aws_s3_bucket.gmem-ca-static_site.bucket}/*" + } + ] + }) +} + +resource "aws_s3_bucket_website_configuration" "gmem-ca-static_site" { + bucket = aws_s3_bucket.gmem-ca-static_site.id + + index_document { + suffix = "index.html" + } + + error_document { + key = "error.html" + } +} + +output "website_endpoint" { + value = aws_s3_bucket_website_configuration.gmem-ca-static_site.website_domain +} + +resource "aws_acm_certificate" "gmem-ca-cert" { + domain_name = aws_route53_zone.gmemca.name + validation_method = "DNS" + provider = aws.virginia +} + +resource "aws_route53_record" "gmem-ca-cert_validation" { + for_each = { + for dvo in aws_acm_certificate.gmem-ca-cert.domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } + + name = each.value.name + records = [each.value.record] + ttl = 60 + type = each.value.type + zone_id = aws_route53_zone.gmemca.zone_id +} + +resource "aws_acm_certificate_validation" "gmem-ca-cert" { + certificate_arn = aws_acm_certificate.gmem-ca-cert.arn + validation_record_fqdns = [for record in aws_route53_record.gmem-ca-cert_validation : record.fqdn] + provider = aws.virginia +} + +resource "aws_cloudfront_distribution" "gmem-ca-s3_distribution" { + origin { + domain_name = aws_s3_bucket.gmem-ca-static_site.bucket_regional_domain_name + origin_id = "S3-${aws_s3_bucket.gmem-ca-static_site.id}" + + s3_origin_config { + origin_access_identity = aws_cloudfront_origin_access_identity.oai.cloudfront_access_identity_path + + } + } + + origin { + connection_attempts = 3 + connection_timeout = 10 + domain_name = "8vs70xammd.execute-api.eu-west-2.amazonaws.com" + origin_id = "8vs70xammd.execute-api.eu-west-2.amazonaws.com" + + 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" + ] + } + } + + enabled = true + is_ipv6_enabled = true + comment = "S3 Static Site Distribution for gmem.ca" + default_root_object = "index.html" + + aliases = [aws_acm_certificate.gmem-ca-cert.domain_name] + + default_cache_behavior { + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = "S3-${aws_s3_bucket.gmem-ca-static_site.id}" + response_headers_policy_id = "60669652-455b-4ae9-85a4-c4c02393f86c" + + forwarded_values { + query_string = false + + cookies { + forward = "none" + } + } + + viewer_protocol_policy = "redirect-to-https" + min_ttl = 0 + default_ttl = 3600 + max_ttl = 86400 + } + + ordered_cache_behavior { + path_pattern = "/.well-known/webfinger*" + allowed_methods = ["GET", "HEAD", "OPTIONS"] + cached_methods = ["GET", "HEAD", "OPTIONS"] + target_origin_id = "8vs70xammd.execute-api.eu-west-2.amazonaws.com" + + forwarded_values { + query_string = true + headers = ["Origin", "Accept", "Content-Type"] + + cookies { + forward = "all" + } + } + + viewer_protocol_policy = "redirect-to-https" + min_ttl = 0 + default_ttl = 3600 + max_ttl = 86400 + } + + viewer_certificate { + acm_certificate_arn = aws_acm_certificate_validation.gmem-ca-cert.certificate_arn + ssl_support_method = "sni-only" + minimum_protocol_version = "TLSv1.2_2021" + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + tags = { + Name = "gmem.ca" + } +} + +resource "aws_route53_record" "gmem-ca" { + zone_id = aws_route53_zone.gmemca.zone_id + name = aws_route53_zone.gmemca.name + type = "A" + + alias { + name = aws_cloudfront_distribution.gmem-ca-s3_distribution.domain_name + zone_id = aws_cloudfront_distribution.gmem-ca-s3_distribution.hosted_zone_id + evaluate_target_health = false + } +} diff --git a/terraform/main.tf b/terraform/main.tf index ff0f61f..32f20db 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -11,11 +11,11 @@ terraform { hcloud = { source = "hetznercloud/hcloud" version = "1.36.1" - } - cloudflare = { - source = "cloudflare/cloudflare" + } + cloudflare = { + source = "cloudflare/cloudflare" version = "3.33.1" - } + } } backend "s3" { bucket = "gsimmer-terraform-state"