CloudFormation嵌套栈创建困惑:单栈模板字节超限后的格式疑问
I totally get the frustration—hitting that CloudFormation template size limit is a pain, and nested stack examples can feel all over the place because people structure them based on their specific use cases. Let’s break this down with a concrete example that mirrors a typical single-stack setup, so you can see exactly how to split things up consistently.
First, let’s recap the core of nested stacks: Your "parent" stack acts as the orchestrator, and each "child" stack is a separate template that handles a subset of your resources. The parent uses the AWS::CloudFormation::Stack resource to reference each child, passing in parameters and pulling in outputs as needed.
Step 1: Original Single Stack Snippet (Example)
Let’s say your original stack had an EC2 instance, an S3 bucket, and a Lambda function—something like this:
AWSTemplateFormatVersion: '2010-09-09' Parameters: InstanceType: Type: String Default: t2.micro BucketName: Type: String Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: !Ref InstanceType ImageId: ami-0c55b159cbfafe1f0 # Amazon Linux 2 MyS3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName VersioningConfiguration: Status: Enabled MyLambdaFunction: Type: AWS::Lambda::Function Properties: Runtime: python3.9 Handler: index.lambda_handler Code: ZipFile: | def lambda_handler(event, context): return "Hello from Lambda" Role: !GetAtt LambdaExecutionRole.Arn 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
Step 2: Split into Parent + Child Stacks
We’ll split this into three child stacks: one for EC2, one for S3, and one for Lambda (plus its IAM role). The parent stack will tie them all together.
Parent Stack Template
This is where you define all top-level parameters, then reference each child stack. Note that for child templates larger than 51KB, you’ll need to host them in an S3 bucket (inline templates are only feasible for small resources).
AWSTemplateFormatVersion: '2010-09-09' Parameters: InstanceType: Type: String Default: t2.micro BucketName: Type: String ChildTemplatesS3Bucket: Type: String # Bucket where you'll upload child templates Resources: EC2ChildStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${ChildTemplatesS3Bucket}.s3.amazonaws.com/ec2-child-stack.yaml Parameters: InstanceType: !Ref InstanceType S3ChildStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${ChildTemplatesS3Bucket}.s3.amazonaws.com/s3-child-stack.yaml Parameters: BucketName: !Ref BucketName LambdaChildStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${ChildTemplatesS3Bucket}.s3.amazonaws.com/lambda-child-stack.yaml # Optional: Use outputs from children in other parts of the parent Outputs: EC2InstanceId: Value: !GetAtt EC2ChildStack.Outputs.InstanceId S3BucketArn: Value: !GetAtt S3ChildStack.Outputs.BucketArn LambdaFunctionArn: Value: !GetAtt LambdaChildStack.Outputs.FunctionArn
EC2 Child Stack (ec2-child-stack.yaml)
Handles only the EC2 instance, with its own parameters and outputs:
AWSTemplateFormatVersion: '2010-09-09' Parameters: InstanceType: Type: String Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: InstanceType: !Ref InstanceType ImageId: ami-0c55b159cbfafe1f0 # Amazon Linux 2 Outputs: InstanceId: Value: !Ref MyEC2Instance
S3 Child Stack (s3-child-stack.yaml)
Handles the S3 bucket:
AWSTemplateFormatVersion: '2010-09-09' Parameters: BucketName: Type: String Resources: MyS3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName VersioningConfiguration: Status: Enabled Outputs: BucketArn: Value: !GetAtt MyS3Bucket.Arn
Lambda Child Stack (lambda-child-stack.yaml)
Handles the Lambda function and its IAM role:
AWSTemplateFormatVersion: '2010-09-09' Resources: MyLambdaFunction: Type: AWS::Lambda::Function Properties: Runtime: python3.9 Handler: index.lambda_handler Code: ZipFile: | def lambda_handler(event, context): return "Hello from Lambda" Role: !GetAtt LambdaExecutionRole.Arn 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: FunctionArn: Value: !GetAtt MyLambdaFunction.Arn
Key Things to Remember
- Template Storage: For child templates larger than 51KB, upload them to an S3 bucket (ensure the bucket is accessible to the CloudFormation service). Inline templates are only for very small resources.
- Parameter Passing: Use the
Parametersfield in theAWS::CloudFormation::Stackresource to pass values from parent to child. - Output Sharing: Define outputs in child stacks so the parent (or other children) can reference them using
!GetAtt <ChildStackName>.Outputs.<OutputName>. - Dependencies: CloudFormation automatically handles dependencies between child stacks if they reference each other’s outputs, but you can explicitly set
DependsOnif needed. - Validation: Always validate each child stack individually first using
aws cloudformation validate-templatebefore deploying the parent.
This structure is consistent and scalable—you can add more child stacks as your template grows, organizing them by resource type, environment, or logical component.
内容的提问来源于stack exchange,提问作者claudiadast

