這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
設定 CDK Toolkit 訊息和互動
AWS CDK Toolkit Library 提供 IIoHost
界面,可自訂在 CDK 操作期間如何處理訊息和互動,讓您控制部署進度、錯誤訊息和使用者提示的顯示,以更好地整合應用程式的使用者體驗。
在執行部署或合成等操作之前,您需要了解 CDK Toolkit 如何與使用者通訊。IIoHost
界面可做為 CDK Toolkit 與應用程式之間的通訊管道,同時處理傳出訊息和傳入使用者回應。
當 CDK Toolkit 執行操作時,它會透過兩個主要機制進行通訊:
-
訊息:通知您操作進度的資訊輸出 (例如「開始部署」或「已建立資源」)。
-
請求:需要輸入或確認的決策點 (例如「您要部署這些變更嗎?」),讓您有機會提供事先不需要的資訊。
使用 IIoHost
界面
IIoHost
介面包含兩種主要方法:
-
notify
:處理單向資訊性訊息。 -
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 登錄檔。
請求類型
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
界面更可維護,因為您只需要覆寫需要自訂行為的特定方法。
與不同環境整合
Web 應用程式整合
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 });