運用巢狀堆疊,將範本分割成可重複使用的部分 - AWS CloudFormation

運用巢狀堆疊,將範本分割成可重複使用的部分

隨著基礎設施擴充,您可能會在多個範本中重複建立相同的資源組態。為避免這種重複性,您可以將這些通用組態拆分至專用範本中。然後,在其他範本中使用 AWS::CloudFormation::Stack 資源參考這些專用範本,建立巢狀堆疊。

例如,假設您有一個用於您大多數堆疊的負載平衡器組態。相較於複製相同的組態並在您的範本中貼上,您可以為負載平衡器建立專用的範本。之後,任何需要相同負載平衡器組態的其他範本,都可以參考此範本。

巢狀堆疊本身也能包含其他巢狀堆疊,形成堆疊的階層,如下圖所示。根堆疊為最上層的堆疊,即為所有巢狀堆疊最終所屬的堆疊。每一個巢狀堆疊都有一個立即的「父系堆疊」。針對第一層巢狀堆疊,根堆疊也是其父系堆疊。

  • 堆疊 A 是所有其他、巢狀、階層中堆疊的根堆疊。

  • 針對堆疊 B,堆疊 A 同時是其父系堆疊及根堆疊。

  • 針對堆疊 D,堆疊 C 是父系堆疊;針對堆疊 C,堆疊 B 為其父系堆疊。

巢狀堆疊,即做為另一個堆疊的部分建立的堆疊,具有立即的父系堆疊,以及最上層的根堆疊。

範本拆分的前後範例

本範例展示如何將單一大型 CloudFormation 範本,透過巢狀範本,重組為更具結構化且可重複使用的設計。一開始,「巢狀堆疊前」的範本將所有資源定義在同一個檔案中。隨著資源數量增加,這種方式會變得雜亂且難以管理。「巢狀堆疊後」的範本將資源拆分至多個較小的獨立範本中。每個巢狀堆疊負責處理一組特定的相關資源,使整體結構更具條理且易於維護。

巢狀堆疊前

巢狀堆疊後

AWSTemplateFormatVersion: 2010-09-09 Parameters: InstanceType: Type: String Default: t2.micro Description: The EC2 instance type Environment: Type: String Default: Production Description: The deployment environment Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-1234567890abcdef0 InstanceType: !Ref InstanceType MyS3Bucket: Type: AWS::S3::Bucket
AWSTemplateFormatVersion: 2010-09-09 Resources: MyFirstNestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://s3.amazonaws.com/amzn-s3-demo-bucket/first-nested-stack.yaml Parameters: # Pass parameters to the nested stack if needed InstanceType: t3.micro MySecondNestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://s3.amazonaws.com/amzn-s3-demo-bucket/second-nested-stack.yaml Parameters: # Pass parameters to the nested stack if needed Environment: Testing DependsOn: MyFirstNestedStack

巢狀堆疊架構範例

本節展示一個巢狀堆疊架構,包含一個參考巢狀堆疊的最上層堆疊。該巢狀堆疊會部署 Node.js Lambda 函式,從最上層堆疊接收參數數值,並傳回透過最上層堆疊公開的輸出。

步驟 1:在本機系統建立巢狀堆疊的範本

下列範例示範巢狀堆疊範本的格式。

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: Nested stack template for Lambda function deployment Parameters: MemorySize: Type: Number Default: 128 MinValue: 128 MaxValue: 10240 Description: Lambda function memory allocation (128-10240 MB) Resources: LambdaFunction: Type: AWS::Lambda::Function Properties: FunctionName: !Sub "${AWS::StackName}-Function" Runtime: nodejs18.x Handler: index.handler Role: !GetAtt LambdaExecutionRole.Arn Code: ZipFile: | exports.handler = async (event) => { return { statusCode: 200, body: JSON.stringify('Hello from Lambda!') }; }; MemorySize: !Ref MemorySize LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole' Outputs: LambdaArn: Description: ARN of the created Lambda function Value: !GetAtt LambdaFunction.Arn

