Our Blog

Oct 31 2014

CloudFormation Zen: Nested Stacks

Derek DeJonghe

Nested stacks are a great way to organize your CloudFormation. However, in order to reduce stress, lower cloud costs and improve time to market, you must modularize your templates.

Nesting highlights the importance and agility of modularized templates. Imagine having a nested stack that referenced the same template for three separate stack resources. If you changed one parameter across these three it would cause the configuration management to boot an entirely different application server with similar infrastructure.

Modularizing speeds up your infrastructure development tenfold and eliminates the copy and paste of CloudFormation. Modularizing templates is the first step in truly treating your Infrastructure as Code (IaC)!

Think of your templates as functions and your nested stack as mainly calling your functions and applying the parameters.

Nesting and CloudFormation Basics

CloudFormation is an AWS service and JSON template language that allows for programmatic creation of, and interaction with, AWS resources. The collection of one or more resources created by CloudFormation is called a stack. CloudFormation allows us to achieve IaC practices, a programmatic approach to describe, create, update and delete infrastructure.

CloudFormation templates have hard limits of 200 resources, 60 parameters, 100 mappings and 60 outputs. To build large networks (and keep your sanity) you’ll need to break up your templates to work within these limitations. This is especially important to note because VPC networks can become lengthy.

A CloudFormation nested stack is a stack containing one or more CloudFormation stacks as resources. Nesting your stacks allows you to break up your CloudFormation into logical pieces. It also allows you to map outputs to parameters between templates.

Nesting is very important when working with multiple stacks that interact and depend on each other. Nested stacks will recognize changes that affect child stacks and update their parameters accordingly.

CloudFormation workflow can be represented as in the following diagram:

CFNWorkflow

Nesting

A nested stack is a normal CloudFormation template that defines a resource of type AWS::CloudFormation::Stack. Order of operations still holds true in nested stacks. If a stack uses a depends on or a GetAtt of another stack resource, those resources will be created before the dependent. CloudFormation will sort the dependencies and boot in the most efficient way, parallelizing what it can.

Stack Resource documentation can be found here: AWS Stack Resource Documentation

The following is a depiction of a nested stack using the diagram above.

NestedCFNWorkflow

Breaking Up Your CloudFormation

Modularization is key for refactoring large, unwieldy templates. Find portions of your template that are common and repeated, and break them out into their own template.

Use parameters as your variable values.

Use conditions where applicable for Boolean logic, such as determining if an Auto Scaling group and coupled Elastic Load Balancer should span multiple availability zones.

Mappings are a good way to get longevity out of your parameters. For example, say you commonly use the same number for max and min instances in an Auto Scaling group dependent on the environment. Use the environment parameter as a key in your find in map function.

Outputs are very important in nesting your stacks. Outputs are the only section of a child template available to the nested template. Typically you want to only output information from the template about the living resources it returns such as Physical IDs, ARNs, IPs and URL Endpoints.

Accessing Your Outputs

The ability to map outputs to parameters between child stacks is a huge incentive to nest.
To access outputs from a stack resource you must use the intrinsic function Fn::GetAtt. Unlike most other GetAtt attributes, the stack resource has a namespace of ‘Outputs.’ followed by the OutputName. We see the namespace as a foreshadow that AWS will expand on these features in the future.

Example:
CodesnippetZenFormation

This example would return the output named ProdAppSubnetAz1 from your network stack and map it to a parameter named SubnetAz1 to an application stack using a parameter for a TemplateURL.

Updates

Each time you update the nested stack it will look for changes in all of its child stacks. An update to a child stack would occur if the template in S3 has changed or if a parameter value of that template has changed. Stacks will not be updated unless there is a change to the resources requested. Adding an output to a template will not create an update as the resources in that stack did not change. You should plan ahead and output everything you might need before you deploy.

Typically you’ll only update the nested stack. It’s worth noting that if an update rollback fails on a child stack, the nested stack will inherit the UPDATE_ROLLBACK_FAILED state. You cannot update from this state. You have two options: contact AWS support to request a manual change to the state or deletion of your nested stack.

Fin

Infrastructure as Code becomes a reality with nested stacks and modularized templates. Remember to keep your templates in version control. The sooner you start treating your infrastructure as a real project, the sooner you will reach a state of heightened awareness and architectural enlightenment.

Namaste…

Save

Save

4 thoughts on “CloudFormation Zen: Nested Stacks”

  1. Ricky Morris says:

    Great information!! Thanks for sharing!!

  2. Bruce says:

    Any thoughts on how to implement conditional dependencies?

    Say I have a child template to create vpc peering connections.

    I usually need 2 vpn peering connections, unless the peer subnet parametes are equal, in which case you only need one.

    How to make the second DependsOn dependent on a Condition.

    Keep getting this error when I try a conditional Fn:: within the DependsOn.

    A client error (ValidationError) occurred when calling the ValidateTemplate operation: Template format error: DependsOn must be a string or list of strings.

    1. Hey there Bruce,

      Apologies for the late response, I’m afraid I don’t quite understand your question. You should not a DependsOn for a Condition, Conditions are always evaluated before any resources. You can Conditionally create resources. From the error you’re displaying it’s true you can not use a intrinsic function within the dependsOn statement, the value can only be a string or list of strings. The string(s) must be logicalId’s of other resources within the same template.

  3. Chris G. Sellers says:

    Nested stacks are a good way to get around resource limits in a stack, but be careful, if you share too many parameters/outputs between stacks you can run into a limit there as well. Maps can help address that a little as you mentioned above but something to be aware of ahead of time when you break your stack up. Good article.

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe to RightBrain

Recent Posts

Categories

Recent Comments

Archives

Tags