Skip to content

milliHQ/terraform-aws-next-js-image-optimization

Repository files navigation

Terraform Next.js Image Optimization module for AWS

CI

A drop-in image optimization loader for the Next.js image component next/image.

Notice: If you look for a complete solution to host a Next.js application with Terraform on AWS, please check out our Terraform Next.js module for AWS.

Features

Architecture

The image optimization module is designed as a full stack AWS app. It relies on multiple AWS services and connects them to work as a single application:

Architecture overview diagram

Usage

1. Deploy the module to AWS

Initialize the module by creating a main.tf file with the following content (you can place the file in the same directory where your Next.js project is located):

# main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

# Main AWS region where the resources should be created in
# Should be close to where your Next.js deployment is located
provider "aws" {
  region = "us-east-1"
}

module "next_image_optimizer" {
  source = "milliHQ/next-js-image-optimization/aws"

  next_image_domains = ["example.com", "sub.example.com"]
}

output "domain" {
  value = module.next_image_optimizer.cloudfront_domain_name
}

Then run Terraform to deploy the image optimiziation module to your AWS account:

terraform init  # Only needed on the first time running Terraform

terraform plan  # (Optional) See what resources Terraform will create
terraform apply # Deploy the image optimizer module to your AWS account

After Terraform has successfully created all resources in your AWS account, you should see the following output on the terminal:

> Apply complete!
>
> Outputs:
>
> domain = "<distribution-id>.cloudfront.net"

You should save the <distribution-id>.cloudfront.net output somewhere since you need it in the next step.

2. Adjust Next.js config

In your Next.js project, open or create the next.config.js file and add the following lines (Remember to replace <distribution-id> with the output from the previous step):

// next.config.js

module.exports = {
+  images: {
+    path: 'https://<distribution-id>.cloudfront.net/_next/image'
+  },
}

Then rebuild and redeploy your Next.js application to make use of the changed configuration.

Examples

Requirements

Name Version
terraform >= 0.13
aws >= 4.8

Providers

Name Version
aws >= 4.8

Inputs

Name Description Type Default Required
cloudfront_acm_certificate_arn CloudFront ACM certificate to use. string null no
cloudfront_aliases Custom domain(s) for CloudFront. list(string) [] no
cloudfront_create_distribution Controls whether a CloudFront distribution should be created. bool true no
cloudfront_enable_origin_shield Controls whether CloudFront Origin Shield should be enabled on the image optimizer lambdas. bool true no
cloudfront_minimum_protocol_version The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. One of SSLv3, TLSv1, TLSv1_2016, TLSv1.1_2016, TLSv1.2_2018 TLSv1.2_2019 or TLSv1.2_2021. string "TLSv1" no
cloudfront_origin_id Override the id for the custom CloudFront id. string "tf-next-image-optimizer" no
cloudfront_origin_shield_region Override the region chosen for the CloudFront origin shield. Use auto to automatically determine the optimal region. string "auto" no
cloudfront_price_class Price class for the CloudFront distribution. One of PriceClass_All, PriceClass_200, PriceClass_100. string "PriceClass_100" no
debug_use_local_packages (Debug) Use local packages instead of downloading them from npm. bool false no
deployment_name Identifier for the deployment group (only lowercase alphanumeric characters and hyphens are allowed). string "tf-next-image" no
lambda_attach_policy_json Controls whether lambda_policy_json should be added to IAM role for Lambda function. bool false no
lambda_memory_size Amount of memory in MB the worker Lambda Function can use. Valid value between 128 MB to 10,240 MB, in 1 MB increments. number 1024 no
lambda_policy_json Additional policy document as JSON to attach to the Lambda Function role. string "" no
lambda_role_permissions_boundary ARN of IAM policy that scopes aws_iam_role access for the lambda. string null no
lambda_timeout Max amount of time the worker Lambda Function has to return a response in seconds. Should not be more than 30 (Limited by API Gateway). number 30 no
next_image_base_origin Base URL where requests for absolute image paths should be resolved to. Should not have a trailing slash. string null no
next_image_content_security_policy Set the value of the Content-Security-Policy header in the response of the image optimizer. string null no
next_image_dangerously_allow_SVG Enable the optimization of SVG images. bool false no
next_image_device_sizes Allowed device sizes that should be used for image optimization. list(number) null no
next_image_domains Allowed origin domains that can be used for fetching images. list(string) [] no
next_image_formats If the Accept head matches more than one of the configured formats, the first match in the array is used. Therefore, the array order matters. If there is no match, the Image Optimization API will fallback to the original image's format. list(string)
[
"image/webp"
]
no
next_image_image_sizes Allowed image sizes that should be used for image optimization. list(number) null no
next_image_version Next.js version from where you want to use the image optimizer from. Supports semver ranges. string "12.1.3" no
source_bucket_id When your static files are deployed to a Bucket (e.g. with Terraform Next.js) the optimizer can pull the source from the bucket rather than over the internet. string null no
tags Tag metadata to label AWS resources that support tags. map(string) {} no

Outputs

Name Description
cloudfront_cache_behavior Predefined CloudFront cache behavior. Can be used to embed the image optimizer into an existing CloudFront resource.
cloudfront_cache_policy_id Cache policy id used for image optimization.
cloudfront_domain_name Domain of the internal CloudFront distribution.
cloudfront_hosted_zone_id Zone id of the internal CloudFront distribution.
cloudfront_origin Predefined CloudFront origin. Can be used to embed the image optimizer into an existing CloudFront resource.
cloudfront_origin_id Id of the custom origin used for image optimization.
cloudfront_origin_request_policy_id Request policy id used for image optimization.

Limits

  • Max file size of a resized image is 6mb (#110)
    Resized images returned by the image optimization API cannot exceed 6mb in size, because this is the maximum allowed payload size for AWS Lambda.

Versioning

The module internally relies on the original Next.js image optimizer. So the versioning of the module is aligned with the version of the corresponding Next.js release.

For example the v10.0.5 version of this Terraform module uses the image optimizer from the Next.js 10.0.5 release.

Please note that we only publish versions >=10.0.5, for a full list of available versions see the published versions in the Terraform Registry.

Contributing

Contributions are welcome!
If you want to improve this module, please take a look at our contributing guide.

About

This project is maintained by milliVolt infrastructure.
We build custom infrastructure solutions for any cloud provider.

License

Apache-2.0 - see LICENSE for details.

Note: All sample projects in examples/* are licensed as MIT to comply with the official Next.js examples.