Deploying Next.js 15 to AWS CloudFront with CDK

Deploying Next.js 15 to AWS CloudFront with CDK

S

Stewart Moreland

Prerequisites

  1. AWS Account with permissions to create CloudFormation stacks, S3 buckets, Lambda functions, CloudFront distributions, ACM certificates, and Route 53 records.
  2. AWS CLI configured with appropriate credentials (aws configure).
  3. AWS CDK v2 CLI installed globally:
Install AWS CDK
npm install -g aws-cdk

Verify with cdk --version (docs.aws.amazon.com).

  1. Node.js (LTS recommended) and npm installed.
  2. Docker installed if you plan to build containerized Lambda functions (optional for NextjsGlobalFunctions) (github.com).
  3. Route 53 Hosted Zone for your custom domain (optional, if using a custom domain).
💡 CDK Bootstrap

Make sure to bootstrap your AWS environment once per account/region before proceeding with deployment.

Initialize Your CDK Project

Step 1: Create Project Structure

Initialize CDK TypeScript Project
mkdir infrastructure
cd infrastructure
cdk init app --language typescript

This bootstraps a basic CDK project with bin/ and lib/ folders (docs.aws.amazon.com).

Step 2: Bootstrap AWS Environment

Bootstrap CDK Environment
cdk bootstrap

Install and Configure cdk-nextjs

Install the Package

Install cdk-nextjs
npm install cdk-nextjs

This library provides high-level constructs for deploying Next.js apps on AWS (github.com).

Configure Next.js for Standalone Output

In your Next.js application root (outside infrastructure/), update next.config.js:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
reactStrictMode: true,
};
module.exports = nextConfig;
💡 Standalone Output

The standalone output ensures your build artifacts can run independently of Next.js internals, which is required for Lambda deployment.

Define the CDK Stack with NextjsGlobalFunctions

Create your main stack configuration in lib/nextjs-stack.ts:

lib/nextjs-stack.ts
import { App, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { NextjsGlobalFunctions } from 'cdk-nextjs';
import { join } from 'path';
export class NextjsStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new NextjsGlobalFunctions(this, 'NextJsApp', {
// Path to your Next.js project root
buildContext: join(__dirname, '..', 'path-to-next-app'),
// (Optional) health check endpoint
healthCheckPath: '/api/health',
// (Optional) overrides for fine-tuning CloudFront / Lambda
// overrides: { nextjsDistribution: { ... }, nextjsFunctions: { ... } },
});
}
}
const app = new App();
new NextjsStack(app, 'NextJsStack');

What NextjsGlobalFunctions Provides

💡 CloudFront Behavior Limit

CloudFront supports a maximum of 25 behaviors. Group static assets under /static to avoid exceeding this limit.

Alternative Constructs

You can choose other constructs based on your architecture needs:

  • NextjsGlobalContainers - For containerized deployments
  • NextjsRegionalContainers - For single-region container deployments

Add Custom Domain and SSL (ACM + Route 53)

Step 1: Request ACM Certificate

Request ACM Certificate
aws acm request-certificate \
--domain-name example.com \
--validation-method DNS \
--region us-east-1

Step 2: DNS Validation

Validate the certificate by adding the CNAME records ACM returns into your Route 53 hosted zone.

Step 3: Configure Domain in CDK

Update your stack to include custom domain configuration:

Custom Domain Configuration
import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';
new NextjsGlobalFunctions(this, 'NextJsApp', {
buildContext: join(__dirname, '..', 'path-to-next-app'),
domainNames: ['example.com', 'www.example.com'],
certificate: Certificate.fromCertificateArn(
this,
'SiteCert',
'arn:aws:acm:us-east-1:123456789012:certificate/abcd-efgh-...'
),
});

Step 4: Route 53 Alias Record

Create an ALIAS A record pointing example.com → your CloudFront distribution domain. In Route 53:

  1. Choose "Alias to CloudFront distribution"
  2. Select your distribution
  3. Region will pre-select us-east-1

Deploy Your Application

Synthesize and Deploy

Generate CloudFormation Template
cdk synth

Post-Deployment Considerations

Cache Invalidation

For ISR (revalidation) or content updates, manually create invalidations:

CloudFront Cache Invalidation
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths '/*'
💡 Automated Invalidation

Wire a CodeBuild/CodePipeline step to automate cache invalidation on each deploy for seamless updates.

Monitoring & Logging

Security Enhancements

Add WAF Protection
import { WebAcl } from 'aws-cdk-lib/aws-wafv2';
const webAcl = new WebAcl(this, 'WebAcl', {
scope: Scope.CLOUDFRONT,
defaultAction: WafAction.allow(),
rules: [
// Add rate limiting and IP blocking rules
],
});

Troubleshooting Common Issues

Build Failures

Domain Configuration

💡 Certificate Region

Remember: ACM certificates for CloudFront must be in us-east-1, regardless of your application's primary region.


💡 Next Steps

Consider setting up automated CI/CD pipelines and monitoring dashboards to complete your production deployment workflow.