CDK Toolkit メッセージとインタラクションの設定 - AWS クラウド開発キット (AWS CDK) v2

これは AWS CDK v2 デベロッパーガイドです。旧版の CDK v1 は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

CDK Toolkit メッセージとインタラクションの設定

AWS CDK Toolkit Library は、CDK オペレーション中のメッセージとインタラクションの処理方法をカスタマイズする IIoHost インターフェイスを提供します。これにより、デプロイの進行状況、エラーメッセージ、ユーザープロンプトの表示を制御して、アプリケーションのユーザーエクスペリエンスと統合しやすくなります。

デプロイや合成などのオペレーションを実行する前に、CDK Toolkit がユーザーと通信する方法を理解しておく必要があります。IIoHost インターフェイスは、CDK Toolkit とアプリケーション間の通信チャネルとして機能し、送信メッセージと受信ユーザーレスポンスの両方を処理します。

CDK Toolkit がオペレーションを実行すると、2 つの主要なメカニズムを介して通信します。

  • メッセージ: オペレーションの進行状況 (「デプロイの開始」や「リソースの作成」など) を通知する情報出力。

  • リクエスト: 入力または確認が必要な決定ポイント (「これらの変更をデプロイしますか?」など)。事前に必要であることがわからなかった情報を提供する機会を提供します。

IIoHost インターフェイスの使用

IIoHost インターフェイスは 2 つの主要な方法で構成されます。

  1. notify: 一方向の情報メッセージを処理します。

  2. requestResponse: レスポンスを必要とするインタラクティブなリクエストを処理します。

