重構 CDK 程式碼時保留已部署的資源 - AWS 雲端開發套件 (AWS CDK) v2

這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

重構 CDK 程式碼時保留已部署的資源

重要

CDK 重構處於預覽版本中,可能會有所變更。

透過 AWS 雲端開發套件 (AWS CDK) 重構,您可以重構 CDK 程式碼,例如重新命名建構模組、在堆疊之間移動資源,以及重組應用程式,同時保留部署的資源,而不是取代它們。此功能可協助您維持良好的軟體工程最佳實務,而不會導致意外的資源替換。

什麼是資源保留的 CDK 重構?

當您部署 CDK 應用程式時, AWS CloudFormation 會依資源IDs 來識別資源。 AWS CDK 會根據建構IDs狀結構中的建構 ID 及其路徑產生這些邏輯 ID。如果您變更建構的 ID 或將其移至程式碼中的不同位置, AWS CloudFormation 通常會將此解譯為建立新資源並刪除舊資源的請求。對於資料庫、儲存貯體或佇列等具狀態的資源,此取代可能會導致服務中斷或資料遺失。

CDK 重構透過以下方式解決此挑戰:

  • 偵測在程式碼中移動或重新命名資源的時間。

  • 使用 AWS CloudFormation 的重構功能來保留基礎實體資源。

  • 在不取代實際資源的情況下更新邏輯 IDs。

  • 在堆疊的資源之間維護參考。

您可以使用 CDK CLI cdk refactor命令或 CDK Toolkit Library refactor的動作來執行 CDK 重構。本指南主要討論 CLI 方法,但基礎原則適用於這兩種方法。如需使用 Toolkit Library 的資訊,請參閱使用 CDK Toolkit Library 執行程式設計動作

重要

重構操作必須單獨執行,與其他動作分開,例如新增資源、刪除資源或修改資源屬性。

如果您需要新增、刪除或修改資源以及重構,您應該先分別部署這些變更,然後使用重構來重組您的資源。

CDK 重構的優點

CDK 重構為 AWS CDK 開發人員提供下列優點:

  • 改善程式碼組織 – 重新命名建構和重組 CDK 應用程式的結構,無需資源替換。

  • 建立可重複使用的元件 – 將重複的程式碼解壓縮為可重複使用的 L3 建構,同時保留已部署的資源。

  • 增強架構分離 – 在堆疊之間移動資源,以更好地隔離應用程式的不同部分。

  • 防止意外資源替換 – 重新命名建構時,避免意外資源重新建立。

  • 緩解第三方程式庫變更 – 保護您的應用程式免受您依賴的建構程式庫中的邏輯 ID 變更影響。

  • 套用軟體工程最佳實務 – 重構程式碼,而不會影響部署的基礎設施。

CDK CLI cdk refactor命令的運作方式

重要

您必須向 --unstable=refactor選項提供使用此功能的所有命令。

首先,部署初始 CDK 應用程式,以在 AWS 帳戶中建立基準資源。重構 CDK 程式碼之後,例如重新命名建構模組或在堆疊之間移動資源,請使用 cdk refactor命令開始重構已部署資源的程序。

當您執行 refactor 命令時,CDK CLI 會比較您目前的程式碼與部署狀態,以偵測您的本機變更。它會驗證您的 CDK 應用程式是否包含與部署狀態完全相同的一組資源,僅在其在建構樹狀結構中的位置中有所不同。然後,CDK CLI 會產生重構計畫,將舊資源位置映射至其新位置。CDK CLI 會顯示提議的變更,並在您確認後,使用 AWS CloudFormation 的重構 API 來更新資源IDs,而不替換這些變更。

在幕後,CDK CLI 會透過比較其屬性和相依性來決定哪些資源已移動,並識別在功能上同等但在建構樹狀結構中具有不同路徑的資源。如果偵測到任何資源新增、刪除或修改,重構操作將被拒絕,並顯示錯誤訊息。

重構 CDK 程式碼時保留資源的範例

在此範例中,我們會保留已部署的資源,同時使用 CDK CLI cdk refactor命令重構 CDK 程式碼。

我們的範例 CDK 應用程式包含單一堆疊,其中包含 S3 儲存貯體、CloudFront 分佈和 Lambda 函數。建構樹結構如下:

App └─ MyStack ├─ Bucket ├─ Distribution └─ Function

以下是我們的應用程式程式碼範例:

