使用嵌套堆栈将模板拆分为可重复使用的部分
随着基础设施的发展,您可能会发现自己在多个模板中反复创建相同的资源配置。为避免这种冗余,您可以将这些常用配置分成专用模板。然后,您可以使用其他模板中的 AWS::CloudFormation::Stack 资源来引用这些专用模板,创建嵌套堆栈。
例如,假如您拥有用于大多数堆栈的负载均衡器配置。您可以为负载均衡器创建专用模板,而不是将相同的配置复制并粘贴到您的模板中。然后,您可以从需要相同负载均衡器配置的其他模板中引用此模板。
嵌套堆栈本身可以包含其他嵌套堆栈,构成一个堆栈层次结构,如下图所示。根堆栈是所有嵌套堆栈最终归属的顶级堆栈。每个嵌套堆栈都有一个直属父堆栈。对于第一级的嵌套堆栈而言,根堆栈也是父堆栈。
-
堆栈 A 是该层次结构中所有其他嵌套堆栈的根堆栈。
-
对于堆栈 B 来说,堆栈 A 既是父堆栈,也是根堆栈。
-
对于堆栈 D,堆栈 C 是父堆栈;而对于堆栈 C 来说,堆栈 B 是父堆栈。

拆分模板之前和之后的示例
此示例演示如何提取单个大型 CloudFormation 模板,然后使用嵌套模板将其重组为结构化程度更高、可重复使用的设计。最初,“嵌套堆栈前”模板显示在一个文件中定义了所有资源。随着资源数量不断增长,该文件可能会变得混乱且难以管理。“嵌套堆栈后”模板将资源拆分为若干较小的独立模板。每个嵌套堆栈都处理一组特定的相关资源,从而使整体结构更有条理,更易于维护。
嵌套堆栈前 |
嵌套堆栈后 |
---|---|
|
|
嵌套堆栈架构的示例
本部分演示了一种嵌套堆栈架构,该架构由引用嵌套堆栈的顶级堆栈组成。嵌套堆栈部署 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:打包并部署模板
注意
在本地使用模板时,Amazon CLI package 命令可以帮助您准备部署模板。它会自动处理将本地构件上传到 Amazon S3(包括 TemplateURL
),并生成一个新的模板文件,其中包含对这些 S3 位置的更新引用。有关更多信息,请参阅 使用 Amazon CLI 将本地构件上传到 S3 存储桶。
接下来,您可以使用 package 命令将嵌套模板上传到 Amazon S3 存储桶。
aws cloudformation package \ --s3-bucket
amzn-s3-demo-bucket
\ --template/path_to_template/top-level-template.yaml
\ --output-template-filepackaged-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 资源的嵌套堆栈,您必须通过包含 --capabilities
选项来确认 IAM 功能。
aws cloudformation deploy \ --template-file
packaged-template.yaml
\ --stack-namestack-name
\ --capabilities CAPABILITY_NAMED_IAM
在嵌套堆栈上执行堆栈操作
使用嵌套堆栈时,在操作过程中必须谨慎处理。某些堆栈操作(如堆栈更新等)应从根堆栈启动,而不是直接在嵌套堆栈上执行。更新根堆栈时,只有包含模板更改的嵌套堆栈才会更新。
此外,嵌套堆栈的存在可能会影响根堆栈上的操作。例如,如果一个嵌套堆栈卡在 UPDATE_ROLLBACK_IN_PROGRESS
状态,则根堆栈将等待该嵌套堆栈完成其回滚后再继续。在继续更新操作之前,请确保您拥有 IAM 权限,以在其回滚时取消堆栈更新。有关更多信息,请参阅 使用 Amazon Identity and Access Management 控制 CloudFormation 访问权限。
按照以下过程查找根堆栈和嵌套堆栈。
查看嵌套堆栈的根堆栈
-
登录到 Amazon Web Services Management Console 并打开 Amazon CloudFormation 控制台 https://console.aws.amazon.com/cloudformation
。 -
在堆栈页面上,选择您要查看其根堆栈的嵌套堆栈的名称。
嵌套堆栈的堆栈名称上方会显示 NESTED。
-
在堆栈信息选项卡的概述部分中,选择列为根堆栈的堆栈名称。
查看属于根堆栈的嵌套堆栈
-
从要查看其嵌套堆栈的根堆栈中,选择资源选项卡。
-
在类型列中,查找类型为 AWS::CloudFormation::Stack 的资源。