步驟 2:在本機系統建立最上層堆疊的範本

下列範例展示最上層堆疊範本的格式,以及參考您在上一步建立之堆疊的 AWS::CloudFormation::Stack 資源。

YAML

AWSTemplateFormatVersion: 2010-09-09 Description: Top-level stack template that deploys a nested stack Resources: NestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: /path_to_template/nested-template.yaml Parameters: MemorySize: 256 Outputs: NestedStackLambdaArn: Description: ARN of the Lambda function from nested stack Value: !GetAtt NestedStack.Outputs.LambdaArn

步驟 3:封裝並部署範本

注意

在本機處理範本時,AWS CLI package 命令可協助您準備用於部署的範本。它會自動處理本機成品上傳至 Amazon S3 (包括 TemplateURL),並產生新的範本檔案,其中包含這些 S3 位置的更新參考。如需更多詳細資訊,請參閱 透過 AWS CLI 上傳本機成品到 S3 儲存貯體

接著,您可以使用 package 命令將巢狀範本上傳至 Amazon S3 儲存貯體。

aws cloudformation package \ --s3-bucket amzn-s3-demo-bucket \ --template /path_to_template/top-level-template.yaml \ --output-template-file packaged-template.yaml \ --output json

命令會在 --output-template-file 指定的路徑上產生新的範本。如下所示,它會將 TemplateURL 參考取代為 Amazon S3 位置。

產生範本

AWSTemplateFormatVersion: 2010-09-09 Description: Top-level stack template that deploys a nested stack Resources: NestedStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: https://s3.us-west-2.amazonaws.com/amzn-s3-demo-bucket/8b3bb7aa7abfc6e37e2d06b869484bed.template Parameters: MemorySize: 256 Outputs: NestedStackLambdaArn: Description: ARN of the Lambda function from nested stack Value: Fn::GetAtt: - NestedStack - Outputs.LambdaArn

執行 package 命令後,您可以使用 deploy 命令部署已處理的範本。對於包含 IAM 資源巢狀堆疊的 IAM 功能,您必須透過包含 --capabilities 選項確認 IAM 功能。

aws cloudformation deploy \ --template-file packaged-template.yaml \ --stack-name stack-name \ --capabilities CAPABILITY_NAMED_IAM

對巢狀堆疊執行堆疊操作

處理巢狀堆疊時,執行操作時需謹慎對待。某些堆疊操作 (例如堆疊更新) 應從根堆疊啟動,而非直接在巢狀堆疊上執行。更新根堆疊時,僅有範本發生變更的巢狀堆疊會被更新。

此外,巢狀堆疊的存在可能會影響對根堆疊的操作。例如,若某個巢狀堆疊卡在 UPDATE_ROLLBACK_IN_PROGRESS 狀態,根堆疊會等待該巢狀堆疊完成復原後再繼續。執行更新操作前,請確保您具備取消堆疊更新的 IAM 許可,以防其復原。如需更多詳細資訊,請參閱 使用 AWS Identity and Access Management 來控制 CloudFormation 存取

透過下列步驟尋找根堆疊和巢狀堆疊。

檢視巢狀堆疊的根堆疊
  1. 請登入 AWS 管理主控台,開啟位於 https://console.aws.amazon.com/cloudformation 的 CloudFormation 主控台。

  2. 堆疊頁面上,選擇要檢視根堆疊的巢狀堆疊名稱。

    巢狀堆疊會在其堆疊名稱上方顯示巢狀

  3. 堆疊資訊索引標籤的概觀區段中,選擇列為根堆疊的堆疊名稱。

檢視屬於根堆疊的巢狀堆疊
  1. 從您要檢視其巢狀堆疊的根堆疊,選擇資源索引標籤。

  2. 類型欄中,尋找 AWS::CloudFormation::Stack 類型的資源。