1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS CDK】AWS CDK Toolkit LibraryがGAされました(その3)

Posted at

※このブログは、2025/09/08にこちらで公開した内容のQiita版になります。

今回のお話

前々回および前回の記事で、AWS CDK Toolkit Libraryの基本、および「CDK CLIで行っていたあの機能、AWS CDK Toolkit Libraryではどうやるの?」という事を書きました。

最終回となる今回は、エラーハンドリング、そしてちょっと高度な「IIoHost」について紹介しようと思います。

※AWS CDK Toolkit LibraryのAWS公式サイトはこちら。

エラーハンドリング

CDK Toolkit Libraryには、ToolkitError クラスにあらかじめエラーハンドリング用のヘルパー関数が用意されており、 容易にエラーハンドリング処理を実装できます。

具体的には以下の通りです。(すべてstatic関数です)1

ヘルパー関数 説明 備考
isToolkitError(error) CDK Toolkitライブラリのエラーかどうかを判定する 以下エラーの親クラス
isAuthenticationError(error) クレデンシャル違いなど、認証に関するエラーかどうかを判定する
isAssemblyError(error) CDKの定義間違いなので発生したエラーかどうかを判定する。
isContextProviderError(error) ContextProvider(≒cintext)に起因するエラーかどうか判定する ContextProviderは、synth時のcdk.context.json出力などに関係するクラス。
withCause(message, error) errorをcause(エラーの根本原因)としてオリジナルエラーをToolkitErrorとして返す これはエラー種類の判定ではない

下記がサンプルコードになります(一部AWS公式サイトより)
下記サンプルコードの通りToolkitErrorは、コンストラクタなどから自分で生成することもできます。

ちなみにCDK Toolkit Libraryのエラーはエラータイプのinstanceofチェックに頼らず、ヘルパー関数を使用する事がAWS公式より案内されています。

import { ToolkitError } from '@aws-cdk/toolkit-lib';
  
try {
  // なんか処理
  await toolkit.deploy(cloudAssemblySource, {
    stacks: { strategy: StackSelectionStrategy.ALL_STACKS }
  });
  
} catch (error) {
  if (ToolkitError.isAuthenticationError(error)) {
    // 認証エラー(クレデンシャル不一致など)
    console.error('Authentication failed. Check your AWS credentials.');
  
  } else if (ToolkitError.isAssemblyError(error)) {
    // CDKの定義が違う
    console.error('CDK app error:', error.message);
  
  } else if (ToolkitError.isToolkitError(error)) {
    // context周りでエラー
    console.error('CDK Toolkit error:', error.message);
  
  } else if (ToolkitError.isToolkitError(error)) {
    // 上記に該当しないToolkitErrorのエラー
    console.error('CDK Toolkit error:', error.message);
    
    // withCauseで、cause付きのToolkitErrorを取得する
    throw ToolkitError.withCause(error.message, error);
    
  } else {
    // ToolkitErrorではない、予期しないエラー
    console.error('Unexpected error:', error);
    
    // こんな感じで、ToolkitErrorエラーの作成もできる
    throw new ToolkitError('予期しないエラー', 'unknown', error)
  }
}

IIoHostによるメッセージとインタラクション

CDK Toolkit Libraryではオペレーションを実行時、下記「メッセージ」および「リクエスト」という2つの主要なメカニズムを介して通信します。

  • メッセージ:オペレーションの実行状況などを通知する。(例:「デプロイの進行中」など)
  • リクエスト:ユーザーからの入力または確認が必要な決定ポイントで、これらを確認する機会を提供する。(例:「このスタックをデプロイしていいですか?」など)

これらを構成するのに必要なのが IIoHost インターフェースです

IIoHostインターフェースについて

IIoHost インターフェースは、以下2つの構成で成り立っています。

  • notify:上記「メッセージ」を処理します。
  • requestResponse:上記「リクエスト」を処理します。

ソースコードでは、下記の内容になっています。

import type { IoMessage, IoRequest } from './io-message';
export interface IIoHost {
    notify(msg: IoMessage<unknown>): Promise<void>;
    requestResponse<T>(msg: IoRequest<unknown, T>): Promise<T>;
}

またCDK Toolkit Libraryのコンストラクタでは、以下のようにIIoHostを定義します。

const toolkit = new Toolkit({
  ioHost: {
    notify: async function (msg) {...(なんか処理)},
    requestResponse: async function (msg) {...(なんか処理)},
  }
});

notifyについて

