yasutomogのブログ

Software Engineerの雑記

Amplify + Next.js + microCMSのプレビュー環境について

概要

株式会社トライビート| TRIBEAT CO., LTD. では、数年前からJamstackなWebサイトやECサイトの構築を推進(提案)しており、年々こういったご相談を受けることが増えています。 選定技術はそのときの顧客要件によって変わりますが、Amplify、Next.js、microCMSを使うことが多いです。Jamstackな構成を検討していると、SSGしてファイル生成する都合上、プレビュー機能をどうする?って課題に当たります。Headless CMSで下書きしたとき(公開前)に、Webページとしてどう見えるかを確認するユースケースですね。

アーキテクチャ的にSSGしたものをCDNホスティングすることで、「高速化、スケーラビリティ、セキュア」を担保する一方で、リアルタイムな表示は工夫が必要になります。プレビュー用のページもSSGすれば確認可能ではありますが、ビルドには大抵数分掛かるため、UXが悪くなり実用的ではないと考えています。

Next.jsでは標準的にPreview Modeが用意されていますが、昨年の調査時はAmplify上で正しく動作しませんでした。最近、Amplify hostingのGitHub issueを確認したところ、解決されていそうだったため、改めて検証してみました。

Next.js のPreview Modeとは

nextjs.org

上記の公式ドキュメントに実装方法が手順付きで記載されているので、詳細はこちらを確認するのが良いですが。色々端折って要約すると、Next.js には元々、APIを追加する機能が備わっており、 そのAPIの中で、 setPreviewData 関数を利用することで、プレビュー機能に必要なCookieが発行されます。 このCookieを保持しているブラウザーからアクセスされた場合、SSGで生成済みのページを返すのではなく、 getStaticProps というビルド時に実行されるページ生成用の関数が呼び出されます。

上記機能を利用することで、以下のようなフローが実現可能となります。Headless CMSからプレビュー用URLがリクエストされたときに、Cookieを発行して、対象のページにリダイレクトすると、新たにページ生成した内容で確認が可能となります。

Cookieを保持しているかどうかは、 getStaticProps のパラメーターにある context.preview のbool値で判断可能となります。Cookieを発行する手前の処理で、認証処理を実装することで、Headless CMSからアクセスされたときのみ、機能が有効になるように制御します。

Amplifyでは何が課題だったのか

github.com

github.com

1つ目のissueに関連付けられている、2つ目のissueで解決したようです。Next.jsのPreview Modeは、HTTP Response Header で Cookieを発行していますが、Amplify上にデプロイすると、これがうまく動作していなかったようです。解決されたのが、2022年の12月ということです。

実運用での課題

Amplify上でNext.jsのPreview Modeが動作するということで、課題はなくなったように思えますが、ページ更新のユースケースを想定すると、若干の工夫や考慮が必要になります。当初、本番(hosting)用のAmplify環境(env)上でプレビュー機能も動作させれば、環境構成もシンプルになり最適と考えてましたが、以下のようなケースで使いにくくなると想像しています。

前提

ニュースやブログなどを扱うWebサイトを(Cookieとかはよくわからない)非エンジニアの方がコンテンツ管理している場合

ケース1

  1. ニュースの下書きデータを Headless CMS からプレビュー機能で確認(このときにPreview Mode の Cookie が発行)。
  2. その後、別な作業をしている時に、Webサイトから現在のブログ内容を確認。
  3. 担当者は、公開中のブログページ内容を確認するつもりだが、意図せず下書きデータが保存されていると、下書き内容でページが表示される。

ケース2

  1. 既に公開済みの記事に不備があり、Headless CMSからデータ編集し、プレビュー機能で確認(このときにPreview Mode の Cookie が発行)。
  2. 現在公開中のページと更新後のページを目視で差分チェックしようとしたところ、下書き内容のページでしか確認ができない

上記のようなケースは、Cookieを保持しているブラウザーはSSGされたものではなく、常に新しくページ生成した結果が表示されるため発生します。以下の図のAとBは、同じサイトページをリクエストしていますが、Cookieの保持により表示されるコンテンツ内容は異なる可能性があります。 CMSの操作や現状サイトの確認などを繰り返し作業しているときに、Cookieの保持について意識するのは厳しいと想像しています。

