這是 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();
現在,假設您想要將此程式碼重構為:
-
將儲存貯體從 重新命名
Bucket為更具描述性的WebsiteOrigin。 -
將儲存貯體和分佈移至新的
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 可能會偵測並保留這些資源。這表示設計要取代的資源必須與重構操作分開處理。
若要正確管理設計為要取代的資源:
-
首先,部署您的應用程式以視需要取代這些資源。
-
然後,分別執行重構操作,以重組您的程式碼。
這種兩步驟方法可確保正確處理設計來取代的資源,同時仍可讓您受益於其他資源的 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 執行程式設計動作。