notify には、IoMessage 型の引数msg の内容に応じたメッセージ処理を記載します。

AWS公式のサンプルでは下記のように msg.level に応じたログを出力する処理が記載されており、アプリのログ出力とも似通った分かりやすい内容となっています。

notify: async function (msg) {
  // notify関数の例
    switch (msg.level) {
      case 'error':
        console.error(`[${msg.time}] ERROR: ${msg.message}`);
        break;
      case 'warning':
        console.warn(`[${msg.time}] WARNING: ${msg.message}`);
        break;
      case 'info':
        console.info(`[${msg.time}] INFO: ${msg.message}`);
        break;
      case 'debug':
        console.debug(`[${msg.time}] DEBUG: ${msg.message}`);
        break;
      case 'trace':
        console.debug(`[${msg.time}] TRACE: ${msg.message}`);
        break;
      default:
        console.log(`[${msg.time}] ${msg.level}: ${msg.message}`);
      }
    },

ちなみにmsgにはlevelの他にも、以下のようなプロパティがあります。

プロパティ 説明 備考
time 日時情報(Date型)
action 実行した処理(deploy, synth, listなど)
code メッセージコード
message メッセージ本文
span メッセージスパン 同じ操作に意味的に関連した複数メッセージのグループ。それ以外では無意味
data メッセージに添付されたデータ

requestResponseについて

requestResponse は、ユーザーからの入力または確認が必要な場合に送信されるリクエストに対する挙動(=レスポンス処理)を記載します。

なおこのrequestResponse は、CDK Toolkit Library において非常に重要です。

なぜならCDK Toolkit Libraryでは、このような処理に対する初期値が「何も確認しない」になっているからです。(CDK CLIで言えば、--require-approval の 初期値が never になっているのと同じ)

そのため、例えば toolkit.destroy(=スタックの削除)のような危険な処理もユーザーに確認することなく、ダイレクトで実行されてしまいます

そこで、これを防ぐために requestResponse でちゃんと確認するように設定する必要があります。

サンプルとしては以下です。(AWS公式より)

requestResponse: async (msg) => {

  // (例)本番だけは何も確認しない場合        
  if (environment === 'production') {
    console.log(`Auto-approving for production: ${msg.message}`);
      // msg.defaultResponseは「デフォルトの挙動を行う(=何も確認しない)」ための専用のプロパティ
      return msg.defaultResponse;
  }
  
  // 何かしら確認のためのプロンプトなどを出す処理を行う
  // ちなみに引数のmsgは、defaultResponseプロパティを持つ事以外notifyのmsgと同じです。 
  return showPromptForApproval(msg.message);
}

なおこのIIoHost ですが、下記のいずれかの方法で定義できます。

  • Toolkit コンストラクタに notifyrequestResponse を直で定義する
  • NonInteractiveIoHost クラスを継承したカスタムクラスを自分で定義し、それをToolkit コンストラクタのIIoHostに設定する

ちなみに後者を使用すると「変更する必要がある動作のみをカスタマイズしながら、既存の実装を活用できる」というメリットがあります。

これはAWS公式にサンプルコードがありますので、そちらを参照ください。

まとめ

以上、AWS CDK Toolkit LibraryのエラーハンドリングとIIoHostについての設定についてでした。

今日の内容、特にIIoHostRequestResponse はちょっと難しい内容かもしれませんが、RequestResponse は非常に重要な設定なので、必ず最初に設定しておいた方が良いと思います。

ちなみに今回RequestResponseの部分について説明が駆け足になってしまいましたが、詳しく知りたい方は、山梨 蓮さん(X:@ren_yamanashi)がブログで非常に詳しく説明してくれていますので、ぜひそちらもご参照ください。

最後に

9/12(金)に大阪で開催された「JAWS-UG CDK支部#22 大阪でもCDKしたいねん」にて、「CDK CLIでできてたあの機能、CDK Toolkit Libraryではどうやるの?」というタイトルで、このブログに記載の内容でLTをさせていただきました。

また今週末の10/11(土)に金沢で開催される「JAWS Festa 2025」において、ありがたいことにCFPが採用され、業務効率化をさらに加速させる、ノーコードツールとStep Functionsのハイブリッド化というタイトルで登壇させていただくことになりましたので、よろしくお願いいたします。(ノーコードツールとの併用やStep Functionsの効果的な使い方についてお話しさせていただきます)

それでは、今回はこの辺で。

  1. 公式ページに記載のToolkitError.isDeploymentErrorは、実際のソースコードでは定義されていませんでした。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?