Preview ModeのCookieを発行する setPreviewData 関数は、引数なしで使用するとSession Cookieとなります(ブラウザが閉じられると、Cookieが削除されます)。引数を指定することで、Cookieの有効期間(Expired)を設定することも可能ですが、最近のPCやMacの使われ方だと、ブラウザーを閉じないでアクセス作業することも多いと想像しています。 また、Next.jsでは、Preview ModeのCookieを削除する関数も用意されていますが、何をトリガーに呼び出すべきかは悩ましいです。

上記から、Amplifyプロジェクト内で、本番用とプレビュー用に環境(env)を分けて構築しようと思いましたが、同じGitブランチを別の環境(env)に分けることは想定されていないようで、Amplify Console上で環境(env)を追加するときに、既に接続済みのGitブランチは表示されないように制御されていました。

どうすべきか悩みましたが、本番用とプレビュー用でAmplifyプロジェクトを分けてしまい、同じGitブランチを接続させるのが、いまのところ良さそうです。microCMSなどのHeadless CMSからリクエストする先を、プレビュー用のAmplifyプロジェクトへ向けることで、本番環境の表示とプレビュー環境の表示を切り分けれます。

プレビュー用のAPIについて

blog.microcms.io

Next.jsの公式ドキュメントもわかりやすかったですが、microCMSのブログも丁寧な内容で助かりました。特に、 getStaticPathsfallback の設定変更については、公式ドキュメントに記載がないので参考になりました。 あまり大きな問題ではないですが、以下は今後検討して作り込む予定です。

  • microCMSのdraftKeyについては、Webhookのクエリストリングで渡すべきか、Amplify環境変数で設定すべきか?
  • プレビュー用のAPIについては、各ページごとに作るべきか、まとめるべきか?

AmplifyのSSR対応時のビルドについて

Amplifyは内部で、Next.jsのアプリケーションがSSGまたはSSRを判断して環境構築を変えているようです。Amplify + Next.jsの構成を最初に試したときは、2〜3年前でした。その当時、SSGモードではビルドが数分で終わるものが、SSRモードに変わることで、20〜30分掛かる事象にあたりました。今回のプレビューAPIは、SSRモードでなければ動作しないこともあり、ビルド時間に懸念がありましたが、AmplifyもNext.jsに合わせて進化しており、いまのところ、SSGとSSRでビルド時間はほぼ変わらないことを確認済みです。

Flutterで環境別のGoogleMap API Keyを設定する方法(dart-define-from-file)

概要

FlutterでGoogleMapを利用するとき、API KeyはOS毎に以下のファイルで設定する必要があります。

テスト環境と本番環境にそれぞれ発行したGoogleMap API Keyを、 ビルド(ipaまたはaabファイルの生成)時に、 dart-define-from-file オプションから設定する方法を記載します。

前提

Flutterで環境ごと設定値を分けるには、元々、Flutterビルドコマンドオプションの dart-define を使ってましたが、 dart-define-from-file オプションによって設定値をファイルにまとめることができるようになりました。
その方法については、以下の記事が大変参考になるので、こちらでは割愛した内容を記載します。

zenn.dev

dart-define-from-fileからの設定

dart_defines/dev.jsondart_defines/prod.json は既に用意している前提で、GoogleMap API Keyをそれぞれのjsonに追加します。

"iOSGoogleMapApiKey": "hoge"
"androidGoogleMapApiKey": "fuga"

iOS

  • ios/Runner/Info.plist に以下を追加し、swiftからdart-defineのjsonにアクセスできるように設定。
  <key>DART_DEFINES</key>
  <string>$(DART_DEFINES)</string>
  • ios/Runner/AppDelegate.swift を以下のように編集して、jsonファイルの内容を取得して使用することが可能。
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // - Setup dart-define(dart-defineの値) 
    let dartDefinesString = Bundle.main.infoDictionary!["DART_DEFINES"] as! String
    var dartDefinesDictionary = [String:String]()
    for definedValue in dartDefinesString.components(separatedBy: ",") {
        let decoded = String(data: Data(base64Encoded: definedValue)!, encoding: .utf8)!
        let values = decoded.components(separatedBy: "=")
        dartDefinesDictionary[values[0]] = values[1]
    }

    GMSServices.provideAPIKey(dartDefinesDictionary["iOSGoogleMapApiKey"]!)
    // self.window.makeSecure()
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

