Nested stacks in CloudFormation or SAM has tree-like structure. Usually, there is a root stack, which contains multiple other stacks, aka nested stacks.

nested stack image

Nested stacks can have other nested stacks, creating hierarchy of stacks. Stack update operation happens at the root level, so if you need to have seperate deployable stacks, consider using SSM parameters. Using SSM parameters, you can deploy different stacks without intitating root-level stack update, and sharing of data between happens using SSM parameters. For example, Stack A deploys kms and s3 resources and saves the id or arn of kms or s3 bucket to SSM parameters. Stack B deploy DynamoDB and Lambda functions. Stack B reads from SSM parameters that was saved by Stack A, and uses the ids or Arns to maybe use encryption key.

For SAM users, make sure to add "Transform: AWS::Serverless-2016-10-31" to root.yml. In terms of resources type in root.yml, "AWS::Serverless::Application" macro is optional for SAM since it would understand "AWS::Cloudformation::Stack" type as well. We have added # comments to make it easy for you copy and understand the subtles changes for SAM

Let's dive into the code showing how to use SAM or CloudFormation nested stacks and share parameters or variables with child Stacks

root.yml
# root/parent stack
AWSTemplateFormatVersion: "2010-09-09"
# Transform: AWS::Serverless-2016-10-31
Description: >
Nested Stacks Parent templates
Parameters:
StageName:
Type: String
Default: dev
AllowedValues:
- dev
- stage
- prod
Description: ENV stage name
Resources:
s3Stack:
Type: AWS::Cloudformation::Stack # AWS::Serverless::Application
Properties:
# assuming there are two outputs in s3Stack (AppBucket, AppBucketDomain)
Location: s3stack.yml
# passing the root/parent stack parameter value to child stack
Parameters:
stage: !Ref StageName
lambdaStack:
Type: AWS::Cloudformation::Stack # AWS::Serverless::Application
DependsOn: [s3Stack]
Properties:
Location: lambda.yml
Parameters:
# get the output value from s3Stack
S3Bucket: !GetAtt keystack.Outputs.AppBucket
stage: !Ref StageName
apiStack:
Type: AWS::Cloudformation::Stack # AWS::Serverless::Application
DependsOn: [lambdaStack]
Properties:
Location: api.yml
Parameters:
TestFnArn: !GetAtt lambdaStack.Outputs.OrderFnArn
Test2FnArn: !GetAtt lambdaStack.Outputs.Test2FnArn
stage: !Ref StageName
cloudfrontStack:
Type: AWS::Cloudformation::Stack # AWS::Serverless::Application
DependsOn: [keystack, lambdaStack, apiStack]
Properties:
Location: cloudfront.yml
Parameters:
appBucketDomain: !GetAtt keystack.Outputs.AppBucketDomain
apiUrl: !GetAtt apiStack.Outputs.RestApiUrl
stage: !Ref StageName
cognitoStack:
Type: AWS::Cloudformation::Stack # AWS::Serverless::Application
DependsOn: [cloudfrontStack]
Properties:
Location: cognito.yml
Parameters:
redirectUrl: !GetAtt cloudfrontStack.Outputs.cloudFrontDomain
stage: !Ref StageName
s3stack.yml
# nested/child stack
AWSTemplateFormatVersion: "2010-09-09"
# Transform: AWS::Serverless-2016-10-31
Description: >
Nested Stacks: s3stack template
Parameters:
StageName:
Type: String
Default: dev
AllowedValues:
- dev
- stage
- prod
Description: ENV stage name
Resources:
...
lambda.yml
# nested/child stack
AWSTemplateFormatVersion: "2010-09-09"
# Transform: AWS::Serverless-2016-10-31
Description: >
Nested Stacks: Lambda stack template
Parameters:
StageName:
Type: String
Default: dev
AllowedValues:
- dev
- stage
- prod
Description: ENV stage name
Resources:
...
Subscribe now!
No spam, we promise!