const app = new cdk.App(); const myStack = new cdk.Stack(app, 'MyStack'); const bucket = new s3.Bucket(myStack, 'Bucket'); const distribution = new cloudfront.Distribution(myStack, 'Distribution', { defaultBehavior: { origin: new origins.S3Origin(bucket) } }); const function = new lambda.Function(myStack, 'Function', { // function properties }); // Synthesize the app app.synth();

現在,假設您想要將此程式碼重構為:

  1. 將儲存貯體從 重新命名Bucket為更具描述性的 WebsiteOrigin

  2. 將儲存貯體和分佈移至新的WebStack堆疊。

重構之後,建構樹看起來會如下所示:

App ├─ WebStack │ ├─ WebsiteOrigin │ └─ Distribution └─ MyStack └─ Function

而重構程式碼為:

// Refactored structure const app = new cdk.App(); // New WebStack with the bucket and distribution const webStack = new cdk.Stack(app, 'WebStack'); const bucket = new s3.Bucket(webStack, 'WebsiteOrigin'); const distribution = new cloudfront.Distribution(webStack, 'Distribution', { defaultBehavior: { origin: new origins.S3Origin(bucket) } }); // Original MyStack with just the function const myStack = new cdk.Stack(app, 'MyStack'); const function = new lambda.Function(myStack, 'Function', { // function properties }); // Synthesize the app app.synth();

如果沒有 CDK 重構,這些變更會導致 AWS CloudFormation 建立新資源並刪除舊資源,因為邏輯 IDs 會變更:

  • MyStack/Bucket/Resource 會變成 WebStack/WebsiteOrigin/Resource

  • MyStack/Distribution/Resource 會變成 WebStack/Distribution/Resource

透過 CDK 重構,CDK CLI 會偵測這些路徑變更,並使用 AWS CloudFormation 的重構功能來保留基礎資源。當您執行 時cdk refactor,CLI 會顯示它將會進行的變更:

$ cdk refactor The following resources were moved or renamed: ┌───────────────────────────────┬───────────────────────────────┬───────────────────────────────────┐ │ Resource Type │ Old Construct Path │ New Construct Path │ ├───────────────────────────────┼───────────────────────────────┼───────────────────────────────────┤ │ AWS::S3::Bucket │ MyStack/Bucket/Resource │ WebStack/WebsiteOrigin/Resource │ ├───────────────────────────────┼───────────────────────────────┼───────────────────────────────────┤ │ AWS::CloudFront::Distribution │ MyStack/Distribution/Resource │ WebStack/Distribution/Resource │ └───────────────────────────────┴───────────────────────────────┴───────────────────────────────────┘ Do you wish refactor these resources (y/n)?

當您輸入 進行確認時y,CDK CLI 會顯示重構操作的進度:

Refactoring... ✅ Stack refactor complete

確認後,CDK CLI 會執行重構操作,同時保留這兩個資源,同時更新其邏輯 IDs 以符合新的程式碼結構。

相同的映射也會顯示在 cdk diff命令的輸出中,依堆疊整理:

Stack MyStack Resources [-] AWS::S3::Bucket Bucket Bucket1234567 destroy (OR move to WebStack.WebsiteOrigin1234567 via refactoring) [-] AWS::CloudFront::Distribution Distribution Distribution1234567 destroy (OR move to WebStack.Distribution1234567) ... Stack WebStack Resources [+] AWS::S3::Bucket WebsiteOrigin WebsiteOrigin1234567 (OR move from MyStack.Bucket1234567) [+] AWS::CloudFront::Distribution Distribution Distribution1234567 (OR move from MyStack.Distribution1234567) ...

開始使用 CDK 重構

若要開始使用重構,請完成下列先決條件:

使用最新的範本引導您的環境

CDK 重構功能需要引導堆疊中的新許可。為了確保您擁有必要的許可,請使用最新的範本來引導您的環境:

cdk bootstrap

如需引導的詳細資訊,請參閱 AWS CDK 的引導環境

安裝最新的 CDK CLI 版本

CDK 重構需要最新版本的 CDK CLI。若要確保您擁有最新版本:

npm install -g aws-cdk

如需詳細安裝說明,請參閱 AWS CDK 入門

使用覆寫檔案來解決重構中的模棱兩可情況

CDK CLI 會根據將您的程式碼與部署的資源進行比較,自動運算所有資源映射。在大多數情況下,此自動偵測運作良好,但在某些情況下,CLI 可能會遇到無法自行解決的模棱兩可情況。若要為 CDK CLI 提供指引,請使用覆寫檔案。

建立覆寫檔案以解決模棱兩可的問題

覆寫檔案是一種 JSON 檔案,可在 CDK CLI 無法判斷資源的重構解析度時提供映射。檔案包含依環境組織的資源映射:

{ "environments": [ { "account": "123456789012", "region": "us-east-2", "resources": { "StackA.OldName": "StackB.NewName", "StackC.Foo": "StackC.Bar" } } ] }

在此檔案中:

  • environments 陣列包含一或多個具有帳戶和區域的環境項目。

  • 在每個環境中, resources 物件包含映射。

  • 金鑰代表格式為 的目前位置<stack name>.<logical ID>

  • 值代表相同格式的新位置。

若要搭配 CDK CLI 使用覆寫檔案:

cdk refactor --override-file=overrides.json

重構跨多個環境的堆疊

CDK 應用程式可以包含部署到不同環境 (AWS 帳戶和區域) 的多個堆疊。在重構這類應用程式中保留資源時,CDK CLI 會以特定方式處理環境:

  • CLI 會依環境分組堆疊,並在每個環境中分別執行重構。

  • 您可以在重構期間在堆疊之間移動資源,但所有涉及移動的堆疊都必須位於相同的環境中。

  • 嘗試跨環境移動資源將導致錯誤。

此行為可確保資源保持在其原始 AWS 帳戶和區域中,這是必要的,因為 CloudFormation 資源無法實際跨帳戶或區域邊界移動。

例如,如果您的 CDK 應用程式同時為開發和生產環境定義堆疊,則重構操作將在每個環境中獨立執行。資源可以在開發環境或生產環境中的堆疊之間移動,但不能從開發到生產,反之亦然。

處理旨在取代的資源

有些 CDK 建構仰賴 CloudFormation 的資源取代行為作為其設計的一部分。例如,API Gateway Deployment和 Lambda Version 的建構旨在在其屬性變更時建立新資源。

重構時,請勿包含任何應該導致資源取代的變更。否則,CDK CLI 可能會偵測並保留這些資源。這表示設計要取代的資源必須與重構操作分開處理。

若要正確管理設計為要取代的資源:

  1. 首先,部署您的應用程式以視需要取代這些資源。

  2. 然後,分別執行重構操作,以重組您的程式碼。

這種兩步驟方法可確保正確處理設計來取代的資源,同時仍可讓您受益於其他資源的 CDK 重構。

一般考量和限制

在 CDK 重構期間保留資源時,請記住下列考量事項:

  • 環境限制:資源只能在相同環境中的堆疊之間移動。不支援跨環境移動。

  • 模棱兩可:如果您有多個相同的資源同時重新命名,CDK CLI 可能無法自動判斷正確的映射。在這些情況下,您將需要使用覆寫檔案提供明確的映射。

  • 引導要求:若要在重構期間保留資源,您需要使用包含必要許可的最新版本來更新引導堆疊。

  • 排除某些建構:某些建構,例如 API Gateway Deployment和 Lambda 的 Version依賴於資源替換,並自動排除在重構之外。

使用 CI/CD 管道重構

若要在 CI/CD 管道中使用重構功能,您需要能夠在管道中執行 CDK CLI。以下是將重構整合至 CI/CD 工作流程的一些重要考量。

在 CI/CD 中使用重構的先決條件

您必須能夠在 CI/CD 環境中使用 CDK CLI,才能受益於此功能。

將重構整合到您的管道工作流程

如果您使用 CLI 在 CI/CD 管道中部署,您的指令碼通常如下所示:

... cdk deploy <stack filter> ...

如果您想要在工作流程中包含重構,以下是基本範例:

... cdk refactor <stack filter> cdk deploy <stack filter> ...

您也可以將重構作為管道中的單獨步驟。

處理重構失敗

請注意,如果您的程式碼包含實際的資源修改以及重構, cdk refactor將會失敗。由於您在管道中自動呼叫重構,因此您需要處理潛在的故障:

# Allow refactoring to fail but continue the pipeline cdk refactor <stack filter> || true cdk deploy <stack filter>

或者,您可能想要確保在您成功執行重構之前不會發生部署:

# Only deploy if refactoring succeeds cdk refactor <stack filter> && cdk deploy <stack filter>
CI/CD 環境的最佳實務

若要在 CI/CD 管道中有效使用重構:

  • 與其他變更分開重構:請記住,重構操作必須與資源新增、刪除或修改分開。在您的管道中,請考慮進行重構的專用遞交和部署。

  • 適當使用覆寫檔案:了解覆寫檔案僅由 CDK CLI 用作解決模棱兩可案例的備用檔案。

  • 管道--force中不需要 :在 CI/CD 管道等非互動式環境中,CDK refactor 命令會自動繼續,而不會提示確認。只有在互動式環境中才需要 --force選項。

相關資源

如需 CDK CLI cdk refactor命令的選項和引數資訊,請參閱 cdk refactor

若要開始使用 CDK Toolkit Library refactor的動作,請參閱使用 CDK Toolkit Library 執行程式設計動作