extension UIWindow {
  func makeSecure() {
    let field = UITextField()
    field.isSecureTextEntry = true
    self.addSubview(field)
    field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
    field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
    self.layer.superlayer?.addSublayer(field.layer)
    field.layer.sublayers?.first?.addSublayer(self.layer)
  }
}

参考URL medium.com

Android

  • android/app/build.gradle の defaultConfig に以下を追加し、dart-defineの値をAndroidManifest.xmlで利用できるように設定
    defaultConfig {
         manifestPlaceholders["googleApiKey"] = androidGoogleMapApiKey
     }
  • android/app/src/main/AndroidManifest.xml で上記の manifestPlaceholders に指定したKEYを使い設定
         <meta-data android:name="com.google.android.geo.API_KEY" android:value="${googleApiKey}"/>

参考URL

developer.android.com

Androidで正しく設定できているかどうかを確認する方法(値が正しく渡せているかを確認する)

apkファイルの拡張子をzipに変更して解凍することで、AndroidManifest.xml を見つけることはできるが、そのまま開いてもバイナリ形式にエンコードされているため確認することができない。

code.google.com

上記から AXMLPrinter2.jar をダウンロードし、以下のようなコマンドで確認用のAndroidManifest.xmlを生成することが可能。

 java -jar AXMLPrinter2.jarのPath AndroidManifest.xmlのPath > check_AndroidManifest.xml

PHP(ZTS)のxdebugインストール

概要

  • 同じチームのエンジニアが新しいプロジェクトに参画し、既に作成済みのDocker環境にxdebugを入れようとしたところ、うまく動かないという相談を受けて調査開始
  • peclコマンドでxdebugをインストールして設定しているが、確かに動かない、、、

結論

  • Docker環境のPHPは、ZTSで動いていたため、peclコマンドいれたxdebugは動作しない
  • ZTS用のxdebug.soを、自分で作ってあげる必要がある

ハマリポイント

  • peclコマンドでインストール後、以下のコマンドで確認をしていた。

      php -r "phpinfo();" | grep xdebug  
      php -v 
    
  • 上記コマンドだと、xdebugがちゃんと入っているように見えるため、最初はリモートデバッグ接続しようとしているVSCode側の設定とかを疑って時間がかかった。

  • Webブラウザから、phpinfo();出力したページを表示して、xdebugの設定が反映されていないことを確認できたので、ここからPHP側を疑って調査した。

解決方法

wget http://www.xdebug.org/files/xdebug-3.1.5.tgz
tar xzvf xdebug-3.1.5.tgz
cd xdebug-3.1.5/
zts-phpize
./configure --with-php-config=/usr/bin/zts-php-config
make
make install
  • 上記コマンドを実行すると、xdebug.soファイルが作成される
  • あとは、xdebug用のiniファイルを配置してあげる
zend_extension = "make installの出力先/xdebug.so"
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log
xdebug.log_level=0

AmplifyプロジェクトでCognito送信者のLambdaトリガーを設定してみた

概要

  • Amplifyプロジェクトで普通にAuthを追加してMFA対応していた
  • SMS認証コードとEMail認証コードはそれぞれCognito標準機能を使っていたが、TwilioやSendGridなどの別サービスで送るための対応が必要になった
  • Cognitoから認証コードを送るときに、カスタム送信できるような機構が用意されているので、それを利用

ドキュメントや参考になるブログ

docs.aws.amazon.com

docs.aws.amazon.com

docs.aws.amazon.com

qiita.com

