[AWS] AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイする

2025/01/07

AWS
CDK
Next.js

こんにちは。今年もよろしくお願いします。

今回は、AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイする方法を紹介します。

AWS CDKとは

AWS CDK(Cloud Development Kit)は、AWSのリソースをコードで管理するためのフレームワークです。CDKを使うことで、AWSのリソースをコードで定義し、デプロイすることができます。

Next.jsのデプロイ方法について

Next.jsには、用途に合わせて様々なデプロイ方法があります。

下記4つのデプロイ方法について、それぞれの特徴を紹介します。

今回は、SSG(Static Site Generation)を使ったデプロイ方法を紹介します。

SSG(Static Site Generation)

SSGは、ビルド時にHTMLファイルを生成し、それを配信する方法です。ビルド時に生成されたHTMLファイルをアップロードするだけで、サイトを公開することができます。

特に、静的なコンテンツを持つサイトや、SEO対策を行いたい場合に適しています。

ISR(Incremental Static Regeneration)

ISRは、ビルド時にHTMLファイルを生成し、それを配信する方法です。ただし、ISRでは、ビルド時に生成されたHTMLファイルをキャッシュし、リクエストがあった際に再生成することができます。

特に、頻繁に更新されるコンテンツを持つサイトや、リアルタイムな情報を提供したい場合に適しています。

SSR(Server Side Rendering)

SSRは、リクエストがあった際にサーバー側でHTMLファイルを生成し、それを配信する方法です。

リクエストがあるたびにHTMLファイルを生成するため、動的なコンテンツを持つサイトや、セッション管理が必要な場合に適しています。

CSR(Client Side Rendering)

CSRは、リクエストがあった際にクライアント側でHTMLファイルを生成し、それを配信する方法です。

クライアント側でHTMLファイルを生成するため、動的なコンテンツを持つサイトや、SPA(Single Page Application)に適しています。

CloudFrontとS3

CloudFrontは、コンテンツを高速に配信するためのCDN(Content Delivery Network)です。CloudFrontを使うことで、ユーザーに近い場所からコンテンツを配信することができます。

S3は、オブジェクトストレージサービスです。S3を使うことで、大容量のデータを安全に保存することができます。

S3とCloudFrontを組み合わせることで、高速かつ安全にコンテンツを配信することができます。

さあ、始めましょう

それでは、AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイする方法を紹介します。

はじめに、今回の簡単なディレクトリ構成を紹介します。

.
├── cdk
│   ├── bin
│   │   └── cdk.ts
│   ├── lib
│   │   └── cdk-stack.ts
│   └── package.json
└── nextjs
    ├── out
    ├── src
    │   └── app
    │       └── page.tsx
    ├── next.config.js
    └── package.json

このディレクトリ構成では、cdkディレクトリにAWS CDKのコードを、nextjsディレクトリにNext.jsのコードを配置しています。

1. AWS CDKのセットアップ

まずは、AWS CDKのセットアップを行います。

mkdir cdk
cd cdk
npm install -g aws-cdk
cdk init app --language typescript

2. Next.jsのセットアップ

次に、Next.jsのセットアップを行います。

mkdir nextjs
cd nextjs
npx create-next-app@latest --typescript

3. AWS CDKでの設定

次に、AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイするための設定を行います。

cdk/lib/cdk-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';

export class CdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // S3バケットを作成
    const bucket = new s3.Bucket(this, 'NextjsSsgBucket', {
      websiteIndexDocument: 'index.html',
      publicReadAccess: true,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ACLS, // パブリックアクセス制限を解除
      removalPolicy: cdk.RemovalPolicy.DESTROY, // 開発用: スタック削除時にバケットも削除
    });

    // CloudFrontディストリビューションを作成
    const distribution = new cloudfront.Distribution(this, 'NextjsSsgDistribution', {
      defaultBehavior: {
        origin: new origins.S3StaticWebsiteOrigin(bucket),
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
      },
    });

    // S3に静的ファイルをデプロイ
    new s3deploy.BucketDeployment(this, 'NextjsSsgDeployment', {
      sources: [s3deploy.Source.asset('../next-app/out')], // Next.jsの静的ファイルフォルダ
      destinationBucket: bucket,
      distribution,
      distributionPaths: ['/*'], // CloudFrontキャッシュを無効化
    });

    // 出力: S3バケット名とCloudFront URL
    new cdk.CfnOutput(this, 'BucketName', {
      value: bucket.bucketName,
    });
    new cdk.CfnOutput(this, 'CloudFrontURL', {
      value: `https://${distribution.domainName}`,
    });
  }
}

4. Next.jsのビルド

次に、Next.jsのビルドを行います。

cd nextjs
npm run build

ビルドが完了すると、outディレクトリに静的ファイルが生成されます。

5. デプロイ

最後に、AWS CDKでNext.jsのSSGでCloudFrontとS3にデプロイします。

cd cdk
cdk bootstrap
cdk deploy

デプロイが完了すると、S3バケット名とCloudFrontのURLが表示されます。

これで、Next.jsのSSGでCloudFrontとS3にデプロイすることができました。

今回はこのあたりで。