Skip to content

Commit 793a91d

Browse files
committed
add cloudfront
1 parent fe1e2de commit 793a91d

File tree

3 files changed

+89
-28
lines changed

3 files changed

+89
-28
lines changed

.readme/cloudfront-nextjs.png

347 KB
Loading

README.md

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
1-
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
1+
# Next.js on AWS Fargate with Terraform
2+
3+
![Preview](./.readme/cloudfront-nextjs.png)
24

3-
## Getting Started
5+
## Architecture
46

5-
First, run the development server:
7+
See the [Terraform code](./infra/main.tf) for the full architecture.
68

7-
```bash
8-
npm run dev
9-
# or
10-
yarn dev
11-
# or
12-
pnpm dev
13-
# or
14-
bun dev
15-
```
16-
17-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18-
19-
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
20-
21-
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
9+
- A VPC with public, private, private isolated subnets
10+
- An ECS cluster with a Fargate service
11+
- A Route 53 private hosted zone for the ECS service (AWS CloudMap/Service Discovery)
12+
- API Gateway w/ VPC Link Integration to the ECS service using the private DNS name
13+
- An ECS task definition with a container that runs the Next.js app
14+
- A CloudFront distribution with an API Gateway origin
2215

23-
## Learn More
16+
## Deploy to AWS with Terraform
2417

25-
To learn more about Next.js, take a look at the following resources:
18+
First, you need to install Terraform. You can download it from [here](https://www.terraform.io/downloads.html).
2619

27-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
2920

30-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31-
32-
## Deploy on Vercel
21+
```bash
22+
cd infra
23+
# Initialize the Terraform providers
24+
terraform init
25+
# See the changes that will be applied
26+
terraform plan
27+
# Apply the changes to your default AWS profile
28+
terraform apply
29+
```
3330

34-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
31+
You can also use a different AWS profile by setting the `AWS_PROFILE` environment variable.
3532

36-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
33+
```bash
34+
AWS_PROFILE=my-profile terraform apply
35+
```

infra/main.tf

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ resource "aws_service_discovery_service" "nextjs_service_discovery" {
312312
}
313313
}
314314

315-
316315
resource "aws_security_group" "nextjs_service_sg" {
317316
vpc_id = aws_vpc.vpc.id
318317
ingress {
@@ -332,3 +331,66 @@ resource "aws_security_group" "nextjs_service_sg" {
332331
ipv6_cidr_blocks = ["::/0"]
333332
}
334333
}
334+
335+
resource "aws_cloudfront_distribution" "nextjs_cdn" {
336+
enabled = true
337+
is_ipv6_enabled = true
338+
origin {
339+
origin_id = "default"
340+
# Use the API gateway as the origin
341+
domain_name = "${aws_apigatewayv2_api.nextjs_api.id}.execute-api.${var.aws_region}.amazonaws.com"
342+
custom_origin_config {
343+
origin_keepalive_timeout = 60
344+
origin_read_timeout = 60
345+
origin_protocol_policy = "https-only"
346+
http_port = 80
347+
https_port = 443
348+
origin_ssl_protocols = ["TLSv1.2"]
349+
}
350+
}
351+
# This is the cheapest price class, targets the US, Canada, and Europe
352+
price_class = "PriceClass_100"
353+
default_cache_behavior {
354+
allowed_methods =["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
355+
cached_methods = ["GET", "HEAD"]
356+
target_origin_id = "default"
357+
viewer_protocol_policy = "redirect-to-https"
358+
cache_policy_id = aws_cloudfront_cache_policy.nextjs_cdn_cache_policy.id
359+
origin_request_policy_id = data.aws_cloudfront_origin_request_policy.all_viewer_except_host_header.id
360+
compress = true # Compress response objects automatically
361+
}
362+
viewer_certificate {
363+
cloudfront_default_certificate = true
364+
}
365+
restrictions {
366+
geo_restriction {
367+
restriction_type = "none"
368+
}
369+
}
370+
}
371+
372+
resource "aws_cloudfront_cache_policy" "nextjs_cdn_cache_policy" {
373+
name = "nextjs-cdn-cache-policy"
374+
parameters_in_cache_key_and_forwarded_to_origin {
375+
cookies_config {
376+
cookie_behavior = "none"
377+
}
378+
headers_config {
379+
header_behavior = "none"
380+
}
381+
query_strings_config {
382+
query_string_behavior = "all"
383+
}
384+
enable_accept_encoding_gzip = true
385+
enable_accept_encoding_brotli = true
386+
}
387+
min_ttl = 0
388+
default_ttl = 0 # Force the CDN to always check the origin for the latest content unless a cache-control header is set
389+
}
390+
391+
# When not using a custom domain name, ignore the host header. Otherwise you'd use
392+
# the "AllViewerAndCloudFrontHeaders-2022-06" policy with ID "33f36d7e-f396-46d9-90e0-52428a34d9dc"
393+
data "aws_cloudfront_origin_request_policy" "all_viewer_except_host_header" {
394+
# See: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html#managed-origin-request-policy-all-viewer-except-host-header
395+
id = "b689b0a8-53d0-40ab-baf2-68738e2966ac"
396+
}

0 commit comments

Comments
 (0)