対応方法

  • AmplifyのCloud Formationに組み込みたかったが、現状、この機能はCloud Formationに対応されていないらしく、別途設定が必要になる
  • KMS(AWSコンソール)から、「カスタマー管理型のキー」を作成する
    • 特に考えずそのまま作成する
  • Lambda Layerを作っておく
    • package.jsonに以下を追加しておく。実際の認証コード送信に必要であれば、「@sendgrid/mail」や「twilio」も追加しておく
  • Lambdaを用意する
    • 公式ドキュメントにあるものを流用すれば良い
    • handler関数では、Cognitoから発火されたイベント名をみて、処理をハンドリングしてあげる(TwilioやSendGridを使って認証コード送信を書く)
  • LambdaにKMSの権限をアタッチしてあげる
    • Lambdaの[設定]→[アクセス権限]→[実行ロール]からKMSの権限をアタッチする
  • Amazon Cognitoサービスプリンシパルに、Lambda関数を呼び出すための、cognito idp.amazonaws.com へのアクセス権を付与

    aws lambda add-permission \
    --function-name <作成したLambdaのARN> \
    --statement-id "CognitoLambdaInvokeAccess" \
    --action lambda:InvokeFunction \
    --principal cognito-idp.amazonaws.com
    
  • Cognitoユーザープールを更新して、Lambdaトリガーを追加する

    aws cognito-idp update-user-pool \
    --user-pool-id <CognitoユーザープールID>  \
    --lambda-config "CustomSMSSender={LambdaVersion=V1_0,LambdaArn=<作成したLambdaのARN>},CustomEmailSender={LambdaVersion=V1_0,LambdaArn=<作成したLambdaのARN>},KMSKeyID=<作成したKMSのARN>" \
    --profile <AWSのプロファイル>
    
  • 間違ってLambdaトリガーを追加したときに解除するコマンド

    aws cognito-idp update-user-pool \
    --userpool-id <userpool_id> \
    --lambda-config "{}"
    

ハマったところ

たまに認証コードが同じユーザーに2度送られる事象が発生

  • SMS認証コードをTwilioのVerify APIを使って送信していたが、時たま、2度送られていた
  • 設定したLambdaトリガーのログを見ていると、以下が出力されており、失敗したLambdaの約1分後に同じイベントが発火されていた。
  • Verify API処理が3秒超える場合がたまにあり、そのときに再度Lambdaが実行され2度送信されていることを確認

    Task timed out after 3.00 seconds
    

対応方法

  • Lambdaのタイムアウトをデフォルトの3秒から10秒に変更し、メモリも256mbに変更
  • 設定値は、利用するサービス仕様に合わせる

www.twilio.com

カスタムLambdaトリガーが実行されない事象発生

  • aws cognito-idp update-user-pool コマンドでLambdaカスタムトリガーを紐付けても、Lambdaが呼ばれない
  • AmplifyでAuth追加した時点では、Cognitoの「どの属性を確認しますか?」の項目では、「Eメールまたは電話番号」を選択していたが、コマンド実行すると、「検証なし」に変更されていた。

対応方法

  • aws cognito-idp update-user-pool コマンドのオプションに auto-verified-attributes を追加
  • 上記オプションには、 sms-configuration が必要になる
    • sms-configuration に指定には、「SMS 送信に使用する IAM ロールの ARN」と「SMS 送信に使用する IAM ロールの、信頼ポリシーに設定されている sts:ExternalId の値」が必要になる。
    • このIAMロールは、Amplifyで適切にAuth追加していると既に作成されているので、それを使う。
    • Cognito(AWSコンソール)の「MFAそして確認」メニューの一番下に「新規ロール名」があるので、IAM(AWSコンソール)から検索して、信頼関係のタブを開くと「sts:ExternalId」の値が確認可能
    aws cognito-idp update-user-pool \
    --user-pool-id <CognitoユーザープールID> \
    --lambda-config "CustomSMSSender={LambdaVersion=V1_0,LambdaArn=<作成したLambdaのARN>},CustomEmailSender={LambdaVersion=V1_0,LambdaArn=<作成したLambdaのARN>},KMSKeyID=<作成したKMSのARN>" \
    --profile <AWSのプロファイル> \
    --auto-verified-attributes {email,phone_number} \
    --sms-configuration SnsCallerArn=<SMS 送信に使用する IAM ロールの ARN>,ExternalId=<SMS 送信に使用する IAM ロールの、信頼ポリシーに設定されている sts:ExternalId の値>
    

Next.js on Amplifyの503エラーの続き

概要

yasutomo.hatenablog.com

  • 上記ブログの続き
  • AmplifyでNext.jsをデプロイしたタイミングだと問題なく動くが、あるタイミングからCloud Frontの503エラーになっていた
  • 上記事象が発生するのは、同じAmplifyプロジェクト上で同じソースコードで構築したhostingでも再現するものとしないものがあった

原因

  • Next.js on Amplifyで構築される、Lambda@Edge に SQS の権限がアタッチされないことがある
  • SQS の権限がアタッチ「されるとき」と「されないとき」の2パターンあるのがポイントで、ケースは以下
    • Amplify hosting作成時、はじめてデプロイするタイミングのソースコードがISR対応している:SQSの権限がアタッチされる
    • Amplify hosting作成時、はじめてデプロイするタイミングのソースコードがISR対応していない:SQSの権限がアタッチされない
  • ISRのキャッシュが切れて裏でページ生成されるタイミングで、Lambda@edge から SQS に SendMessage しようとしたときに権限がないと503エラーとなる

対処方法

  • 解決するには、以下2つがある。(現状はどちらも試していて、どちらのケースでもうまく動いている)
    • Amplify hostingを作り直す
      • 事象が発生しているhostingを一度削除し、改めて作り直す
      • まだサイト公開前とかであれば、こちらの方法がシンプルで良さそう
    • 事象が発生している Lambda@edge にSQSの権限をアタッチする
      • 雑にやるなら、AmazonSQSFullAccess ポリシーを付ける。正しくやるなら、"Resource": "arn:aws:sqs:us-east-1:<アカウント ID >:", の Actionに "sqs:SendMessage" を指定する。
    • Lambda@edge や SQS のIDについては、Amplifyコンソールのデプロイ部分のログに出力されている
    • Lambda@edge に権限アタッチ後、改めてデプロイしても自分で割り当てた権限はついたままとなっている(Amplify側の挙動の保証はない?)

所感

  • プロジェクト構築時は、シンプルな状態から始めることが多いので、途中からISR対応ページなど追加したときに気をつける
  • Amplifyコンソールのデプロイフェーズのログが重要
    • ここに出力されている、CloudFront や Lambda@edge のIDから詳細ログを追う力が必要

調査のときに見ていたGitHubとドキュメント

github.com

github.com

Next.js on Amplifyの503エラー

yasutomo.hatenablog.com

yasutomo.hatenablog.com

また雑多なメモを残しておきます。

概要

  • Amplify上でNext.jsを動かすときに503エラーが発生
  • ネットで調べていると色々と情報はでてくるが、自分がハマったケースは大きく2つ
    • Next.jsでISRをしているときに発生
    • Amplifyのアクセスコントロールを適用しようとして発生

Next.jsでISRをしているときに発生

  • 調べ始めたとき、以下2つの日本語記事が参考になりました。

zenn.dev

dev.classmethod.jp

  • はじめてAmplify hosting するときに、Amplify CLI と Next.js verisonのバージョンをどちらも latest にするのがポイント

f:id:yasug:20211203001942p:plain

  • 上記対応はプロジェクト構築時にも見て知っていたので正しく設定していましたが、それでも503エラーが発生するケースがありました。
  • ちょっとたちが悪いのが、ページ表示したタイミングで常に発生するわけではなく、何かしらの契機で発生していて、調査が難かしかったです。
  • それから調査を続けてて、参考になったissueが以下です。

github.com

github.com

  • 1つ目はwebpackのバージョンで、5をfalseにして4で動かすというものです。自分の場合これでは解決に至らず、結局は5に戻しています。また、このオプションは近い将来に無効になるので、可能であれば使わずに解決したいところでした。
  • 2つ目は、Amplifyの環境変数にある、_LIVE_UPDATES の値でした。このissueにもある通り、verisonに10 と指定されていました。ビルド設定のバージョンはlatestになっているのを確認していたので、こちらはissueを見るまで気づきませんでした。
  • 10になっている部分をlatestに変更し、改めてビルドし直してみましたが解決はしなかったです。ダメ元で、一度hostingを削除して改めて作り直したところ、_LIVE_UPDATES のNext.jsのバージョンも以下のようにすべてlatestになっており、その後は503エラーは発生していないです。

f:id:yasug:20211203003030p:plain