import { IoMessage, IoRequest } from '@aws-cdk/toolkit-lib'; interface IIoHost { // Handle informational messages notify(message: IoMessage): Promise<void>; // Handle requests that need responses requestResponse(request: IoRequest): Promise<any>; }

メッセージレベルとリクエストタイプ

CDK Toolkit は、いくつかのタイプのメッセージとリクエストを生成します。

メッセージレベル

  • デバッグ: トラブルシューティングの詳細メッセージ。

  • エラー: オペレーションに影響する可能性のあるエラーメッセージ。

  • 情報: 一般的な情報メッセージ。

  • 結果 - オペレーションのプライマリメッセージ。

  • トレース: 非常に詳細な実行フロー情報。

  • 警告: オペレーションを妨げない警告メッセージ。

詳細なリストについては、 AWS CDK Toolkit Library API リファレンスIoMessages Registry」を参照してください。

リクエストタイプ

CDK Toolkit は、ユーザーからの入力または確認が必要な場合にリクエストを送信します。これらは、レスポンスを許可する特別なメッセージです。レスポンスが指定されていない場合、Toolkit は利用可能な場合はデフォルトのレスポンスを使用します。

基本的な IIoHost の実装

カスタム io ホストを実装する簡単な例を次に示します。

import { Toolkit } from '@aws-cdk/toolkit-lib'; // Create a toolkit with custom message handling const toolkit = new Toolkit({ ioHost: { // Implementing the IIoHost interface // Handle informational messages notify: async function (msg) { // Example: Handle different message levels appropriately 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}`); } }, // Handle requests that need responses requestResponse: async function (msg) { // Example: Log the request and use default response console.log(`Request: ${msg.message}, using default: ${msg.defaultResponse}`); return msg.defaultResponse; // Or implement custom logic to provide responses // if (msg.type === 'deploy') { // return promptUserForDeployment(msg); // } } } as IIoHost // Explicitly cast to IIoHost interface });

CDK Toolkit は各呼び出しの完了を待機するため、メッセージを処理する際に HTTP リクエストやユーザープロンプトなどの非同期オペレーションを実行できます。

デフォルトのIIoHost動作

カスタム io ホストを指定しない場合、CDK Toolkit Library はデフォルトの非インタラクティブ実装を使用します。

  • メッセージのコンソール出力 (さまざまなメッセージタイプに適切な色を使用)。

  • ユーザー入力のプロンプトなしで、完全に非インタラクティブ。

  • 可能な場合は、デフォルトのレスポンスを自動的に使用します (プロンプトへの「はい」の回答に相当)。

  • 入力が必要なが、デフォルトのレスポンスが利用できない場合、失敗します。

このデフォルトの動作は、無人操作に適していますが、インタラクティブなコマンドラインアプリケーションには適していません。ユーザー操作を必要とするコマンドラインアプリケーションの場合は、カスタム io ホストを実装する必要があります。カスタム実装は、ロギングシステム、UIs、またはその他の特殊な環境との統合にも役立ちます。

高度な io ホスト実装

より複雑なシナリオでは、開始点として NonInteractiveIoHost クラスを拡張することをお勧めします。このアプローチにより、変更する必要がある特定の動作のみをカスタマイズしながら、既存の非インタラクティブ実装を活用できます。

基本実装を拡張するカスタム io ホストの例を次に示します。

import { NonInteractiveIoHost } from '@aws-cdk/toolkit-lib'; class MyCustomIoHost extends NonInteractiveIoHost { // Override only the methods you need to customize // Example: Custom implementation for notify public async notify(msg: IoMessage<unknown>): Promise<void> { // Add custom notification handling logic if (msg.level === 'error') { console.error(`ERROR: ${msg.message}`); // Optionally log to a service or notify a monitoring system await this.logToMonitoringService(msg); } else { await super.notify(msg); } } // Example: Custom implementation for requestResponse public async requestResponse<T, U>(request: IoRequest<T, U>): Promise<U> { // Implement custom request handling console.log(`Received request: ${request.message}`); return request.defaultResponse; } private async logToMonitoringService(msg: IoMessage<unknown>): Promise<void> { // Implementation for monitoring service integration console.log(`Logging to monitoring service: ${msg.level} - ${msg.message}`); } }

このアプローチは、カスタム動作を必要とする特定のメソッドを上書きするだけで済むため、IIoHostインターフェイス全体を最初から実装するよりも保守的です。

さまざまな環境との統合

ウェブアプリケーション統合

import { Toolkit } from '@aws-cdk/toolkit-lib'; // Example for integrating with a web application const toolkit = new Toolkit({ ioHost: { notify: async function (msg) { // Send message to frontend via WebSocket webSocketServer.send(JSON.stringify({ type: 'cdk-notification', messageLevel: msg.level, message: msg.message, time: msg.time })); }, requestResponse: async function (msg) { // Create a promise that will be resolved when the user responds return new Promise((resolve) => { const requestId = generateUniqueId(); // Store the resolver function pendingRequests[requestId] = resolve; // Send request to frontend webSocketServer.send(JSON.stringify({ type: 'cdk-request', requestId: requestId, requestType: msg.type, message: msg.message, defaultResponse: msg.defaultResponse })); // Frontend would call an API endpoint with the response, // which would then call pendingRequests[requestId](response) }); } } as IIoHost // Explicitly cast to IIoHost interface });

CI/CD 環境の統合

import { Toolkit } from '@aws-cdk/toolkit-lib'; // Example for CI/CD environments (non-interactive) const toolkit = new Toolkit({ ioHost: { notify: async function (msg) { // Log all messages with appropriate level switch (msg.level) { case 'error': console.error(msg.message); break; case 'warning': console.warn(msg.message); break; default: console.log(msg.message); } }, requestResponse: async function (msg) { // In CI/CD, always use default responses or predefined answers console.log(`Auto-responding to request: ${msg.message} with ${msg.defaultResponse}`); return msg.defaultResponse; } } as IIoHost // Explicitly cast to IIoHost interface });

io ホスト実装のベストプラクティス

カスタム io ホストを実装するときは、次のベストプラクティスを考慮してください。

  • エラー処理: io ホストメソッドに堅牢なエラー処理を実装して、障害が CDK オペレーションに影響を与えないようにします。

  • タイムアウト: 無期限の待機を防ぐために、ユーザーインタラクションのタイムアウトを実装することを検討してください。

  • ログ記録: 特に非インタラクティブ環境では、トラブルシューティングのために重要なメッセージをログに保存します。

  • デフォルトレスポンス: ユーザーとのやり取りが不可能な自動環境には、適切なデフォルトレスポンスを提供します。

  • 進行状況の表示: 長時間実行されるオペレーションの場合は、明確な進行状況インジケータを提供してユーザーエクスペリエンスを向上させます。

次の例は、エラー処理、ユーザーインタラクションのタイムアウト、適切なログ記録を備えたカスタム io ホストを実装することで、これらのベストプラクティスを示しています。この実装は、ユーザーの応答性と信頼性の高いオペレーションのバランスを取る必要があるインタラクティブなアプリケーションに適しています。

import { Toolkit } from '@aws-cdk/toolkit-lib'; // Example with error handling and timeouts const toolkit = new Toolkit({ ioHost: { notify: async function (msg) { try { console.log(`[${msg.time}] ${msg.level}: ${msg.message}`); // Additional logging or UI updates } catch (error) { // Ensure errors in notification handling don't break the CDK operation console.error("Error handling notification:", error); } }, requestResponse: async function (msg) { try { // Implement timeout for user response const response = await Promise.race([ getUserResponse(msg), new Promise(resolve => setTimeout(() => resolve(msg.defaultResponse), 60000)) ]); return response; } catch (error) { console.error("Error handling request:", error); return msg.defaultResponse; } } } as IIoHost // Explicitly cast to IIoHost interface });

トラブルシューティング

カスタム io ホストを実装する際の考慮事項:

  • 未処理の promise 拒否: すべての非同期オペレーションが try/catch ブロックで適切に処理されていることを確認します。

  • 無限待機: アプリケーションがハングしないように、すべてのユーザーインタラクションのタイムアウトを実装します。

  • メッセージレベルの欠落: 将来の CDK バージョンで追加される可能性のある新しいメッセージレベルを処理する準備をします。

  • 一貫性のないレスポンス: requestResponse 実装が想定された形式で値を返すことを確認します。

次の例は、今後の CDK バージョンで導入される可能性のある不明なメッセージタイプの適切な処理など、メッセージレベルを処理するための堅牢なアプローチを示しています。この実装により、io ホストは適切なログ記録を維持しながら CDK 更新との互換性を維持できます。

import { Toolkit } from '@aws-cdk/toolkit-lib'; // Example of handling unknown message levels const toolkit = new Toolkit({ ioHost: { notify: async function (msg) { // Handle known levels const knownLevels = ['info', 'warning', 'error', 'debug', 'trace', 'status']; if (knownLevels.includes(msg.level)) { // Handle known level handleKnownMessageLevel(msg); } else { // Handle unknown level as info console.log(`Unknown message level "${msg.level}": ${msg.message}`); } }, requestResponse: async function (msg) { // Default implementation return msg.defaultResponse; } } as IIoHost // Explicitly cast to IIoHost interface });