Some time ago AWS released a feature for CloudFormation called Cross-Stack References. Cross-stack references are very useful when you have parameters or resources that you need to reference in other stacks. This is extremely helpful because you can make your CloudFormation stacks much more modular and easier to maintain. For example, typically when creating infrastructure you would need to create VPC, subnet, route table, NACL, load balancer, EC2 instance, and database resources all in one CloudFormation stack.
With Cross-stack references you can create separate stacks for network resources, application resources, databases, etc. They can also be very useful when integrating with an existing environment or CloudFormation template, as you can retrieve VPC IDs, Subnet IDs, etc. and use them within a new stack. Cross-stack references save a lot of manual work, where previously you would need to look up all the IDs needed and add them to parameters or create Lambda functions to retrieve the IDs.
Cross-stack references are created by adding an “Export” declaration to a normal CloudFormation stack output and using a new built-in function to access them. That new function, Fn::ImportValue, does have a few restrictions that are important to note if you are setting out to create your first cross-stack reference with it. Namely, the export names must be unique within an account and region; the function will not allow you to create references across regions. In addition, AWS will not allow you to delete a stack that is being referenced by another stack and your outputs cannot be changed or removed while they are being referenced by a stack.
There is one problem with cross-stack references: when your infrastructure is fairly complex–with multiple stacks and many references within those stacks–it can be very difficult to see and understand all the connections and references. Then, when it comes time to make changes to a resource or reference it can be hard to see where those changes will have an impact.
To solve the problems with complex cross-stack references, I fell back to my tried and trusted friends–data, analysis, and visualization. In this case not much analysis was needed. All that was needed was a way to get data about all the cross-stack references, and then a way to visualize them.
Getting the Data
To get the necessary data I used the AWS Python SDK Boto3. I first hit the AWS account and retrieved all the CloudFormation exports and the name of the template from which they are being exported. I then iterated over all those exports and retrieved all the places where they were being imported and the name of that template. I then wrote the output to a json file that will be used for the visualization, which can be found here.
D3 and the Sankey Diagram
The code for the visuals can be found here. The interactive visualizations can be seen here, and below are example screen shots of each of the visualizations.
Summary and Conclusions
In the end, a customer can see the complete relationships between all the stacks in their environment. So far the most useful feature has been to see when there are exports that are not being used and to remove them to make the cross-stack references more efficient and easier to maintain. The other thing that this may be useful for is to see an overall picture of your AWS infrastructure and how things are related within it.
Some future considerations:
- Better color coding of the nodes. For instance, one color to denote stacks and another color to denote exports.
- A drop down to select only the stacks that you want to see. This would be especially helpful when the number of stacks deployed gets very large.