[Amazon CloudWatch Synthetics] Canaryのランタイム更新時の注意点とエラー発生時の対処(AWS CDK)

2021.09.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

Amazon CloudWatch Syntheticsを使用すると、WebサイトやAPIのURLの監視(外形監視)を行うことができます。

今回は、Amazon CloudWatch SyntheticsのCanaryのランタイムをAWS CDKで更新する際の注意点とエラー発生時の対処についてです。

先にまとめ

CanaryのランタイムをAWS CDKで更新する場合、下記の手順で行う。

エラーを回避する方法

  1. Canaryを停止する
  2. CDKデプロイする

Canary実行中にデプロイしてしまいエラーとなった場合

  1. Canaryを停止する
  2. CloudFormationスタックのロールバックが失敗していれば、Canaryリソースをスキップしてロールバックを継続し、ロールバックを完了させる。
  3. CDKでCanaryリソースを再作成する。

Canaryのランタイムを更新しようとしたらエラーが発生した

前回の下記エントリでAWS CDKで作成したCanaryがエラーとなり、ランタイムをsyn-nodejs-puppeteer-3.2にアップグレードすることにより回避しました。

しかしこのアップグレードを行う際に少しハマりました。

ランタイムのアップグレードをしようと編集したスタックをCDKデプロイした際に、Canaryのステータスは実行中(定期実行が有効)でした。

その状態でCDKデプロイしたところ、下記の通りThe operation cannot be performed at this time. An update is in progress for resource〜というメッセージが出てResourceConflictExceptionとなりスタックのデプロイがFAILしました。スタックはUPDATE_ROLLBACK_COMPLETEステータスで終了しています。

$ cdk deploy
AwsCdkAppStack: deploying...
[0%] start: Publishing 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
[100%] success: Published 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
AwsCdkAppStack: creating CloudFormation changeset...
10:37:04 PM | UPDATE_FAILED        | AWS::Synthetics::Canary | WebsiteCanary0039E740
Resource handler returned message: "The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:cwsyn-website-canary-a0e45618-ed6f-46f6-9a2a-68dbdf2401b2 (Service: AWSLambda; Status Code:
409; Error Code: ResourceConflictException; Request ID: 2ee2e87a-a97f-4b69-a578-52d1a5c25f72; Proxy: null)" (RequestToken: 007a7599-7239-d7d3-745b-54ded30529cd, HandlerErrorCode: GeneralServiceException)

(中略)
The stack named AwsCdkAppStack failed to deploy: UPDATE_ROLLBACK_COMPLETE

コンソールからCanaryを停止します。

ステータスが停止となりました。

再度CDKデプロイを試みると、次はCanaryのリソース更新が先程と同じResourceConflictExceptionエラーとなり、更にスタックがUPDATE_ROLLBACK_FAILEDステータスで終了しました。状況が悪化しましたね…。

$ cdk deploy
AwsCdkAppStack: deploying...
[0%] start: Publishing 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
[100%] success: Published 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
AwsCdkAppStack: creating CloudFormation changeset...
10:45:45 PM | UPDATE_FAILED        | AWS::Synthetics::Canary | WebsiteCanary0039E740
Resource handler returned message: "The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:cwsyn-website-canary-a0e45618-ed6f-46f6-9a2a-68dbdf2401b2 (Service: AWSLambda; Status Code:
409; Error Code: ResourceConflictException; Request ID: e2c247d3-40f3-4c4f-b53a-4022a32a276f; Proxy: null)" (RequestToken: 5e44ee73-7a28-018d-305b-74fd810971f1, HandlerErrorCode: GeneralServiceException)

(中略)

10:46:00 PM | UPDATE_FAILED        | AWS::Synthetics::Canary | WebsiteCanary0039E740
Resource handler returned message: "Canary in a state that can't be modified: ERROR (Service: Synthetics, Status Code: 409, Request ID: 36854cfb-573c-49e5-b18c-04a9952caa01, Extended Request ID: null)" (RequestToken: 694543e9-1be7-3d08-bea6-41d417bd8511, HandlerErro
rCode: GeneralServiceException)

(中略)
The stack named AwsCdkAppStack failed to deploy: UPDATE_ROLLBACK_FAILED (The following resource(s) failed to update: [WebsiteCanary0039E740]. )

コンソールからCanaryを確認すると、ステータスがエラーとなり、同じエラーメッセージが出ています。

スタックがUPDATE_ROLLBACK_FAILEDとなっている場合は、ロールバックが失敗しているためスタックの更新ができません。手動でロールバックを完了させてあげる必要があります。

コンソールで該当のスタックを開いたら[スタックアクション]で[更新ロールバックを続ける]を選択します。

ダイアログが開くので、[高度なトラブルシューティング]を開いてCanaryのリソースにチェックを入れ、[更新ロールバックを続ける]をクリックします。

スタックがUPDATE_ROLLBACK_COMPLETEとなりました。

