Amazon CloudWatch SyntheticsのCanary実行が「Cannot find module ‘SyntheticsLogHelper’」となり失敗する場合の対処(AWS CDK)
こんにちは、CX事業本部 IoT事業部の若槻です。
Amazon CloudWatch Syntheticsを使用すると、WebサイトやAPIのURLの監視(外形監視)を行うことができます。
今回は、AWS CDKで実装したCanaryの実行が「Cannot find module 'SyntheticsLogHelper'」というエラーとなり失敗するので対処してみました。
CDKスタック
Canaryリソースを下記のようなCDKスタックで定義しました。
import * as path from 'path'; import * as cdk from '@aws-cdk/core'; import * as synthetics from '@aws-cdk/aws-synthetics'; export class AwsCdkAppStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) { super(scope, id, props); new synthetics.Canary(this, 'WebsiteCanary', { canaryName: `website-canary`, schedule: synthetics.Schedule.rate(cdk.Duration.minutes(10)), runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, test: synthetics.Test.custom({ code: synthetics.Code.fromAsset( path.join(__dirname, `../src/lambda/website-canary-handler`) ), handler: 'index.handler', }), }); } }
Canaryのスクリプトの内容については、今回の事象には関係が無いので割愛します。
cdk deploy
で上記スタックをデプロイし、Canaryリソースを作成しました。
事象
しかし作成したanaryの実行状況をAWSマネジメントコンソールでC確認すると、Cannot find module 'SyntheticsLogHelper'〜
というエラーとなり実行が失敗しています。
Canary実行のログは下記となります。index.handler()
を呼び出した直後にエラーが発生しているようです。
Start Canary INFO: Event: {"canaryName":"website-canary","s3BaseFilePath":"awscdkappstack-websitecanaryartifactsbucketec81f5-XXXXXXXXXXXX","customerCanaryHandlerName":"index.handler","customerCanaryCodeLocation":"arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:layer:cwsyn-website-canary-bc36552f-2aff-4437-934a-d73f856f73cf:1","invocationTime":1631965835442,"runtimeVersion":"syn-nodejs-puppeteer-3.1","visualReference":null,"activeTracing":false,"canaryRunId":"3bda004c-bd49-438c-937a-024086abd9cb"} INFO: Context: {"callbackWaitsForEmptyEventLoop":true,"functionVersion":"1","functionName":"cwsyn-website-canary-bc36552f-2aff-4437-934a-d73f856f73cf","memoryLimitInMB":"1000","logGroupName":"/aws/lambda/cwsyn-website-canary-bc36552f-2aff-4437-934a-d73f856f73cf","logStreamName":"2021/09/18/[1]b56f1fbe8393491b964edf57846b89a6","invokedFunctionArn":"arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:cwsyn-website-canary-bc36552f-2aff-4437-934a-d73f856f73cf:1","awsRequestId":"993e69cf-4187-403a-b1b9-e00be7ca9d3b"} INFO: Configuring tracing: canaryName: website-canary canaryArn: arn:aws:synthetics:ap-northeast-1:XXXXXXXXXXXX:canary:website-canary canaryRunId: 3bda004c-bd49-438c-937a-024086abd9cb INFO: Setting ActiveTracing to: false INFO: Recording configuration: INFO: Canary execution start time: Sat Sep 18 2021 11:50:35 GMT+0000 (Coordinated Universal Time) INFO: canaryName: website-canary INFO: s3BaseFilePath: awscdkappstack-websitecanaryartifactsbucketec81f5-XXXXXXXXXXXX INFO: awsAccountId: XXXXXXXXXXXX INFO: region: ap-northeast-1 INFO: canaryArn: arn:aws:synthetics:ap-northeast-1:XXXXXXXXXXXX:canary:website-canary INFO: memoryLimitInMB: 1000 INFO: awsRequestId: 993e69cf-4187-403a-b1b9-e00be7ca9d3b INFO: timeRemainingInMillis: 599962 INFO: Launching Puppeteer browser with options: {"args":["--autoplay-policy=user-gesture-required","--disable-background-networking","--disable-background-timer-throttling","--disable-backgrounding-occluded-windows","--disable-breakpad","--disable-client-side-phishing-detection","--disable-component-update","--disable-default-apps","--disable-dev-shm-usage","--disable-domain-reliability","--disable-extensions","--disable-features=AudioServiceOutOfProcess","--disable-hang-monitor","--disable-ipc-flooding-protection","--disable-notifications","--disable-offer-store-unmasked-wallet-cards","--disable-popup-blocking","--disable-print-preview","--disable-prompt-on-repost","--disable-renderer-backgrounding","--disable-setuid-sandbox","--disable-speech-api","--disable-sync","--disk-cache-size=33554432","--hide-scrollbars","--ignore-gpu-blacklist","--metrics-recording-only","--mute-audio","--no-default-browser-check","--no-first-run","--no-pings","--no-sandbox","--no-zygote","--password-store=basic","--use-gl=swiftshader","--use-mock-keychain","--single-process"],"defaultViewport":{"deviceScaleFactor":1,"hasTouch":false,"height":1080,"isLandscape":true,"isMobile":false,"width":1920},"headless":true,"executablePath":"/tmp/chromium"} INFO: Creating a new page. INFO: Setting up page events. INFO: Adding CloudWatchSynthetics/arn:aws:synthetics:ap-northeast-1:XXXXXXXXXXXX:canary:website-canary to user agent header sent with each outbound request. INFO: Creating Puppeteer HAR object. INFO: Starting HAR file logging. INFO: Start executing customer steps INFO: Customer canary entry file name: "index" INFO: Customer canary entry function name: "handler" INFO: Calling customer canary: /opt/nodejs/node_modules/index.handler() ERROR: Canary error: Error: Cannot find module 'SyntheticsLogHelper'Require stack:- /opt/nodejs/node_modules/index.js- /var/task/index.js- /var/runtime/UserFunction.js- /var/runtime/index.js INFO: Har generation stopped INFO: Browser closed INFO: Publishing result and duration CloudWatch metrics with timestamp: Sat Sep 18 2021 11:50:35 GMT+0000 (Coordinated Universal Time) for canaryName: website-canary stepName: null result: FAILED startDateTimeInUTC: Sat Sep 18 2021 11:50:40 GMT+0000 (Coordinated Universal Time) endDateTimeInUTC: Sat Sep 18 2021 11:50:40 GMT+0000 (Coordinated Universal Time) INFO: Getting list of files under /tmp to upload to S3. INFO: Checking list of files under /tmp to see if they are actual files. INFO: List of actual files under /tmp ["/tmp/2021-09-18T11-50-36-721Z-log.txt","/tmp/SyntheticsReport-FAILED.json"] INFO: Uploading files to S3 ["/tmp/2021-09-18T11-50-36-721Z-log.txt","/tmp/SyntheticsReport-FAILED.json"] INFO: Getting S3 location for uploading files INFO: S3 destination for uploading artifacts determined: {"s3Bucket":"awscdkappstack-websitecanaryartifactsbucketec81f5-XXXXXXXXXXXX","s3Key":"canary/ap-northeast-1/website-canary/2021/09/18/11/50-35-442"} ERROR: Unable to fetch S3 bucket location: Access Denied. Fallback to S3 client in current region: ap-northeast-1.
調査
エラーにてCannot find moduleとあったSyntheticsLogHelper
について調べると下記の情報がありました。
SyntheticsLogHelper クラスは、ランタイム syn-nodejs-puppeteer-3.2 以降で利用可能です。これは CloudWatch Synthetics ライブラリですでに初期化されており、Synthetics 構成で設定されています。スクリプトに依存関係としてこれを追加できます。このクラスを使用すると、URL、ヘッダー、およびエラーメッセージをサニタイズして、機密情報を編集できます。
現在利用しているランタイムは、下記の通りsyn-nodejs-puppeteer-3.1
です。
new synthetics.Canary(this, 'WebsiteCanary', { canaryName: `website-canary`, schedule: synthetics.Schedule.rate(cdk.Duration.minutes(10)), runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, test: synthetics.Test.custom({ code: synthetics.Code.fromAsset( path.join(__dirname, `../src/lambda/website-canary-handler`) ), handler: 'index.handler', }), });
よってランタイムを3.2に上げれば良さそうです。しかしCDKスタックでのサジェストではsyn-nodejs-puppeteer-3.2
以上のランタイムが提示されません。どうやら現在利用しているのCDKバージョン(1.111.0)には3.1までのランタイムしか含まれていないようです。
対処
そこで、CDKバージョンを最新版(1.123.0)にアップグレードします。
するとCanaryのランタイムでsyn-nodejs-puppeteer-3.2
が選択できるようになりました。
ランタイムを更新したCanaryリソースのコード。
new synthetics.Canary(this, 'WebsiteCanary', { canaryName: `website-canary`, schedule: synthetics.Schedule.rate(cdk.Duration.minutes(10)), runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_2, test: synthetics.Test.custom({ code: synthetics.Code.fromAsset( path.join(__dirname, `../lambda/synthetics-canary`), ), handler: 'index.handler', }), });
再度cdk deploy
してCanaryを更新すると、エラーなく実行ができるようになりました。
おわりに
AWS CDKで実装したCanaryの実行が「Cannot find module 'SyntheticsLogHelper'」というエラーとなり失敗するので対処してみました。
今回CanaryをはじめてAWS CDKで実装しましたが、Canaryリソースを一つ作るだけでRoleやS3バケット、Lambdaなど周辺リソースは裏側でよろしく作ってくれるのは便利だと思いました。
参考
- AWS CDK で CloudWatch Synthetics Canary を設定する方法 | DevelopersIO
- CloudWatch SyntheticsをCDKで管理する - Qiita
以上