這是 AWS CDK v2 開發人員指南。較舊的 CDK v1 已於 2022 年 6 月 1 日進入維護,並於 2023 年 6 月 1 日結束支援。
本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用 開發和部署雲端基礎設施的最佳實務 AWS CDK
透過 AWS CDK,開發人員或管理員可以使用支援的程式設計語言來定義其雲端基礎設施。CDK 應用程式應組織成邏輯單位,例如 API、資料庫和監控資源,並選擇性地擁有自動化部署的管道。邏輯單位應實作為包含下列項目的建構:
-
基礎設施 (例如 Amazon S3 儲存貯體、Amazon RDS 資料庫或 Amazon VPC 網路)
-
執行期程式碼 (例如 AWS Lambda 函數)
-
組態程式碼
Stacks 定義這些邏輯單位的部署模型。如需 CDK 背後概念的更詳細介紹,請參閱 入門 AWS CDK。
AWS CDK 會仔細考量客戶和內部團隊的需求,以及部署和持續維護複雜雲端應用程式時經常出現的故障模式。我們發現故障通常與未完整測試的應用程式的「out-of-band」變更有關,例如組態變更。因此,我們開發 AWS CDK 了圍繞模型的 ,其中您的整個應用程式在程式碼中定義,不僅商業邏輯,還有基礎設施和組態。如此一來,即可仔細檢閱提議的變更,在類似生產環境進行全方位測試,以變化程度進行,並在發生問題時完全復原。

在部署時間, AWS CDK 會合成包含下列項目的雲端組件:
-
AWS CloudFormation 在所有目標環境中描述基礎設施的範本
-
包含執行期程式碼及其支援檔案的檔案資產
使用 CDK,應用程式主要版本控制分支中的每個遞交都可以代表應用程式的完整、一致、可部署版本。然後,只要進行變更,您的應用程式就可以自動部署。
背後的理念 AWS CDK 帶來了我們建議的最佳實務,我們已經分為四個廣泛的類別。
提示
同時考慮適用於 CDK 定義基礎設施的最佳實務 AWS CloudFormation和您使用的個別 AWS 服務。
組織最佳實務
在 AWS CDK 採用的開始階段,請務必考慮如何設定您的組織以取得成功。最佳實務是讓一個專家團隊負責訓練和指導公司其他人員採用 CDK。此團隊的大小可能有所不同,從小型公司的一到兩個人員,到大型公司的完整品質卓越雲端中心 (CCoE)。此團隊負責為貴公司的雲端基礎設施設定標準和政策,以及訓練和指導開發人員。
CCoE 可能會提供雲端基礎設施應使用哪些程式設計語言的指導。每個組織的詳細資訊各不相同,但良好的政策有助於確保開發人員可以了解和維護公司的雲端基礎設施。
CCoE 也會建立「登陸區域」,以定義您在其中的組織單位 AWS。登陸區域是根據最佳實務藍圖預先設定、安全、可擴展的多帳戶 AWS 環境。若要將組成登陸區域的服務綁定在一起,您可以使用 AWS Control Tower
開發團隊應該能夠使用自己的帳戶,視需要在這些帳戶中測試和部署新資源。個別開發人員可以將這些資源視為其開發工作站的延伸。使用 CDK Pipelines, AWS CDK 應用程式即可透過 CI/CD 帳戶部署,以測試、整合和生產環境 (各自隔離在自己的 AWS 區域或帳戶中)。這可透過將開發人員的程式碼合併到組織的正式儲存庫來完成。

編碼最佳實務
本節介紹組織 AWS CDK 程式碼的最佳實務。下圖顯示團隊與團隊程式碼儲存庫、套件、應用程式和建構程式庫之間的關係。

