aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorclarkzjw <[email protected]>2022-12-10 23:55:18 -0800
committerclarkzjw <[email protected]>2022-12-10 23:55:18 -0800
commita958bdeb69ebbcb440dcf1c1230f62c76c744f8c (patch)
tree7bacd530a24fa749c75695a7f1f8b8325749f88d
parentb4a5f2ee828dd021ab46196e4e05b27074aabe06 (diff)
downloadjinwei.me-a958bdeb69ebbcb440dcf1c1230f62c76c744f8c.tar.gz
infra: add cloudfront, acm and cloudflare config
-rw-r--r--jinwei.me/infra/.terraform.lock.hcl2
-rw-r--r--jinwei.me/infra/acm.tf41
-rw-r--r--jinwei.me/infra/cloudflare.tf3
-rw-r--r--jinwei.me/infra/cloudfront.tf76
-rw-r--r--jinwei.me/infra/s3.tf8
-rw-r--r--jinwei.me/infra/variables.tf6
-rw-r--r--jinwei.me/infra/versions.tf5
7 files changed, 134 insertions, 7 deletions
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" {
23 23
24provider "registry.terraform.io/hashicorp/aws" { 24provider "registry.terraform.io/hashicorp/aws" {
25 version = "4.46.0" 25 version = "4.46.0"
26 constraints = "~> 4.46" 26 constraints = ">= 3.73.0, ~> 4.46"
27 hashes = [ 27 hashes = [
28 "h1:EZB4OgvytV38JpWyye9zoMQ0bfT9yB9xSXM5NY3Lrws=", 28 "h1:EZB4OgvytV38JpWyye9zoMQ0bfT9yB9xSXM5NY3Lrws=",
29 "zh:1678e6a4bdb3d81a6713adc62ca0fdb8250c584e10c10d1daca72316e9db8df2", 29 "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 @@
1resource "aws_acm_certificate" "main" {
2 domain_name = "static.jinwei.me"
3 validation_method = "DNS"
4
5 subject_alternative_names = [
6 "*.static.jinwei.me",
7 ]
8}
9
10resource "aws_acm_certificate_validation" "main" {
11 certificate_arn = aws_acm_certificate.main.arn
12 validation_record_fqdns = [cloudflare_record.acm.hostname]
13}
14
15
16# CloudFront requires ACM to be in us-east-1, so duplicate the resources.
17resource "aws_acm_certificate" "us-east-1" {
18 provider = aws.us-east-1
19
20 domain_name = "static.jinwei.me"
21 validation_method = "DNS"
22
23 subject_alternative_names = [
24 "*.static.jinwei.me",
25 ]
26}
27
28resource "aws_acm_certificate_validation" "us-east-1" {
29 provider = aws.us-east-1
30
31 certificate_arn = aws_acm_certificate.us-east-1.arn
32 validation_record_fqdns = [cloudflare_record.acm.hostname]
33}
34
35# Cloudflare validation record
36resource "cloudflare_record" "acm" {
37 zone_id = data.cloudflare_zones.domain.zones[0].id
38 name = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_name
39 type = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_type
40 value = tolist(aws_acm_certificate.main.domain_validation_options)[0].resource_record_value
41}
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" {
7} 7}
8 8
9resource "cloudflare_record" "s3_bucket" { 9resource "cloudflare_record" "s3_bucket" {
10 # Point CNAME record in Cloudflare to Cloudfront
10 zone_id = data.cloudflare_zones.domain.zones[0].id 11 zone_id = data.cloudflare_zones.domain.zones[0].id
11 name = var.s3_cdn_name 12 name = var.s3_cdn_name
12 value = aws_s3_bucket.main.bucket_regional_domain_name 13 value = aws_cloudfront_distribution.main.domain_name
13 type = "CNAME" 14 type = "CNAME"
14 15
15 ttl = 1 16 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 @@
1resource "aws_cloudfront_distribution" "main" {
2 aliases = [var.s3_cloudfront_name]
3 enabled = true
4 http_version = "http2and3"
5 is_ipv6_enabled = true
6 price_class = "PriceClass_All"
7 retain_on_delete = true
8 wait_for_deployment = false
9
10 default_cache_behavior {
11 target_origin_id = aws_s3_bucket.main.bucket_regional_domain_name
12
13 compress = true
14 viewer_protocol_policy = "redirect-to-https"
15 allowed_methods = ["GET", "HEAD"]
16 cached_methods = ["GET", "HEAD"]
17 cache_policy_id = data.aws_cloudfront_cache_policy.managed["CachingOptimized"].id
18 origin_request_policy_id = data.aws_cloudfront_origin_request_policy.managed["CORS-S3Origin"].id
19 }
20
21 origin {
22 origin_id = aws_s3_bucket.main.bucket_regional_domain_name
23 domain_name = aws_s3_bucket.main.bucket_regional_domain_name
24 origin_access_control_id = aws_cloudfront_origin_access_control.main.id
25 }
26
27 restrictions {
28 geo_restriction {
29 restriction_type = "none"
30 }
31 }
32
33 viewer_certificate {
34 acm_certificate_arn = aws_acm_certificate_validation.us-east-1.certificate_arn
35 minimum_protocol_version = "TLSv1.2_2021"
36 ssl_support_method = "sni-only"
37 }
38}
39
40resource "aws_cloudfront_origin_access_control" "main" {
41 name = var.s3_cloudfront_name
42 description = var.s3_cloudfront_name
43 origin_access_control_origin_type = "s3"
44 signing_behavior = "always"
45 signing_protocol = "sigv4"
46}
47
48# Managed policies
49locals {
50 managed_cache_policies = [
51 "Amplify",
52 "CachingDisabled",
53 "CachingOptimized",
54 "CachingOptimizedForUncompressedObjects",
55 "Elemental-MediaPackage",
56 ]
57 managed_origin_request_policies = [
58 "AllViewer",
59 "CORS-CustomOrigin",
60 "CORS-S3Origin",
61 "Elemental-MediaTailor-PersonalizedManifests",
62 "UserAgentRefererHeaders",
63 ]
64}
65
66data "aws_cloudfront_cache_policy" "managed" {
67 for_each = toset(local.managed_cache_policies)
68
69 name = "Managed-${each.key}"
70}
71
72data "aws_cloudfront_origin_request_policy" "managed" {
73 for_each = toset(local.managed_origin_request_policies)
74
75 name = "Managed-${each.key}"
76}
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" {
22} 22}
23 23
24data "aws_iam_policy_document" "bucket_policy" { 24data "aws_iam_policy_document" "bucket_policy" {
25 # Allow Cloudflare to read from the bucket 25 # Allow Cloudfront to read from the bucket
26 statement { 26 statement {
27 principals { 27 principals {
28 type = "AWS" 28 type = "AWS"
@@ -37,9 +37,9 @@ data "aws_iam_policy_document" "bucket_policy" {
37 "${aws_s3_bucket.main.arn}/*", 37 "${aws_s3_bucket.main.arn}/*",
38 ] 38 ]
39 condition { 39 condition {
40 test = "IpAddress" 40 test = "StringEquals"
41 variable = "AWS:SourceIp" 41 variable = "AWS:SourceArn"
42 values = data.cloudflare_ip_ranges.cloudflare.cidr_blocks 42 values = [aws_cloudfront_distribution.main.arn]
43 } 43 }
44 } 44 }
45} 45}
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" {
12 description = "AWS region" 12 description = "AWS region"
13} 13}
14 14
15
16# RDS 15# RDS
17variable "rds_initial_db_name" { 16variable "rds_initial_db_name" {
18 default = "wordpress" 17 default = "wordpress"
@@ -60,3 +59,8 @@ variable "s3_cdn_name" {
60 type = string 59 type = string
61 default = "static" 60 default = "static"
62} 61}
62
63variable "s3_cloudfront_name" {
64 type = string
65 default = "static.jinwei.me"
66}
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 {
10 } 10 }
11 } 11 }
12} 12}
13
14provider "aws" {
15 alias = "us-east-1"
16 region = "us-east-1"
17}
Powered by cgit v1.2.3 (git 2.41.0)