この状態で再々度CDKデプロイを試みると、次はCanary in a state that can't be modifiedというメッセージとともにエラーとなりました。スタックの状態はUPDATE_ROLLBACK_COMPLETEです。

$ cdk deploy
AwsCdkAppStack: deploying...
[0%] start: Publishing 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
[100%] success: Published 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
AwsCdkAppStack: creating CloudFormation changeset...
11:10:41 PM | UPDATE_FAILED        | AWS::Synthetics::Canary | WebsiteCanary0039E740
Resource handler returned message: "Canary in a state that can't be modified: ERROR (Service: Synthetics, Status Code: 409, Request ID: 25166926-6ef8-4de8-8f5c-095308d97690, Extended Request ID: null)" (RequestToken: 49351968-759c-30f9-e19d-55b6d6838e83, HandlerErro
rCode: GeneralServiceException)

(中略)
The stack named AwsCdkAppStack failed to deploy: UPDATE_ROLLBACK_COMPLETE

Canaryのステータスは引き続きエラーとなっています。

コンソールからCanaryを変更して保存しようとしたら、この場合もエラーとなります。

このCanaryのエラー状態をまずは解消する必要があるみたいです。しかし解消方法を調べてみましたが、有用な方法が見つかりませんでした。そこで最終手段としてCanaryリソースの再作成を行います。

Canaryリソースを一度削除してCDKデプロイします。

lib/aws-cdk-app-stack.ts

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_2,
      test: synthetics.Test.custom({
        code: synthetics.Code.fromAsset(
          path.join(__dirname, `../src/lambda/website-canary-handler`)
        ),
        handler: 'index.handler',
      }),
    });
    */
  }
}

削除が完了したら、上記のコメントアウトを外してCanaryリソースの作成をデプロイします。

$ cdk deploy
This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

(中略)
 ✅  AwsCdkAppStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/AwsCdkAppStack/7b38bc00-fdd1-11eb-a215-064c2582fb33

デプロイ成功しました。

コンソールからCanaryを確認すると、作成直後のCanary実行は成功しています。また過去24時間の実行ポイントも参照できるようになっています。

ログデータ保管先のS3バケットは、初回作成時のものとは別に再作成時に新しいものが作成されていました。

これでCanaryのランタイムを更新することができました。

ランタイムの他の変更パターンの場合

ここまで紹介した事象では、ランタイムを3.1から3.2にアップグレードしようとした際にエラーが発生しました。では逆に3.2から3.1にダウングレードするパターンの場合はどうなるでしょう。

試してみると、CDKデプロイが同じメッセージThe operation cannot be performed at this time. An update is in progress for resourceでエラーとなりました。

$ cdk deploy
AwsCdkAppStack: deploying...
[0%] start: Publishing 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
[100%] success: Published 1212de2fc0b8cad9b83366b8bad2d3697c61b249e887d1282be8b9e9a1a9f1fa:current
AwsCdkAppStack: creating CloudFormation changeset...
12:29:40 AM | UPDATE_FAILED        | AWS::Synthetics::Canary | WebsiteCanary0039E740
Resource handler returned message: "The operation cannot be performed at this time. An update is in progress for resource: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:cwsyn-website-canary-23cf705d-70e8-4465-b2ad-dc7a4971e5c4 (Service: AWSLambda; Status Code:
409; Error Code: ResourceConflictException; Request ID: e5c033b3-0caf-455b-bfed-485c2099846f; Proxy: null)" (RequestToken: a184de57-b1d2-6c60-3a06-ab24e6294e65, HandlerErrorCode: GeneralServiceException)

(省略)
The stack named AwsCdkAppStack failed to deploy: UPDATE_ROLLBACK_FAILED (The following resource(s) failed to update: [WebsiteCanary0039E740]. )

コンソールでCanaryのステータスを見ると、実行中だったものが自動で停止となりました。

少し放置するとエラーとなりました。

前述の事象と同じですね。また復旧も同じ手順でできました。

他の設定を変更する場合

AWS CDKによる下記の変更の場合は、Canaryが実行中ステータスであっても、エラーなく更新ができました。

  • スクリプトの記述の更新
  • スケジュールの変更(定期実行から手動実行に変更など)

コンソールでランタイムを変更する場合

コンソールでCanaryの編集画面を開くと、スケジュールが必ず1回実行が選択された状態となります。

このスケジュールを継続的に実行を選択し、かつランタイムを変更します。

すると変更の保存時にエラーとなりました。

同じエラーが発生しています。今回の事象はAWS CDKに限らないものであることが分かりました。

おわりに

Amazon CloudWatch SyntheticsのCanaryのランタイムをAWS CDKで更新する際の注意点とエラー発生時の対処について紹介しました。

バグっぽい動作なのでそのうち解消されるかも知れません。そもそも作成済みのCanaryのランタイムを変更する機会というのがそんなに無いかもしれないですが。

以上