I want to pass or share a value between two nested stacks within the same parent stack in AWS CloudFormation.
Resolution
The following resolution uses the AWS::CloudFormation::Stack resources NestedStackA and NestedStackB that are part of the same parent stack that's named RootStack. You're passing a value from NestedStackA to NestedStackB. NestedStackA created the S3 bucket resource, and NestedStackB created the S3 bucket policy that's attached to the S3 bucket.
Complete the following steps:
-
In the Outputs section of your CloudFormation template for NestedStackA, include the value that you want to share.
JSON:
{
"Resources": {
"S3Bucket": {
"Type": "AWS::S3::Bucket",
"DeletionPolicy": "Retain",
"Properties": {
"BucketName": "DOC-EXAMPLE-BUCKET"
}
}
},
"Outputs": {
"BucketNameOutput": {
"Value": { "Ref" : "S3Bucket" },
"Description": "You can refer to any resource from the template."
}
}
}
YAML:
Resources:
S3Bucket:
Type: 'AWS::S3::Bucket'
DeletionPolicy: Retain
Properties:
BucketName: DOC-EXAMPLE-BUCKET
Outputs:
BucketNameOutput:
Value: !Ref S3Bucket
Description: You can refer to any resource from the template.
Note: In the preceding templates, replace DOC-EXAMPLE-BUCKET with your bucket name. The Outputs section of the preceding templates returns the bucket name from !Ref.
-
In the Parameters section of the CloudFormation template for NestedStackB, include a parameter to use the S3 bucket name from the output of NestedStackA.
JSON:
{
"Parameters": {
"BucketNameValueParameter": {
"Type": "String",
"Description": "The shared bucket name value from nestedStackA that will be passed to this parameter from the parent stack."
}
},
"Resources": {
"SampleBucketPolicy": {
"Type": "AWS::S3::BucketPolicy",
"Properties": {
"Bucket": {
"Ref": "BucketNameValueParameter"
},
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": {
"Fn::Join": [
"",
[
"arn:aws:s3:::",
{
"Ref": "DOC-EXAMPLE-BUCKET"
},
"/*"
]
]
},
"Principal": "*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.example.com/*",
"http://example.net/*"
]
}
}
}
]
}
}
}
}
}
YAML:
Parameters:
BucketNameValueParameter:
Type: String
Description: >-
The shared bucket name value from nestedStackA that will be passed to this
parameter from the parent stack.
Resources:
SampleBucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref BucketNameValueParameter
PolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- 's3:GetObject'
Effect: Allow
Resource: !Join
- ''
- - 'arn:aws:s3:::'
- !Ref DOC-EXAMPLE-BUCKET
- /*
Principal: '*'
Condition:
StringLike:
'aws:Referer':
- 'http://www.example.com/*'
- 'http://example.net/*'
-
To pass a value between NestedStackA and NestedStackB, configure RootStack to use the Fn::GetAtt function in the Parameter section for NestedStackB. Use the logical ID of NestedStackA and the bucket name output value in the Outputs.NestedStackOutputName format.
JSON:
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Resources" : {
"NestedStackA" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"TemplateURL" : "https://s3.amazonaws.com/<pathway to .template for NestedStack A>"
}
},
"NestedStackB" : {
"Type" : "AWS::CloudFormation::Stack",
"Properties" : {
"TemplateURL" : "https://s3.amazonaws.com/<pathway to .template for NestedStack B>",
"Parameters" : {
"BucketNameValueParameter" : {
"Fn::GetAtt": [
"NestedStackA",
"Outputs.BucketNameOutput"
]
}
}
}
}
}
}
YAML:
AWSTemplateFormatVersion: 2010-09-09
Resources:
NestedStackA:
Type: 'AWS::CloudFormation::Stack'
Properties:
TemplateURL: 'https://s3.amazonaws.com/<pathway to .template for NestedStack A>'
NestedStackB:
Type: 'AWS::CloudFormation::Stack'
Properties:
TemplateURL: 'https://s3.amazonaws.com/<pathway to .template for NestedStack B>'
Parameters:
BucketNameValueParameter: !GetAtt
- NestedStackA
- Outputs.BucketNameOutput
Related information
Embed stacks within other stacks using nested stacks
AWS CloudFormation template snippets