AWS CloudFormation- Nested Stacks
AWS CloudFormation leverages the concept of Infrastructure as Code (IaC). You neednot manually create all of your resources needed one by one, CloudFormation will do this for you.
All resources are defined on the AWS CloudFormation template. This means that this AWS environment can be reliably and easily reproduced since everything is declared on a template.
With AWS CloudFormation, you can either upload your own template, use a sample template, or create a template using Designer. These templates can be in JSON or YAML format. Resources that will be created from these templates are treated and managed as a single unit called stacks.
I have already covered CloudFormation concepts in one of my article before. Pls click here to read that. Today I will explore the concept of nested stack in CloudFormation.
Que 1- What is a Stack in CloudFormation?
Ans- A stack consists of a collection of resources. In other words, the stack consists of one or more templates.
The advantage of the stack is that it is easy to create, delete or update the collection of resources. The advanced stacks have a nested stack which holds a collection of stacks.
Que 2- Why Nested Stack?
Ans- As your infrastructure grows, common patterns can emerge in which you declare the same components in multiple templates. You can separate out these common components and create dedicated templates for them. Then use the resource in your template to reference other templates, creating Nested Stack. And a particular CloudFormation template may be used multiple times if needed.
Thus, as the name suggests, a Nested Stack consists of one or more stacks referencing each other. In such cases, we isolate a common template and reference it as needed from a nested stack.
- Nested stack itself consists of one or stacks in a reference hierarchy.
- Nested Stack will have a parent stack that has one or more child stacks.
Que 3- How does Nested Stack communicate?
Ans- Nested stacks can communicate with each other through stack outputs. A child stack can export certain values as outputs, which can be imported by the parent stack or other nested stacks. This facilitates data sharing and dependency management between different components.
Implement
Task:
Here, we are going to see the example of a Nested Stack by creating an Autoscaling group stack and a Load balancer stack and attaching the Load Balancer stack to the Autoscaling stack.
Steps
1) Sign into the AWS Management Console. Create a S3 bucket (we will be using this S3 bucket to Upload our templates, used for creating stack).
2) Create template for Autoscaling group (Nested_ASG.yaml)
3) Create template for a Load Balancer (Nested_LB.yaml)
4) Create template for a Nested Stack (Nested_stack.yaml)
Upload all the three to S3 bucket.
5) Editing Nested_stack.yaml file, and upload it back to our bucket.
6) Creating a web server with an Autoscaling group and a Load balancer using a CloudFormation Nested stack.
7) Check the resources created by the Nested Stack
8) Checking for an Auto Scaling group
9) Checking for an EC2 instance
10) Checking for a Load Balancer
11) Testing the load balancer
Solution:
1) Sign into the AWS Management Console, create S3 buck.
Navigate to Services menu at the top and click on S3 in the Storage section.
Create a S3 bucket (we will be using this S3 bucket to Upload our Templates) and note down its URL
2) Create template for Autoscaling group (Nested_ASG.yaml), upload it to bucket.
The template Nested_ASG.yaml will have below code:
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Sample Template for creating EC2 instance
Parameters:
WebInstanceType:
Description: WebServer EC2 instance type
Type: String
Default: t2.micro
ConstraintDescription: must be a valid EC2 instance type.
KeyName:
Description: Key pair name
Type: 'AWS::EC2::KeyPair::KeyName'
Default: whizlabs-key
VPCSubnet:
Type: CommaDelimitedList
AMIid:
Description: Image ID
Type: 'AWS::EC2::Image::Id'
Default: ami-00eb20669e0990cb4
TargetGroupName:
Description: Target Group ARN
Type: String
SSHLocation:
Description: The IP address range that can be used to SSH to the EC2 instances
Type: String
MinLength: '9'
MaxLength: '18'
Default: 0.0.0.0/0
Resources:
WebserverASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
VPCZoneIdentifier: !Ref VPCSubnet
TargetGroupARNs:
- !Ref TargetGroupName
LaunchConfigurationName:
Ref: LaunchConfig
MaxSize: "3"
MinSize: "2"
Tags:
- Key: Name
Value: Nested_webserver
PropagateAtLaunch: True
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
KeyName:
Ref: KeyName
ImageId: !Ref AMIid
InstanceType: !Ref WebInstanceType
LaunchConfigurationName: LaunchConfig
SecurityGroups:
- Fn::GetAtt: [ WebsecGroup, GroupId ]
UserData:
'Fn::Base64': !Sub |
#!/bin/bash
# install apache
yum install httpd24 -y
time=`date`
# start server
service httpd start
chkconfig httpd on
echo "Test page of server created at "$time"" > /var/www/html/index.html
WebsecGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: Security Group for Autoscaling
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: !Ref SSHLocation
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: !Ref SSHLocation
Tags:
- Key: Name
Value: WEBSERVER_SGThis YAML code is used to create the Autoscaling Group. The CloudFormation stack attached with the Launch configuration and security group for Launch configuration. Below are some important details provided in the CloudFormation template for creating the Autoscaling group:
Parameters
- InstanceType: It is a WebServer EC2 instance type. It must be a valid EC2 instance type.
- KeyName: Name of an existing EC2 KeyPair to enable SSH access to the instance. It must be the name of an existing EC2 KeyPair.
- AMIid: It is the ID of an image present in the us-east-1 region used to launch your web server.
- LoadBalancerName: Name of the load balancer to which you have to attach the Autoscaling group.
- User data: To install HTTPD service at the time of launching the instance and putting a test page to check the working of the load balancer.
- SSHLocation: The IP address range that can be used to SSH into the EC2 instances. It must be a valid IP CIDR range of form x.x.x.x/x.
Resources
- WebserverASG: Resource name for creating the Autoscaling group.
- LaunchConfig: Launch configuration resource defined for the Autoscaling group.
- WebsecGroup: Security group for the launch configuration.
Click to download Nested_ASG.yaml
3) Create template for a Load Balancer (Nested_LB.yaml), upload it to bucket.
This template (Nested_LB.yaml) is used for launching a load balancer attached to the security group.
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Sample Template for creating LoadBalancer
Parameters:
SubnetId:
Type: CommaDelimitedList
VPCId:
Type: String
Resources:
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: MyApplicationLoadBalancer
Type: application
IpAddressType: ipv4
Scheme: internet-facing
Subnets: !Ref SubnetId
SecurityGroups:
- Fn::GetAtt: [ Elbsg, GroupId ]
Tags:
- Key: Name
Value: ELB_Nested
HTTPListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: "HTTP"
DefaultActions:
- Type: forward
TargetGroupArn: !Ref ALBTargetGroup
ALBTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
HealthCheckPath: /
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Matcher:
HttpCode: 200,302
Name: MyWebServers
Port: 80
Protocol: HTTP
TargetType: instance
UnhealthyThresholdCount: 5
VpcId: !Ref VPCId
Tags:
- Key: Name
Value: ELB_Nested
Elbsg:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupName: ELB-sg
GroupDescription: Security group for Load balancer
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort: '80'
IpProtocol: tcp
ToPort: '80'
Tags:
- Key: Name
Value: ELB_SG
Outputs:
TargetGroupName:
Value: !Ref ALBTargetGroup
Description: Name of Target ARNBelow are some important details provided in the CloudFormation template for creating the Load Balancer.
Resources
- ElasticLoadBalancer: Resource name for creating the load balancer.
- Elbsg: Resource name for creating a security group for the load balancer.
- Outputs: Getting the name of the load balancer using the output to refer it in the Autoscaling group.
Click to download Nested_LB.yaml
4) Create template for a Nested Stack (Nested_stack.yaml), upload it to bucket.
This template is used for creating a nested stack with Nested_ASG.yaml and Nested_LB.yaml. Here we are attaching the Autoscaling group to the load balancer.
Below is the code for (Nested_stack.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Description: Template for Nested stack
Parameters:
VPCId:
Type: AWS::EC2::VPC::Id
Description: Choose 1 VPC from below
SubnetId:
Type: 'List<AWS::EC2::Subnet::Id>'
Description: Choose 2 Subnets to create Load balancer and ASG
Resources:
MyWebserverstack1:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/whizlabs.162017.74686162/Nested_ASG.yaml
TimeoutInMinutes: 5
Parameters:
TargetGroupName: !GetAtt 'Elbstack.Outputs.TargetGroupName'
VPCSubnet: !Join
- ','
- !Ref SubnetId
Elbstack:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: https://s3.amazonaws.com/whizlabs.162017.74686162/Nested_LB.yaml
Parameters:
SubnetId: !Join
- ','
- !Ref SubnetId
VPCId: !Ref VPCId
Outputs:
StackRef:
Value: !Ref Elbstack
OutputFromNestedStack:
Value: !GetAtt Elbstack.Outputs.TargetGroupNameBelow are some important details provided in the CloudFormation template for creating the Nested stack.
Resources
- MyWebserverstack: Name of the stack used to create the Autoscaling group.
- The parameter: Variable in webserverstack that is a reference to the load balancer name (that we received as output from the load balancer).
- Elbstack: Name of the stack used for creating the load balancer.
Click to download Nested_stack.yaml
Get Sumbul Naqvi’s stories in your inbox
Join Medium for free to get updates from this writer.
5) Editing Nested_stack.yaml file, and upload it back to our bucket.
Upload the YAML files into S3 bucket.
Once done copy the URL of first two ( Nested_ASG.yaml and Nested_LB.yaml) and update Nested_stack.yaml and and re uplaod after modification.
URL of Nested_ASG.yaml
https://s3.amazonaws.com/whizlabs.162017.74686162/Nested_ASG.yaml
URL of Nested_LB.yaml
https://s3.amazonaws.com/whizlabs.162017.74686162/Nested_LB.yaml
Edit file locally Nested_stack.yaml and Upload to S3 again.
Click on the S3 bucket name and you will be able to see three files : Nested_ALB.yaml, Nested_ASG.yaml and Nested_Stack.yaml (updated).
6) Creating a web server with an Autoscaling group and a Load balancer using a CloudFormation Nested stack.
Navigate to CloudFormation. Click on Services and then select CloudFormation in the Management & Governance section. On the CloudFormation dashboard, click on Create stack button.
And Specify Stack details.
Prerequisite — Prepare template : Select Template is ready
Specify Template : Template source: Select Amazon S3 URL
Amazon S3 URL : Enter the Nested_stack.yaml object URL
(https://s3.amazonaws.com/whizlabs.162017.74686162/Nested_stack.yaml)
Stack name: Enter a unique stack name such as mycfstack
SubnetID: Choose 2 default subnet groups.
VPCId: Choose the default VPC ID
You will see the other details are auto-filled since it takes the values from the stacks referred to in the nested stack. Click on Next
Add tags, check the both acknowledgements and click on Submit button.
Once you click on the create button, you will be redirected to the CloudFormation stack list.
Status: You will see the status: CREATE_IN_PROGRESS.
You need to wait for 1–5 minutes for the stack resources to finish creating. Click on the refresh button beside New events available to get an update on progress.
Once your stack status changes to CREATE COMPLETE, we are ready to proceed.
7) Check the resources created by the Nested Stack
Check whether the resources are created as per your code.i.e as per your nested stack template.
8) Checking for an Auto Scaling group
Navigate to the EC2 page from the Services menu. Scroll down in the left panel and click on Autoscaling Groups.
You will find the Autoscaling group created by the CloudFormation nested stack. 😊
9) Checking for an EC2 instance
Navigate to the EC2 page from the Services menu. Click on Instances in the left panel.
You will find the newly-created Instance running. 😊
Note: You will see that two EC2 instances have been launched and are currently running (since we gave the minimum size for our Autoscaling group as two instances in the Nested_ASG.yaml file).
10) Checking for a Load Balancer
Navigate to the EC2 page from the Services menu. Scroll down in the left panel and click on Load Balancers.
Check for the Load balancer created by the stack.
You can find that the load balancer is created with two running instances with healthy as their status in target group.😊
11) Testing the load balancer
Navigate to the EC2 page from the Services menu. Scroll down in the left panel and click on Load Balancers.
Click on Description and copy the DNS name.
DNS Name: MyApplicationLoadBalancer-708398540.us-east-1.elb.amazonaws.com
- Paste the DNS name in the browser and you will get the below output, stating that the load balancer is routing the traffic to the instance.
Closely note the timestamp of the server created. Refresh the URL a couple of times and you will get a response from the other server created in the different timestamp.
This concludes that the load balancer routes traffic across both servers.😊
We have successfully created web servers and Auto scaling group and Load balancer and route the traffic using nested stack in cloud formation. 😊
Thanks,
Happy learning & sharing 😊
Sumbul







