Nested Stacks or Cross-stack References? Which to Organize Your AWS CloudFormation Stacks?

Cross-stack References vs Nested Stacks

As you start using AWS CloudFormation for bigger projects, your templates and stacks get larger. Therefore, managing them gets more difficult day by day. Then, at some point, you realize that you need a way to divide your templates into smaller ones to manage them more efficiently.

AWS CloudFormation provides two methods for this, cross-stack references and nested stacks. As you may guess, each technique has different use cases and strengths. Hence, in this post, let’s discuss some of the differences between cross-stack references and nested stacks.

Managing your stacks separately or together

To begin with, let’s understand how each method organizes your stacks.

In cross-stack references, you manage your stacks separately. You export an output from one stack and import it in another, or in other words, your second stack references the output of the first stack. So, the exported output should be ready before the creation of the importing stack. Hence, you need to create the exporting stack first and the importing one after that.

Cross-stack references

However, in nested stacks, you manage your stacks together through a root stack. Your root stack template contains resource definitions for your nested stacks with the S3 URLs of their templates. Besides, in a root stack template, you can also pass outputs of a nested stack to another using the intrinsic Fn::GetAtt function like attributes in return values of other AWS resource types. This will also create implicit dependencies between your nested stacks and order their creations. So, nested stacks are created and updated like a regular resource. You only use your root stack for these actions.

Creating nested stacks from a root stack

So, if you need to manage your stacks from a single point, you should use nested stacks. For example, you can define a root stack that uses different templates to create an application load balancer, an auto scaling group, etc. These resources often need sub-resources like target groups and auto scaling group policies. So, it would be wiser to place them in separate templates but create or update them together through their root stack.

Alternatively, if you need to manage your stacks as separate entities, you should use cross-stack references. For example, suppose one of your stacks is a network stack creating a VPC, and you have multiple stacks for different applications running in the same VPC. In that case, you can create your network stack separately and share its outputs with the values needed by your application stacks.

Sharing your resources or templates

As I mentioned above, in cross-stack references, you share outputs between your stacks. Although these exported outputs can have any value, in practice, they are often IDs of the resources created by the exporting stack. For example, you can export subnet IDs of the public subnets created by your network stack and import them into your application stacks. Then, your application stacks can use these subnet IDs to create any AWS resource needed in the public subnets. So, most of the time, you share the resources created by the exporting stack with others. But these shared resources are managed by the exporting stack. They are only referenced in the importing stacks.

However, a root stack creating nested stacks is like an ordinary stack but creating more CloudFormation stacks. You can use the same nested stack template to define a similar nested stack in different root stacks. So, you can share templates between multiple root stacks. You can even use the same template to define multiple nested stacks of the same type in the same root stack. The only requirement is placing the template in an S3 bucket in the AWS region you use.

Besides, if you use local paths for your nested stacks, you can copy the nested stack template between your project folders and define a new nested stack in the new root stack. Hence, in nested stacks, your focus should be on templates in terms of sharing. Whereas in cross-stack references, your goal would be sharing resource IDs when needed.

Updating your stack resources

In cross-stack references, you cannot update the exported output value if another stack already imports it. This is because the stacks are managed separately, and the updated value may have unexpected consequences on the importing stack. For example, the update may require the replacement of a resource. Therefore, AWS CloudFormation does not allow this.

But if you share a resource by exporting its ID as I described above, you can update its properties and make it available for all resources importing its output by updating only the exporting stack. Let me give an example to explain this better. Let’s say that you have multiple database stacks using the same security group rules, and you need to allow access to the same port in all databases created by these stacks. If you create the database security group in a network stack and share its security group ID with the database stacks as an exported output, you can add the rule to the network stack template and update the network stack without touching your database stacks. Your new rule will be applied to all your databases after the network stack update completes. But you cannot change the exported security group ID in any way unless you remove its references from the database stacks.

However, in nested stacks, you manage all resources together through the root stack. There are no limits for updating nested stack outputs, even if they are passed to other nested stacks as parameter values. Because you update your nested stacks by updating your root stack, it will also launch a stack update on the nested stacks affected. Then, if a resource replacement is necessary in an affected nested stack, it can perform that during its own stack update.

So, updating a stack output or any resource is straightforward in nested stacks. You just make the changes in your templates and update your root stack. It takes care of the rest.

Ease of duplicating your AWS infrastructure

One of the strengths of using AWS CloudFormation is the reusability of your templates to duplicate your infrastructure easily. In cross-stack references, you need to create all stacks one by one to create the same architecture again for another usage in the same or another AWS region.

However, if you organize your stacks as nested stacks, you can just deploy another root stack using the same templates in any region you like, and it will also create the nested stacks for you. Besides, if you use local paths for your nested stack templates and use the cloudformation package command of AWS CLI, it can take care of uploading the nested stack templates to an S3 bucket for you. All you need to do is picking a region and providing an S3 bucket in that region. Using bash scripts in your deployments makes this even more straightforward.

So, if you plan to create duplicates of your infrastructure easily and manage it as a single project, using nested stacks may help you.

Conclusion

Cross-stack references and nested stacks have their use cases. They may seem complicated at first, but you need to know how to use them to organize your AWS CloudFormation stacks efficiently.

As an experienced programmer, I like dividing large projects into multiple small parts and often use nested stacks to group and encapsulate my related AWS resources together. It also simplifies sharing code between different infrastructure projects. Besides, I also often create a single VPC stack and share its resources by exporting its outputs as AWS limits the number of VPCs you can create in an AWS region to five.

Thanks for reading!

Would you like to learn AWS CloudFormation?

If you are a beginner to AWS CloudFormation or learn more advanced features like cross-stack references and nested stacks discussed in this post, my beginner and intermediate level AWS CloudFormation courses on Udemy may help you.

  • Level 1: AWS CloudFormation Step by Step: Beginner to Intermediate

    If you are a beginner to CloudFormation, this course is for you. It will teach you how to create, update, delete CloudFormation stacks, write your own templates with YAML and use template sections efficiently. You will also learn to use change sets to update your stacks safely and the cloudformation commands of AWS CLI.

    Ineterested? To view the course topics and enroll in it with a special discount, you can use this link: Join AWS CloudFormation Step by Step: Beginner to Intermediate on Udemy!

  • Level 2: AWS CloudFormation Step by Step: Intermediate to Advanced

    This course continues from AWS CloudFormation Step by Step: Beginner to Intermediate and teaches you more advanced topics like cross-stack references and nested stacks, helper scripts, stack policies, custom resources, stack drifts, and deploying serverless resources with AWS Serverless Application Model and so on. It includes cross-stack references and nested stacks in detail with hands-on examples. As you may have guessed already, for this course, finishing the beginner-level course or knowing all its topics is a prerequisite.

    You can check the course page and enroll with a special discount using this link: Join AWS CloudFormation Step by Step: Intermediate to Advanced on Udemy!

I organized these courses to help you learn AWS CloudFormation in detail step by step. So, I recommend finishing the beginner-level course first and continuing with the advanced course afterward for a better experience.

See you in my AWS CloudFormation courses!

References

Cross-stack References vs Nested Stacks
Emre Yilmaz

AWS Consultant • Instructor • Founder @ Shikisoft

Follow