Walkthrough with Nested CloudFormation Stacks

Janeth Fernando
FAUN — Developer Community 🐾
4 min readNov 8, 2019

--

AWS CloudFormation is a template model that is used to describe any AWS resources you need and AWS CloudFormation takes care of provisioning the resources for you. Developers and System Administrators use AWS CloudFormation templates because they do not need to create each and every resource and figure out what depends on what.

CloudFormations are written in JSON format or in YAML format. A collection of AWS resources that are provisioned in a single CloudFormation is called a stack.

What are nested stacks?

When we see common settings and features in two or more Cloudformation scripts, we can use one nested CloudFormation script to create the infrastructure we need. The nested stack mechanism is, pointing to another CloudFormation script from one CloudFormation script. Reusing common template patterns using nested stacks is one of the best practices in CloudFormation.

Parent Stack and the Child Stack

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html

As shown in the figure above, CloudFormation starts with the root stack(A). We can also call it as a parent stack. B is a child stack of A, C is a child stack of B and D is a child stack of C. There are two nested stacks(CloudFormation scripts) pointed in the parent stack A. There is only one Cloudformation script pointed in the B stack. Again there are two CloudFormation scripts pointed in the C stack.

In the code below I have shown how to point to a child stack CloudFormation script.

Parent Stack(parent-template.yaml)

#PLEASE NOTE THAT THIS IS NOT A COMPLETE YAML FILEAWSTemplateFormatVersion: 2010-09-09
Description: >-A Sample template to understand what parent stack and child stack(This is the parent template)
Metadata:
'AWS::CloudFormation::Interface':
ParameterGroups:
- Label:
default: Basic Configuration
Parameters:
- ParentParameterA
- ParentParameterB
ParameterLabels:
ParentParameterA:
default: Sample parent parameter A
ParentParameterB:
default: Sample parent parameter B
Resources:
ChildStack:
Type: 'AWS::CloudFormation::Stack'
Properties:
TemplateURL: "https://s3.us-east-1.amazonaws.com/child-template.yaml"
Parameters:
ChildParameterA: !Ref ParentParameterA
ChildParameterB: !Ref ParentParameterB
.
.
.
Parameters:
ParentParameterA:
Description: Your sample parameter A
Type: String
ParentParameterB:
Description: Your sample parameter B
Type: String
AllowedPattern: '[^\s@]+@[^\s@]+\.[^\s@]+'
ConstraintDescription: You should enter a valid email

Above is a sample template of a parent stack. I have used the Cloudformation Interface type to receive the variables. Under Resources, there is only one child stack. The type of the Child stack should be AWS::CloudFormation::Stack while the Template URL should be an S3 bucket URL. (You need to upload your child template into an S3 bucket and provide the URL). In the above example, I have passed two variables into the child stack.(ChildParameterA and ChildParameterB). Assume that ParentParameterA should be a normal String and ParentParameterB is a String email.

In the sample below I have shown how to receive the parameters from the parent stack.

Child Stack(child-template.yaml)

#PLEASE NOTE THAT THIS IS NOT A COMPLETE YAML FILEAWSTemplateFormatVersion: 2010-09-09
Description: >-A Sample template to understand what parent stack and child stack(This is the child template)
Parameters:
ChildParameterA:
Description: Your sample parameter A
Type: String
ChildParameterB:
Description: Your sample parameter B
Type: String
AllowedPattern: '[^\s@]+@[^\s@]+\.[^\s@]+'
ConstraintDescription: You should enter a valid email
Resources:
VPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Ref ChildParameterA
- Key: User
Value: !Ref ChildParameterB
.
.
.

As you can see in the above figure, I have passed the parameters which I received from the parent stack into the tags.

So now think that the child stack is going to output some variables. The parent CloudFormation is going to use those output variables as inputs to the parent CloudFormation. Let's see how this can be done. I am going to continue the above two scripts to explain this scenario.

Child Stack(child-template.yaml)

#THIS IS THE LATTER PART OF THE child-template SCRIPT
.
.
.
Outputs:
MYVPC:
Description: The ID of the VPC
Value: !Ref VPC

As the output, I am displaying the ID of the VPC I created. Now The Parent stack is going to use this output as an input to the parent stack.

Parent Stack(parent-template.yaml)

#THIS IS A PART OF THE PARENT STACK. I AM CONTINUING FROM THE RESOURCES SECTION OF THE parent-template SCRIPTResources:
#Created the child stack here
InstanceSecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
VpcId: !GetAtt [ ChildStack, Outputs.MYVPC ]
GroupDescription: EC2 Instances Security Group
SecurityGroupIngress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0

As you can see here, I have used the output value which is the MYVPC as an input(VpcId) to the parent stack. So, as a result, the InstanceSecurityGroup will get created on the same VPC which got created on the child stack.

The above picture shows how you see a nested stack gets created. Even though I only created the sample-cfn stack, the nested stack which I pointed in the sample-cfn also got created.

Hope this article helps you when you create nested stacks in AWS CloudFormation :)

Join FAUN!

Subscribe to FAUN topics and get your weekly dose of the must-read tech stories, news, and tutorials 🗞️

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--