啟動簡單,並僅在您需要時才新增複雜性
大多數最佳實務的指導原則是盡可能讓事情簡單,但沒有更簡單。只有在您的需求指定更複雜的解決方案時,才新增複雜性。使用 AWS CDK,您可以視需要重構程式碼,以支援新的需求。您不需要預先建構所有可能案例。
與 AWS Well-Architected Framework 保持一致
AWS Well-Architected
AWS CDK 應用程式會映射到 AWS Well-Architected Framework. AWS CDK apps 定義的元件,是一種機制,可編寫和交付 Well-Architected 雲端應用程式最佳實務。您也可以透過成品儲存庫,建立和共用元件做為可重複使用的程式碼庫,例如 AWS CodeArtifact。
每個應用程式都從單一儲存庫中的單一套件開始
單一套件是您 AWS CDK 應用程式的進入點。在這裡,您可以定義部署應用程式不同邏輯單位的方式和位置。您也可以定義 CI/CD 管道來部署應用程式。應用程式建構會定義解決方案的邏輯單位。
針對您在多個應用程式中使用的建構使用其他套件。(共享建構也應有自己的生命週期和測試策略。) 相同儲存庫中套件之間的相依性是由您儲存庫的建置工具管理。
雖然可以,但不建議將多個應用程式放在同一個儲存庫中,尤其是在使用自動化部署管道時。這樣做會增加部署期間變更的「爆量半徑」。當儲存庫中有多個應用程式時,變更一個應用程式會觸發其他應用程式部署 (即使其他應用程式尚未變更)。此外,一個應用程式中的休息時間可防止其他應用程式部署。
根據程式碼生命週期或團隊擁有權將程式碼移至儲存庫
當套件開始用於多個應用程式時,請將它們移至自己的儲存庫。如此一來,應用程式建置系統就可以參考這些套件,也可以在與應用程式生命週期無關的節奏上進行更新。不過,一開始將所有共用的建構放在一個儲存庫中可能很合理。
此外,當不同的團隊正在處理它們時,將套件移至自己的儲存庫。這有助於強制執行存取控制。
若要跨儲存庫界限使用套件,您需要一個私有套件儲存庫,類似於 NPM、PyPi 或 Maven Central,但在您的組織內部。您還需要一個發行程序,以建置、測試和發佈套件到私有套件儲存庫。CodeArtifact 可以託管最熱門的程式設計語言套件。
套件儲存庫中套件的相依性是由語言的套件管理員管理,例如適用於 TypeScript 或 JavaScript 應用程式的 NPM。您的套件管理員有助於確保建置是可重複的。它透過記錄應用程式依賴的每個套件的特定版本來執行此操作。它也可讓您以受控制的方式升級這些相依性。
共用套件需要不同的測試策略。對於單一應用程式,將應用程式部署到測試環境並確認它仍然有效,可能就足夠了。但共用套件必須獨立於耗用應用程式進行測試,就像是公開發行一樣。(您的組織可能會選擇實際將一些共用套件發佈給大眾。)
請記住,建構可以是任意簡單或複雜的。Bucket
是建構,但也可以CameraShopWebsite
是建構。
基礎設施和執行期程式碼在相同的套件中運作
除了產生用於部署基礎設施的 AWS CloudFormation 範本之外, AWS CDK 還綁定執行期資產,例如 Lambda 函數和 Docker 映像,並將其與您的基礎設施一起部署。這可讓您將定義基礎設施的程式碼,以及實作執行期邏輯的程式碼,結合到單一建構中。這是最佳實務。這兩種程式碼不需要位於單獨的儲存庫中,甚至不需要位於單獨的套件中。
若要一起發展這兩種類型的程式碼,您可以使用獨立式建構來完整描述功能,包括其基礎設施和邏輯。使用獨立建構,您可以單獨測試兩種類型的程式碼、跨專案共用和重複使用程式碼,以及同步版本所有程式碼。
建構最佳實務
本節包含開發建構的最佳實務。建構是可重複使用、可組合的模組,可封裝資源。它們是 AWS CDK 應用程式的建置區塊。
使用建構的模型,使用堆疊部署
堆疊是部署單位:堆疊中的所有項目都會一起部署。因此,從多個 AWS 資源建置應用程式的更高層級邏輯單位時, 會將每個邏輯單位表示為 Construct
,而不是 Stack
。僅使用堆疊來描述應如何針對各種部署案例撰寫和連線您的建構。
例如,如果您的其中一個邏輯單位是網站,則構成它的建構 (例如 Amazon S3 儲存貯體、API Gateway、Lambda 函數或 Amazon RDS 資料表) 應組成單一高階建構。然後,該建構應該在一或多個堆疊中執行個體化以進行部署。
透過使用建構結構來建置和堆疊進行部署,您可以提高基礎設施的重複使用潛力,並提高部署方式的靈活性。
使用屬性和方法設定 ,而非環境變數
建構和堆疊內的環境變數查詢是常見的反模式。建構和堆疊都應該接受屬性物件,以允許完全在程式碼中設定。否則, 會對程式碼將在其中執行的機器引入相依性,這會建立更多您必須追蹤和管理的組態資訊。
一般而言,環境變數查詢應限於 AWS CDK 應用程式的頂層。它們也應該用來傳入在開發環境中執行所需的資訊。如需詳細資訊,請參閱的環境 AWS CDK。
裝置測試您的基礎設施
若要在所有環境中的建置時間持續執行完整的單元測試套件,請避免在合成期間進行網路查詢,並在程式碼中建立所有生產階段的模型。(這些最佳實務稍後會介紹。) 如果任何單一遞交一律產生相同的產生範本,您可以信任您寫入的單位測試,以確認產生的範本看起來像您預期的方式。如需詳細資訊,請參閱測試 AWS CDK 應用程式。
請勿變更具狀態資源的邏輯 ID
變更資源的邏輯 ID 會導致在下次部署時將資源取代為新的資源。對於資料庫和 S3 儲存貯體等具狀態資源,或 Amazon VPC 等持久性基礎設施,這很少是您想要的。請注意可能導致 ID 變更的任何 AWS CDK 程式碼重構。撰寫單位測試,宣告具狀態資源的邏輯 IDs 保持靜態。邏輯 ID 衍生自id
您在執行個體化建構時指定的 ,以及建構樹中建構的位置。如需詳細資訊,請參閱邏輯 IDs。
建構不足以合規
許多企業客戶為 L2 建構體 (代表具有內建 Sane 預設值和最佳實務的個別 AWS 資源的「策畫」建構體) 編寫自己的包裝函式。這些包裝函式會強制執行安全最佳實務,例如靜態加密和特定 IAM 政策。例如,您可以建立 MyCompanyBucket
,然後在應用程式中使用 來取代一般的 Amazon S3 Bucket
建構。此模式對於軟體開發生命週期早期出現的安全指導很有用,但不要依賴它作為唯一的強制執行方式。
反之,請使用服務控制政策和許可界限等 AWS 功能,在組織層級強制執行您的安全護欄。使用 CloudFormation Guard
最後,請記住,撰寫您自己的 "L2+" 建構可能會讓您的開發人員無法利用AWS 解決方案建構或第三方建構, AWS CDK 例如 Construct Hub。這些套件通常以標準 AWS CDK 建構結構為基礎,且無法使用您的包裝函式建構。
應用程式最佳實務
在本節中,我們將討論如何撰寫您的 AWS CDK 應用程式,結合建構來定義資源 AWS 的連線方式。
在合成時間做出決策
雖然 AWS CloudFormation 可讓您在部署時間 (使用 Conditions
、 和 Parameters
) 做出決策{ Fn::If }
,而且 AWS CDK 可讓您存取這些機制,但我們建議您不要使用這些機制。與一般用途程式設計語言中可用的值類型相比,您可以使用的值類型和可以對其執行的操作類型會受到限制。
反之,請嘗試使用程式設計語言的if
陳述式和其他功能,在 AWS CDK 應用程式中做出所有決策,例如要執行個體化的建構。例如,常見的 CDK 慣用語,在清單上反覆運算,並使用清單中每個項目的值來執行個體化建構,但使用 AWS CloudFormation 表達式是不可能的。
將 AWS CloudFormation 視為 AWS CDK 用於強大雲端部署的實作詳細資訊,而非語言目標。您不是在 TypeScript 或 Python 中撰寫 AWS CloudFormation 範本,而是撰寫使用 CloudFormation 進行部署的 CDK 程式碼。
使用產生的資源名稱,而非實體名稱
名稱是寶貴的資源。每個名稱只能使用一次。因此,如果您將資料表名稱或儲存貯體名稱硬式編碼到您的基礎設施和應用程式中,則無法在同一個帳戶中部署該基礎設施的該部分兩次。(我們在此討論的名稱是 Amazon S3 儲存貯體建構上的 bucketName
屬性所指定的名稱。)
更糟的是,您無法變更需要取代的資源。如果屬性只能在資源建立時設定,例如 Amazon DynamoDB 資料表KeySchema
的 ,則該屬性是不可變的。變更此屬性需要新的資源。不過,新資源必須具有相同的名稱,才能成為真正的取代項目。但當現有資源仍在使用該名稱時,它不能具有相同的名稱。
更好的方法是盡可能少地指定名稱。如果您省略資源名稱, AWS CDK 將以不會造成問題的方式為您產生它們。假設您有一個資料表做為資源。然後,您可以將產生的資料表名稱做為環境變數傳遞至 AWS Lambda 函數。在您的 AWS CDK 應用程式中,您可以將資料表名稱參考為 table.tableName
。或者,您可以在啟動時在 Amazon EC2 執行個體上產生組態檔案,或將實際資料表名稱寫入 AWS Systems Manager 參數存放區,讓您的應用程式可以從那裡讀取。
如果您需要的位置是另一個 AWS CDK 堆疊,這更直接。假設一個堆疊定義資源,而另一個堆疊需要使用它,則適用以下條件:
-
如果兩個堆疊位於相同的 AWS CDK 應用程式中,請在兩個堆疊之間傳遞參考。例如,將資源建構的參考儲存為定義堆疊的屬性 (
this.stack.uploadBucket = amzn-s3-demo-bucket
)。然後,將該屬性傳遞給需要 資源的堆疊建構器。 -
當兩個堆疊位於不同的 AWS CDK 應用程式中時,請使用靜態
from
方法,根據其 ARN、名稱或其他屬性來使用外部定義的資源。(例如,Table.fromArn()
針對 DynamoDB 資料表使用 )。使用CfnOutput
建構在 的輸出中列印 ARN 或其他必要值cdk deploy
,或查看 AWS Management Console。或者,第二個應用程式可以讀取第一個應用程式產生的 CloudFormation 範本,並從Outputs
區段擷取該值。
定義移除政策和日誌保留
AWS CDK 嘗試透過預設保留您建立的所有項目的政策,防止您遺失資料。例如,包含資料之資源 (例如 Amazon S3 儲存貯體和資料庫資料表) 的預設移除政策是在從堆疊移除資源時,不會將其刪除。反之,資源會從堆疊中孤立。同樣地,CDK 的預設值是永久保留所有日誌。在生產環境中,這些預設值可能會快速導致儲存您實際不需要的大量資料,以及對應的 AWS 帳單。
仔細考慮您希望這些政策對每個生產資源而言是什麼,並相應地指定它們。使用 Aspects 和 AWS CDK 驗證堆疊中的移除和記錄政策。
依部署需求將應用程式分成多個堆疊
對於您的應用程式需要多少堆疊,沒有困難且快速的規則。您通常會根據部署模式做出決定。請記住下列準則:
-
將資源盡可能保持在相同的堆疊中通常更簡單,因此除非您知道要將資源分開,否則請將其放在一起。
-
考慮將具狀態資源 (例如資料庫) 與無狀態資源分開存放。然後,您可以在具狀態堆疊上開啟終止保護。如此一來,您可以自由銷毀或建立無狀態堆疊的多個複本,而不會有資料遺失的風險。
-
具狀態資源對於建構重新命名更為敏感,重新命名會導致資源取代。因此,請勿在可能移動或重新命名的建構中巢狀具狀態的資源 (除非遺失時可以重建狀態,例如快取)。這是另一個將具狀態資源放入其堆疊的好理由。
承諾cdk.context.json
避免非確定性的行為
確定性是成功 AWS CDK 部署的關鍵。每當 AWS CDK 應用程式部署到指定環境時,其結果基本上應該相同。
由於您的 AWS CDK 應用程式是以一般用途程式設計語言撰寫,因此可以執行任意程式碼、使用任意程式庫,以及進行任意網路呼叫。例如,您可以使用 AWS SDK 從 AWS 您的帳戶擷取一些資訊,同時合成您的應用程式。認識到這樣做會導致額外的登入資料設定要求、增加的延遲,以及每次執行 時發生失敗的機率,無論如何都很小cdk synth
。
在合成期間,切勿修改 AWS 您的帳戶或資源。合成應用程式不應有副作用。您的基礎設施變更應該只會在範本 AWS CloudFormation 產生後,於部署階段進行。如此一來,如果發生問題, AWS CloudFormation 可以自動復原變更。若要進行無法在 AWS CDK 架構內輕鬆進行的變更,請使用自訂資源在部署時間執行任意程式碼。
即使是嚴格唯讀呼叫也不一定要安全。考慮網路呼叫傳回的值變更時會發生什麼情況。您的基礎設施中哪些部分會受到影響? 已部署的資源會發生什麼情況? 以下是兩個範例,其中值突然變更可能會導致問題。
-
如果您將 Amazon VPC 佈建至指定區域中所有可用的可用區域,且 AZs 數量在部署日為兩個,則您的 IP 空間會分割成一半。如果 第二天 AWS 啟動新的可用區域,則 之後的下一個部署會嘗試將您的 IP 空間分割為第三個,要求重新建立所有子網路。這可能是不可能的,因為您的 Amazon EC2 執行個體仍在執行中,而且您必須手動清除。
-
如果您查詢最新的 Amazon Linux 機器映像並部署 Amazon EC2 執行個體,且第二天新映像發行,則後續部署會挑選新的 AMI 並取代您的所有執行個體。這可能不是您預期會發生的情況。
這些情況可能很危險,因為 AWS端變更可能會在成功部署數月或數年後發生。突然,您的部署「無緣無故」失敗,而且您很久之前忘記了您的行為和原因。
所幸, AWS CDK 包含稱為內容提供者的機制,用於記錄非確定性值的快照。這可讓未來的合成操作產生與第一次部署時完全相同的範本。新範本中唯一的變更是您在程式碼中所做的變更。當您使用建構的 .fromLookup()
方法時,呼叫的結果會快取在 中cdk.context.json
。您應該將此與其餘程式碼一起遞交至版本控制,以確保 CDK 應用程式的未來執行使用相同的值。CDK Toolkit 包含管理內容快取的命令,因此您可以在需要時重新整理特定項目。如需詳細資訊,請參閱內容值和 AWS CDK。
如果您需要一些沒有原生 CDK 內容提供者的值 (來自 AWS 或其他地方),建議您撰寫單獨的指令碼。指令碼應擷取值並寫入檔案,然後在 CDK 應用程式中讀取該檔案。只有在您想要重新整理預存值時,才執行指令碼,而不是作為一般建置程序的一部分。
讓 AWS CDK 管理角色和安全群組
使用 AWS CDK 建構程式庫的grant()
便利方法,您可以建立 AWS Identity and Access Management 角色,使用最小範圍的許可,將存取授予另一個資源。例如,請考慮如下的行:
amzn-s3-demo-bucket.grantRead(myLambda)
此單行會將政策新增至 Lambda 函數的角色 (也會為您建立)。該角色及其政策是十幾行的 CloudFormation,您不需要撰寫。僅 AWS CDK 授予函數從儲存貯體讀取所需的最低許可。
如果您需要開發人員一律使用由安全團隊建立的預先定義角色, AWS CDK 編碼會變得更加複雜。您的團隊在設計應用程式的方式上可能會失去許多彈性。更好的替代方案是使用服務控制政策和許可界限,以確保開發人員保持在護欄內。
建立程式碼中所有生產階段的模型
在傳統 AWS CloudFormation 案例中,您的目標是產生參數化的單一成品,以便在套用這些環境特有的組態值之後,將其部署到各種目標環境。在 CDK 中,您可以且應該將該組態建置到原始程式碼中。為您的生產環境建立堆疊,並為每個其他階段建立個別堆疊。然後,將每個堆疊的組態值放入程式碼中。使用 Secrets Manager
當您合成應用程式時,在cdk.out
資料夾中建立的雲端組件包含每個環境的個別範本。您的整個建置是確定性的。您的應用程式沒有out-of-band變更,任何指定的遞交一律會產生完全相同的 AWS CloudFormation 範本和隨附的資產。這使得單元測試更加可靠。
測量所有項目
達成完全持續部署的目標,無需人工介入,需要高度的自動化。只有大量監控才能實現該自動化。若要測量部署資源的所有層面,請建立指標、警示和儀表板。請勿停止測量 CPU 用量和磁碟空間等項目。同時記錄您的業務指標,並使用這些測量來自動化部署決策,例如復原。中的大多數 L2 建構 AWS CDK 都有方便的方法,可協助您建立指標,例如 dynamodb.Table 類別上的 metricUserErrors()
方法。