這是 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 執行程式設計動作。