Amplifyのアクセスコントロールを適用しようとして発生

  • Amplifyにはアクセスコントロールのメニューから簡単にBasic認証かけれる便利機能がありますが、Next.jsでSSR対応している場合には正しく動きませんでした。
  • 以下の公式ドキュメントにも、その旨が掲載されていて読んだ記憶があるのですが、いま改めて見ると載ってません。

docs.aws.amazon.com

  • このブログを書く前に試してみたところ、普通に動いているように見えます。その当時は、アクセスコントロールの設定自体は有効になり、画面を開くとID/PASSの入力を求められるのですが、正しい値を入れても認証が通らないという事象でした。
  • そこからAmplifyの機能に頼らず、自分でアクセス制御しようと思い、Amplifyのデプロイ先のCloudFrontに関数を作成しました。Basic認証ではなく、以下のような、IP制限するようなプログラムを設定していました。(CloudFrontの関数ではconstが使えなくて地味にハマりました。)
  function handler(event) {
    var request = event.request;
    var headers = event.request.headers;
    var clientIP = headers['x-forwarded-for']['value']

    var IP_WHITE_LIST = [];
    var isPermittedIp = IP_WHITE_LIST.includes(clientIP);

    if (isPermittedIp) {
        return request;
    } else {
        var response = {
            statusCode: 403,
            statusDescription: 'Forbidden',
        }
        return response;
    }
}
  • これも最初うまく動いていたのですが、何かを契機に503が多発するようになることがあったのと。Amplifyでビルドすると、関数が外れてしまう問題を確認しているところでした。
  • いまはアクセスコントロールがうまく動いていそうなので、一旦このまま経過観察していきたいと思います。

感想

  • 何か困ったら大抵はGitHubでやり取りされているので、そこで解決案やアプローチ方法が見つかることが多い
  • Amplifyのupdateが早いので、その時点では難しくても、最悪の逃げ道だけ用意しておけば、それを使わずとも環境側の変更で解決することが多い

その後

  • この対応後、同様の事象が発生し、更に詳細を追った話

yasutomo.hatenablog.com

AmplifyでNext.jsをSSRしたときのビルドログ出力先

yasutomo.hatenablog.com

昨日、上の記事を書きましたが、Advent Calendarにまだ空きがあるので、雑多なメモを残しておきます。

概要

  • Amplify環境でNext.jsのアプリケーションを構築
  • Next.jsでは、ページによってSSG、ISR、SSRを使い分けている

課題

  • SSRしているページの描画が遅いことが発覚しログ確認しようと思った
  • SSRやISRしているときに、getStaticPropsgetServerSideProps 関数でconsole.log出力していたが、どこで確認できるか分からなかった

解決方法

f:id:yasug:20211202001705p:plain

  • Amplify Console のFrontend environments から デプロイをクリック
  • 以下のようにCloudFrontやLambda@Edgeの識別子を確認することができる
2021-12-01T07:37:02 [INFO]: Beginning deployment for application aaaaaaa, branch:dev, buildId aaaaaa
2021-12-01T07:37:05 [INFO]: Deploying SSR Resources. Distribution ID: bbbbbbb. This may take a few minutes...
2021-12-01T07:37:05 [INFO]: Deployed the following resources to your account:
2021-12-01T07:37:05 [INFO]: - CloudFront Domain ID: ccccccc
2021-12-01T07:37:05 [INFO]: - SSR Lambda@Edge: dddddd-dddddd
2021-12-01T07:37:05 [INFO]: - Image Optimization Lambda@Edge: eeeeee-eeeeee
2021-12-01T07:37:05 [INFO]: - ISR Lambda: ffffff
2021-12-01T07:37:05 [INFO]: - ISR SQS Queue: gggggg
2021-12-01T07:37:05 [INFO]: - S3 Bucket: hhhhhh
2021-12-01T07:37:05 [INFO]: Deployment complete
  • AWSコンソールで、バージニア北部(us-east-1)リージョン からLambdaの識別子でフィルタし、そこからCloudWatchをたどることで、Next.jsのビルド時のログを確認することが可能

気になった点

  • SSRのログを確認しようとしたときに、「 SSR Lambda@Edge」の値からたどっても見つからなく、ISR Lambda の方を確認すると、SSRページのログも出力されていた。