From a958bdeb69ebbcb440dcf1c1230f62c76c744f8c Mon Sep 17 00:00:00 2001 From: clarkzjw Date: Sat, 10 Dec 2022 23:55:18 -0800 Subject: infra: add cloudfront, acm and cloudflare config --- jinwei.me/infra/.terraform.lock.hcl | 2 +- jinwei.me/infra/acm.tf | 41 ++++++++++++++++++++ jinwei.me/infra/cloudflare.tf | 3 +- jinwei.me/infra/cloudfront.tf | 76 +++++++++++++++++++++++++++++++++++++ jinwei.me/infra/s3.tf | 8 ++-- jinwei.me/infra/variables.tf | 6 ++- jinwei.me/infra/versions.tf | 5 +++ 7 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 jinwei.me/infra/acm.tf create mode 100644 jinwei.me/infra/cloudfront.tf diff --git a/jinwei.me/infra/.terraform.lock.hcl b/jinwei.me/infra/.terraform.lock.hcl index 9fdb71e..e16e9bd 100644 --- a/jinwei.me/infra/.terraform.lock.hcl +++ b/jinwei.me/infra/.terraform.lock.hcl @@ -23,7 +23,7 @@ provider "registry.terraform.io/cloudflare/cloudflare" { provider "registry.terraform.io/hashicorp/aws" { version = "4.46.0" - constraints = "~> 4.46" + constraints = ">= 3.73.0, ~> 4.46" hashes = [ "h1:EZB4OgvytV38JpWyye9zoMQ0bfT9yB9xSXM5NY3Lrws=", "zh:1678e6a4bdb3d81a6713adc62ca0fdb8250c584e10c10d1daca72316e9db8df2", diff --git a/jinwei.me/infra/acm.tf b/jinwei.me/infra/acm.tf new file mode 100644 index 0000000..c6900cd --- /dev/null +++ b/jinwei.me/infra/acm.tf @@ -0,0 +1,41 @@ +resource "aws_acm_certificate" "main" { + domain_name = "static.jinwei.me" + validation_method = "DNS" + + subject_alternative_names = [ + "*.static.jinwei.me", + ] +} + +resource "aws_acm_certificate_validation" "main" { + certificate_arn = aws_acm_certificate.main.arn + validation_record_fqdns = [cloudflare_record.acm.hostname] +} + + +# CloudFront requires ACM to be in us-east-1, so duplicate the resources. +resource "aws_acm_certificate" "us-east-1" { + provider = aws.us-east-1 + + domain_name = "static.jinwei.me" + validation_method = "DNS" + + subject_alternative_names = [ + "*.static.jinwei.me", + ] +} + +resource "aws_acm_certificate_validation" "us-east-1" { + provider = aws.us-east-1 + + certificate_arn = aws_acm_certificate.us-east-1.arn + validation_record_fqdns = [cloudflare_record.acm.hostname] +} + +# Cloudflare validation record +resource "cloudflare_record" "acm" { + zone_id = data.cloudflare_zones.domain.zones[0].id + name = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_name + type = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_type + value = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_value +} diff --git a/jinwei.me/infra/cloudflare.tf b/jinwei.me/infra/cloudflare.tf index 5c79607..a6ca299 100644 --- a/jinwei.me/infra/cloudflare.tf +++ b/jinwei.me/infra/cloudflare.tf @@ -7,9 +7,10 @@ data "cloudflare_zones" "domain" { } resource "cloudflare_record" "s3_bucket" { + # Point CNAME record in Cloudflare to Cloudfront zone_id = data.cloudflare_zones.domain.zones[0].id name = var.s3_cdn_name - value = aws_s3_bucket.main.bucket_regional_domain_name + value = aws_cloudfront_distribution.main.domain_name type = "CNAME" ttl = 1 diff --git a/jinwei.me/infra/cloudfront.tf b/jinwei.me/infra/cloudfront.tf new file mode 100644 index 0000000..2566584 --- /dev/null +++ b/jinwei.me/infra/cloudfront.tf @@ -0,0 +1,76 @@ +resource "aws_cloudfront_distribution" "main" { + aliases = [var.s3_cloudfront_name] + enabled = true + http_version = "http2and3" + is_ipv6_enabled = true + price_class = "PriceClass_All" + retain_on_delete = true + wait_for_deployment = false + + default_cache_behavior { + target_origin_id = aws_s3_bucket.main.bucket_regional_domain_name + + compress = true + viewer_protocol_policy = "redirect-to-https" + allowed_methods = ["GET", "HEAD"] + cached_methods = ["GET", "HEAD"] + cache_policy_id = data.aws_cloudfront_cache_policy.managed["CachingOptimized"].id + origin_request_policy_id = data.aws_cloudfront_origin_request_policy.managed["CORS-S3Origin"].id + } + + origin { + origin_id = aws_s3_bucket.main.bucket_regional_domain_name + domain_name = aws_s3_bucket.main.bucket_regional_domain_name + origin_access_control_id = aws_cloudfront_origin_access_control.main.id + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + acm_certificate_arn = aws_acm_certificate_validation.us-east-1.certificate_arn + minimum_protocol_version = "TLSv1.2_2021" + ssl_support_method = "sni-only" + } +} + +resource "aws_cloudfront_origin_access_control" "main" { + name = var.s3_cloudfront_name + description = var.s3_cloudfront_name + origin_access_control_origin_type = "s3" + signing_behavior = "always" + signing_protocol = "sigv4" +} + +# Managed policies +locals { + managed_cache_policies = [ + "Amplify", + "CachingDisabled", + "CachingOptimized", + "CachingOptimizedForUncompressedObjects", + "Elemental-MediaPackage", + ] + managed_origin_request_policies = [ + "AllViewer", + "CORS-CustomOrigin", + "CORS-S3Origin", + "Elemental-MediaTailor-PersonalizedManifests", + "UserAgentRefererHeaders", + ] +} + +data "aws_cloudfront_cache_policy" "managed" { + for_each = toset(local.managed_cache_policies) + + name = "Managed-${each.key}" +} + +data "aws_cloudfront_origin_request_policy" "managed" { + for_each = toset(local.managed_origin_request_policies) + + name = "Managed-${each.key}" +} diff --git a/jinwei.me/infra/s3.tf b/jinwei.me/infra/s3.tf index 58e0502..49f8e10 100644 --- a/jinwei.me/infra/s3.tf +++ b/jinwei.me/infra/s3.tf @@ -22,7 +22,7 @@ resource "aws_s3_bucket_policy" "main" { } data "aws_iam_policy_document" "bucket_policy" { - # Allow Cloudflare to read from the bucket + # Allow Cloudfront to read from the bucket statement { principals { type = "AWS" @@ -37,9 +37,9 @@ data "aws_iam_policy_document" "bucket_policy" { "${aws_s3_bucket.main.arn}/*", ] condition { - test = "IpAddress" - variable = "AWS:SourceIp" - values = data.cloudflare_ip_ranges.cloudflare.cidr_blocks + test = "StringEquals" + variable = "AWS:SourceArn" + values = [aws_cloudfront_distribution.main.arn] } } } diff --git a/jinwei.me/infra/variables.tf b/jinwei.me/infra/variables.tf index 9145176..2ae72ed 100644 --- a/jinwei.me/infra/variables.tf +++ b/jinwei.me/infra/variables.tf @@ -12,7 +12,6 @@ variable "region" { description = "AWS region" } - # RDS variable "rds_initial_db_name" { default = "wordpress" @@ -60,3 +59,8 @@ variable "s3_cdn_name" { type = string default = "static" } + +variable "s3_cloudfront_name" { + type = string + default = "static.jinwei.me" +} diff --git a/jinwei.me/infra/versions.tf b/jinwei.me/infra/versions.tf index 9d28904..3200530 100644 --- a/jinwei.me/infra/versions.tf +++ b/jinwei.me/infra/versions.tf @@ -10,3 +10,8 @@ terraform { } } } + +provider "aws" { + alias = "us-east-1" + region = "us-east-1" +} -- cgit v1.2.3