Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance improvements #222

Merged
merged 9 commits into from
Sep 21, 2024
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
'use strict'
// this handler looks for requests that are effectively for directories
// coming through cloudfront. As it doesn't know that that means to serve
// the index file, it just throws a 404. This will perform the appropriate
// rerouting of the URL so that S3 can retrieve the right file and respond
// correctly.

exports.handler = (event, context, callback) => {
export const handler = async (event) => {
const request = event.Records[0].cf.request;
const { uri } = request;

Expand All @@ -15,5 +14,5 @@ exports.handler = (event, context, callback) => {
request.uri += '/index.html';
}

callback(null, request);
return request;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// Thanks to https://www.ximedes.com/2018-04-23/deploying-gatsby-on-s3-and-cloudfront/
// for the approach which is very solid

exports.handler = (event, context, callback) => {
export const handler = async (event) => {
const request = event.Records[0].cf.request;
const response = event.Records[0].cf.response;
const headers = response.headers;
Expand Down Expand Up @@ -108,5 +108,5 @@ exports.handler = (event, context, callback) => {
}
].forEach(h => (headers[h.key.toLowerCase()] = [h]));

callback(null, response);
return response;
};
15 changes: 7 additions & 8 deletions infra/application/cloudfront.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ resource "aws_cloudfront_origin_access_identity" "origin_access_identity" {
resource "aws_cloudfront_distribution" "web_app" {
enabled = true
is_ipv6_enabled = true
price_class = "PriceClass_100"
http_version = "http2"
price_class = "PriceClass_All"
http_version = "http2and3"
wait_for_deployment = false

aliases = ["ajfisher.me"]
Expand Down Expand Up @@ -47,8 +47,6 @@ resource "aws_cloudfront_distribution" "web_app" {
forwarded_values {
query_string = false

# headers = ["Origin"]

cookies {
forward = "none"
}
Expand Down Expand Up @@ -76,7 +74,7 @@ resource "aws_cloudfront_distribution" "web_app" {
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.apex_cert.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2018"
minimum_protocol_version = "TLSv1.2_2021"
}

depends_on = [aws_acm_certificate_validation.apex_cert]
Expand All @@ -100,11 +98,12 @@ resource "aws_cloudfront_distribution" "redirect_distribution" {
is_ipv6_enabled = true

aliases = ["www.ajfisher.me"]
price_class = "PriceClass_100"
price_class = "PriceClass_All"
http_version = "http2and3"
wait_for_deployment = false

origin {
domain_name = aws_s3_bucket.redirect_to_apex.website_endpoint
domain_name = aws_s3_bucket_website_configuration.redirect_to_apex.website_endpoint
origin_id = "origin-redirect-app-${aws_s3_bucket.redirect_to_apex.id}"

// The redirect origin must be http even if it's on S3 for redirects to work properly
Expand Down Expand Up @@ -138,7 +137,7 @@ resource "aws_cloudfront_distribution" "redirect_distribution" {
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.app_cert.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2018"
minimum_protocol_version = "TLSv1.2_2021"
}

restrictions {
Expand Down
4 changes: 2 additions & 2 deletions infra/application/lambda.tf
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ resource "aws_lambda_function" "redirect_lambda" {

source_code_hash = data.archive_file.cloudfront_lambda_functions.output_base64sha256

runtime = "nodejs14.x"
runtime = "nodejs20.x"
}

resource "aws_lambda_function" "header_lambda" {
Expand All @@ -79,6 +79,6 @@ resource "aws_lambda_function" "header_lambda" {

source_code_hash = data.archive_file.cloudfront_lambda_functions.output_base64sha256

runtime = "nodejs14.x"
runtime = "nodejs20.x"
}

48 changes: 35 additions & 13 deletions infra/application/s3.tf
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
# logfiles for the front end application
resource "aws_s3_bucket" "website_logs" {
bucket = "aj-web-logs-${var.env}"
acl = "log-delivery-write"
tags = {
src = "terraform"
component = "logs"
}
}

resource "aws_s3_bucket_server_side_encryption_configuration" "website-logs-encryption" {
bucket = aws_s3_bucket.website_logs.id

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

resource "aws_s3_bucket_ownership_controls" "website_logs" {
bucket = aws_s3_bucket.website_logs.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}

resource "aws_s3_bucket_acl" "website_logs" {
depends_on = [aws_s3_bucket_ownership_controls.website_logs]

bucket = aws_s3_bucket.website_logs.id
acl = "log-delivery-write"
}

# redirection bucket
resource "aws_s3_bucket" "redirect_to_apex" {
bucket = "ajfisher-site-apex-redirect-${var.env}"
}

resource "aws_s3_bucket_website_configuration" "redirect_to_apex" {
bucket = aws_s3_bucket.redirect_to_apex.id

website {
redirect_all_requests_to = "https://ajfisher.me"
redirect_all_requests_to {
host_name = "ajfisher.me"
protocol = "https"
}
}

resource "aws_s3_bucket_server_side_encryption_configuration" "redirect-encryption" {
bucket = "ajfisher-site-apex-redirect-${var.env}"

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions infra/application/versions.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

terraform {
required_version = ">= 1.0.9"
required_version = ">= 1.9.2"
required_providers {
archive = {
source = "hashicorp/archive"
}
aws = {
source = "hashicorp/aws"
version = "~> 3.63.0"
version = "~> 5.0"
configuration_aliases = [ aws.useast ]
}
}
Expand Down
116 changes: 55 additions & 61 deletions infra/application/web.tf
Original file line number Diff line number Diff line change
@@ -1,66 +1,16 @@
# policy for the bucket
#data "template_file" "bucket_policy" {
# template = <<EOF
#{
# "Version": "2012-10-17",
# "Statement": [{
# "Sid": "OnlyCloudfrontReadAccess",
# "Effect": "Allow",
# "Principal": {
# "AWS": "${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"
# },
# "Action": "s3:GetObject",
# "Resource": "arn:aws:s3:::aj-web-ajfisher-me-${var.env}/*"
# }]
#}
#EOF
#
#}

# data "template_file" "public_bucket_policy" {
# template = <<EOF
# {
# "Version": "2012-10-17",
# "Statement": [{
# "Sid": "PublicRead",
# "Effect": "Allow",
# "Principal": "*",
# "Action": "s3:GetObject",
# "Resource": "arn:aws:s3:::aj-web-ajfisher-me-${var.env}/*"
# }]
# }
# EOF
#
# }

# Location for the frontend code to reside
resource "aws_s3_bucket" "website_code" {
bucket = "aj-web-ajfisher-me-${var.env}"
acl = "private"

# acl = "public-read"

logging {
target_bucket = aws_s3_bucket.website_logs.id
target_prefix = "aj-web-logs-${var.env}/"
}

website {
index_document = "index.html"
error_document = "404.html"
}

cors_rule {
allowed_origins = ["https://www.ajfisher.me"]
allowed_headers = ["Authorization", "Content-Length"]
allowed_methods = ["GET", "HEAD"]
}

tags = {
src = "terraform"
component = "code"
}
# policy = data.template_file.bucket_policy.rendered
}

resource "aws_s3_bucket_policy" "website_code" {
bucket = aws_s3_bucket.website_code.id

policy = <<POLICY
{
"Version": "2012-10-17",
Expand All @@ -75,13 +25,57 @@ resource "aws_s3_bucket" "website_code" {
}]
}
POLICY
}

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
resource "aws_s3_bucket_logging" "website_code" {
bucket = aws_s3_bucket.website_code.id

target_bucket = aws_s3_bucket.website_logs.id
target_prefix = "aj-web-logs-${var.env}/"
}

resource "aws_s3_bucket_website_configuration" "website_code" {
bucket = aws_s3_bucket.website_code.id

index_document {
suffix = "index.html"
}

error_document {
key = "error.html"
}
}

resource "aws_s3_bucket_cors_configuration" "website_code" {
bucket = aws_s3_bucket.website_code.id

cors_rule {
allowed_origins = ["https://ajfisher.me"]
allowed_headers = ["Authorization", "Content-Length"]
allowed_methods = ["GET", "HEAD"]
}
}

resource "aws_s3_bucket_ownership_controls" "website_code" {
bucket = aws_s3_bucket.website_code.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}

resource "aws_s3_bucket_acl" "website_code" {
depends_on = [aws_s3_bucket_ownership_controls.website_code]

bucket = aws_s3_bucket.website_code.id
acl = "private"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "website_code" {
bucket = aws_s3_bucket.website_code.id

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
59 changes: 31 additions & 28 deletions infra/prod/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading