The main idea behind the Nested Stacks is to avoid writing superfluous code and to make templates reusable.
Instead, a template is created only once, stored in an S3 bucket, and during stacks creation – you just refer to it.
For example, you can use the same template file to create two Load Balancers with different parameters and/or listeners using Conditions.
Documentation is available here>>>, and a good post is here>>>.
In this post we will:
create a root stack – it will describe our other stacks, it will like a skeleton
will add another stack with a VPC as a child stack to the root stack
and one more child stack with AWS SecurityGroups
Also, our nested stack must be able to share their parameters between them to make it possible to use the same template for various environments – Dev/Stage/Prod.
In the end – we will take a brief overview of AWS CloudFormation parameters Import/Export feature between independent stacks.
Here we are creating the only one resource – AWS::CloudFormation::Stack passing a child’s stack template file network-stack.yml via the root’s Properties.
In the TemplateURL will have to set an S3 bucket URL – will update it shortly.
CloudFormation created a nested-stacks-root stack and its child stack named nested-stacks-root-VPCStack-1FTY8TI2PR2D2 with VPC, as described in the network-stack.yml template:
AWS CloudFormation package && deploy
To avoid uploading templates manually we can use AWS CLI CloudFormation package and deploy options.
package
package will copy specified files or a whole directory in an S3 bucket.
Update your root-stack.json — replace the TemplateURL of the VPCStack Resouce to a local path – full or relative to the root stack’s file:
In the Resources block for the VPCStack resource add Parameters section with VPCCIDRBlock parameter where we will pass our VPCCIDRBlock value from the “global” parameters:
Also, Nested Stack allows using other stacks Outputs via the Fn::GetAtt function.
Let’s add a third stack named SecurityGroupStack where our SecurityGroup will be described.
We will pass the VPC ID to this SecurotyGroup using Outputs of the network-stack.yml stack.
Remember, that such parameters can be passed only from the “bottom” to “top” and back.
I.e. you can not pass a parameter directly from the VPCStack to the SecurityGroupStack, but you can return a value to the root stack and then use it as a parameter for a child stack.
To do so:
in the VPCStack (network-stack.yml) stack we will add Outputs to return an ID of the VPC crated
in the root stack root-stack.json we will describe a new stack with the SecurityGroupStack name, which Parameters will accept a vlue from the VPCStackOutputs (network-stack.yml)
will create a new stack SecurityGroupStack, which template will use Parameters > VPCID
In the Resources add another stack with a VPC using the same template file, but now in its Parameters use the Fn::FindInMap function to get a value for the Property VPCCIDRBlock:
Do not forget about SecurityGroup – add another one – again, using the same SG’s template sg-stack.yml, and attach this second SecurityGroup to the second VPC:
CloudFormation removed the VPCStack and instead created two new stacks – VPCStack1 и VPCStack2, and in the same way – for the SecurityGroup.
Import/export values vs Nested Stacks
The Outputs in nested stacks is good to share parameters between affined stacks, but it will work only for current stacks “tree” and can not be shared with a not related stack in this AWS account.
Here we can use another AWS CLoudFormatiuon feature called cross-stack reference – in a first stack you’ll create an Export, and in an another – their Import.
Pitfalls
exported values are accessible within the same AWS region only
you can’t delete a stack if it importing values used by any other stack
Add an Export for the ID of the SecurityGroups crated to make it available to use later in other, independent, stacks.
To do so, update the SecurityGroup sg-stack.yml template and add its ID to the Outputs:
in the Value we are getting a SecurityGroup ID from its Outputs
in the Export: Name with the Fn::Sub we are generating an uniq name.
Deploy, check the SecurityGroup‘s stack Outputs:
And Outputs of the root stack – find the Exported values:
Also, they are available now in the Exports of the whole CloudFormation for this account:
Now, we can use it for other stacks.
To check it, let’s add a stack with the only VPC resource (just because a CloudFormation stack has to have at least one Resource type), and in its Outputs using Fn::ImportValue we will display SecurityGroups IDs from the nested-stacks-root stack: