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

Add CloudFront policies #82

Merged
merged 1 commit into from
Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions docs/upgrading-v0.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Upgrading to 0.8.0

This is a guide for upgrading from a previous version of this module to `v0.8.0`.

With version `v0.8.0` the CloudFront distributions were updated to use [cache and origin request policies](https://aws.amazon.com/blogs/networking-and-content-delivery/amazon-cloudfront-announces-cache-and-origin-request-policies/) ([#82](https://github.com/dealmore/terraform-aws-next-js/pull/82)) instead of the (now) legacy cache settings.

Unfortunately the Terraform AWS provider currently does not support ([terraform-provider-aws#17626](https://github.com/hashicorp/terraform-provider-aws/issues/17626)) upgrading existing CloudFront distributions from the legacy settings to policies, so the update requires a manual step in the console.

If you are not sure whether you need to apply this steps, you can run `terraform apply`.
When the following error message appears you need to do the manual update:

```
Error: error updating CloudFront Distribution (E27ZJ807F87DQA): InvalidArgument: The parameter ForwardedValues cannot be used when a cache policy is associated to the cache behavior.
status code: 400, request id: 012b60c1-adc8-4175-a5ff-111d819e2b18
```

## Manual upgrade from the AWS Console

Terraform Next.js module for AWS uses two CloudFront distributions, that booth need to be upgraded.

### Upgrading Proxy-Config CloudFront distribution

1. Login into the [AWS Console](https://console.aws.amazon.com/).
2. Go to the [CloudFront service page](https://console.aws.amazon.com/cloudfront/home).
3. Click in the sidebar left on "Distributions".
4. Select the distribution with the suffix **"- Proxy-Config"** (From the "Comment" column) in the list.
5. With the distribution click on "Distribution Settings" button above.
6. In the next screen go to the "Behaviors" tab.
7. It should show you a single behavior in the list. Select it and click on the "Edit" button above.
8. For the setting **"Cache and origin request settings"** switch to **"Use a cache policy and origin request policy"**
9. For **"Cache Policy"** now select **"Managed-CachingOptimizedForUncompressedObjects"** from the dropdown
10. For **"Origin Request Policy"** now select **"Managed-CORS-S3Origin"** from the dropdown
11. Click the button **"Yes, edit"** in the bottom right corner

### Upgrading the main CloudFront distribution

1. Login into the [AWS Console](https://console.aws.amazon.com/).
2. Go to the [CloudFront service page](https://console.aws.amazon.com/cloudfront/home).
3. Click in the sidebar left on "Distributions".
4. Select the distribution with the suffix **"- Main"** (From the "Comment" column) in the list.
5. With the distribution click on "Distribution Settings" button above.
6. In the next screen go to the "Behaviors" tab.
7. Based on your configuration you should see 2 or more entries, the following steps should be completed for each entry:

8. Select a behavior from the list. Click on the "Edit" button above.
9. For the setting **"Cache and origin request settings"** switch to **"Use a cache policy and origin request policy"**.
10. For **"Cache Policy"** now select **"Managed-CachingOptimized"** from the dropdown.
11. For **"Origin Request Policy"** now select **"Managed-CORS-S3Origin"** from the dropdown.
12. Click the button **"Yes, edit"** in the bottom right corner.

13. Repeat the steps 8-12 for all behaviors from this distribution.

After the manual upgrade through the console, run `terraform apply` again.
This time it should apply the changes without errors.
If you still experience issues, please [create an issue](https://github.com/dealmore/terraform-aws-next-js/issues).
67 changes: 50 additions & 17 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,9 @@ module "next_image" {
count = var.create_image_optimization ? 1 : 0

source = "dealmore/next-js-image-optimization/aws"
version = "2.0.1"
version = "~> 10.0.5"

cloudfront_create_distribution = false
next_image_version = var.image_optimization_version

# tf-next does not distinct between image and device sizes, because they
# are eventually merged together on the image optimizer.
Expand Down Expand Up @@ -181,25 +180,13 @@ locals {
path_pattern = "/_next/image*"
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = module.next_image[0].cloudfront_origin_image_optimizer.origin_id
target_origin_id = module.next_image[0].cloudfront_origin_id

compress = true
viewer_protocol_policy = "redirect-to-https"

min_ttl = 0
default_ttl = 86400
max_ttl = 31536000

forwarded_values = {
cookies = {
forward = "none"
}

headers = module.next_image[0].cloudfront_allowed_headers

query_string = true
query_string_cache_keys = module.next_image[0].cloudfront_allowed_query_string_keys
}
origin_request_policy_id = module.next_image[0].cloudfront_origin_request_policy_id
cache_policy_id = module.next_image[0].cloudfront_cache_policy_id
}] : []

cloudfront_custom_behaviors = var.cloudfront_custom_behaviors != null ? merge(
Expand All @@ -208,6 +195,50 @@ locals {
) : local.next_image_custom_behavior
}

resource "random_id" "policy_name" {
prefix = "${var.deployment_name}-"
byte_length = 4
}

# Managed origin request policy
data "aws_cloudfront_origin_request_policy" "managed_all_viewer" {
name = "Managed-AllViewer"
}

resource "aws_cloudfront_cache_policy" "this" {
name = "${random_id.policy_name.hex}-cache"
comment = "Managed by Terraform Next.js"

# Default values (Should be provided by origin)
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000

parameters_in_cache_key_and_forwarded_to_origin {
cookies_config {
cookie_behavior = "all"
}

headers_config {
header_behavior = length(var.cloudfront_cache_key_headers) == 0 ? "none" : "whitelist"

dynamic "headers" {
for_each = length(var.cloudfront_cache_key_headers) == 0 ? [] : [true]
content {
items = var.cloudfront_cache_key_headers
}
}
}

query_strings_config {
query_string_behavior = "all"
}

enable_accept_encoding_gzip = true
enable_accept_encoding_brotli = true
}
}

module "proxy" {
source = "./modules/proxy"

Expand All @@ -225,6 +256,8 @@ module "proxy" {
cloudfront_alias_domains = var.domain_names
cloudfront_viewer_certificate_arn = var.cloudfront_viewer_certificate_arn
cloudfront_minimum_protocol_version = var.cloudfront_minimum_protocol_version
cloudfront_origin_request_policy_id = data.aws_cloudfront_origin_request_policy.managed_all_viewer.id
cloudfront_cache_policy_id = aws_cloudfront_cache_policy.this.id
debug_use_local_packages = var.debug_use_local_packages
tags = var.tags
lambda_role_permissions_boundary = var.lambda_role_permissions_boundary
Expand Down
27 changes: 15 additions & 12 deletions modules/proxy-config/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ resource "aws_s3_bucket_object" "proxy_config" {
# CloudFront
############

# Managed origin request policy
data "aws_cloudfront_origin_request_policy" "managed_cors_s3_origin" {
name = "Managed-CORS-S3Origin"
}

# Managed cache policy
data "aws_cloudfront_cache_policy" "managed_caching_optimized_for_uncompressed_objects" {
name = "Managed-CachingOptimizedForUncompressedObjects"
}

resource "aws_cloudfront_origin_access_identity" "this" {
comment = "S3 CloudFront access ${aws_s3_bucket.proxy_config.id}"
}
Expand All @@ -60,7 +70,6 @@ resource "aws_cloudfront_distribution" "distribution" {
is_ipv6_enabled = true
comment = "${var.deployment_name} - Proxy-Config"
price_class = var.cloudfront_price_class
tags = var.tags

origin {
domain_name = aws_s3_bucket.proxy_config.bucket_regional_domain_name
Expand All @@ -76,19 +85,11 @@ resource "aws_cloudfront_distribution" "distribution" {
cached_methods = ["GET", "HEAD"]
target_origin_id = local.s3_origin_id

forwarded_values {
query_string = false

cookies {
forward = "none"
}
}

# Allow connections via HTTP to improve speed
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000

origin_request_policy_id = data.aws_cloudfront_origin_request_policy.managed_cors_s3_origin.id
cache_policy_id = data.aws_cloudfront_cache_policy.managed_caching_optimized_for_uncompressed_objects.id
}

viewer_certificate {
Expand All @@ -100,4 +101,6 @@ resource "aws_cloudfront_distribution" "distribution" {
restriction_type = "none"
}
}

tags = var.tags
}
55 changes: 22 additions & 33 deletions modules/proxy/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ module "edge_proxy" {
lambda_at_edge = true

function_name = random_id.function_name.hex
description = "Managed by Terraform-next.js"
description = "Managed by Terraform Next.js"
handler = "handler.handler"
runtime = var.lambda_default_runtime
role_permissions_boundary = var.lambda_role_permissions_boundary
Expand All @@ -58,14 +58,23 @@ module "edge_proxy" {
# CloudFront
############

# Managed origin request policy
data "aws_cloudfront_origin_request_policy" "managed_cors_s3_origin" {
name = "Managed-CORS-S3Origin"
}

# Managed cache policy
data "aws_cloudfront_cache_policy" "managed_caching_optimized" {
name = "Managed-CachingOptimized"
}

resource "aws_cloudfront_distribution" "distribution" {
enabled = true
is_ipv6_enabled = true
comment = "${var.deployment_name} - Main"
price_class = var.cloudfront_price_class
aliases = var.cloudfront_alias_domains
default_root_object = "index"
tags = var.tags

# Static deployment S3 bucket
origin {
Expand Down Expand Up @@ -103,6 +112,7 @@ resource "aws_cloudfront_distribution" "distribution" {

dynamic "custom_origin_config" {
for_each = lookup(origin.value, "custom_origin_config", null) != null ? [true] : []

content {
http_port = lookup(origin.value["custom_origin_config"], "http_port", null)
https_port = lookup(origin.value["custom_origin_config"], "https_port", null)
Expand All @@ -121,17 +131,12 @@ resource "aws_cloudfront_distribution" "distribution" {
cached_methods = ["GET", "HEAD"]
target_origin_id = local.origin_id_static_deployment

forwarded_values {
query_string = true

cookies {
forward = "all"
}
}

viewer_protocol_policy = "redirect-to-https"
compress = true

origin_request_policy_id = var.cloudfront_origin_request_policy_id
cache_policy_id = var.cloudfront_cache_policy_id

lambda_function_association {
event_type = "origin-request"
lambda_arn = module.edge_proxy.this_lambda_function_qualified_arn
Expand All @@ -148,21 +153,11 @@ resource "aws_cloudfront_distribution" "distribution" {
cached_methods = ordered_cache_behavior.value["cached_methods"]
target_origin_id = ordered_cache_behavior.value["target_origin_id"]

min_ttl = ordered_cache_behavior.value["min_ttl"]
default_ttl = ordered_cache_behavior.value["default_ttl"]
max_ttl = ordered_cache_behavior.value["max_ttl"]
compress = ordered_cache_behavior.value["compress"]
viewer_protocol_policy = ordered_cache_behavior.value["viewer_protocol_policy"]

dynamic "forwarded_values" {
for_each = lookup(ordered_cache_behavior.value, "forwarded_values", null) != null ? [true] : []
content {
query_string = lookup(ordered_cache_behavior.value["forwarded_values"], "query_string", null)
cookies {
forward = lookup(lookup(ordered_cache_behavior.value["forwarded_values"], "cookies", null), "forward", null)
}
}
}
origin_request_policy_id = ordered_cache_behavior.value["origin_request_policy_id"]
cache_policy_id = ordered_cache_behavior.value["cache_policy_id"]
}
}

Expand All @@ -173,19 +168,11 @@ resource "aws_cloudfront_distribution" "distribution" {
cached_methods = ["GET", "HEAD"]
target_origin_id = local.origin_id_static_deployment

forwarded_values {
query_string = false

cookies {
forward = "none"
}
}

compress = true
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 86400
max_ttl = 31536000

origin_request_policy_id = data.aws_cloudfront_origin_request_policy.managed_cors_s3_origin.id
cache_policy_id = data.aws_cloudfront_cache_policy.managed_caching_optimized.id
}

# Custom error response when a doc is not found in S3 (returns 403)
Expand All @@ -209,4 +196,6 @@ resource "aws_cloudfront_distribution" "distribution" {
restriction_type = "none"
}
}

tags = var.tags
}
Loading