When I first got introduced to the Spring framework it allowed me to re-envision how to construct objects to work together while enabling more diverse capabilities by constructing variations of object, decoupling architecture and finally increasing test-ability and test driven development. This is accomplished through a two aspect approach. The first aspect is Interface & Object definition, the second aspect is orchestration & assembly. SOA then breaks this model out into the following layers: Consumer, Integration, Business Process, Service, Component and finally the Operational System Layers. These capabilities allowed me, and other developers, to construct adaptable SaaS (Software as a Service) systems which supported higher customization while limiting the amount of new code and maintenance required on these systems. The downside to this is that you ended up either having a monolithic service which would then be deployed multiple times or you’d end up with a lot of micro services which would then need an orchestration layer tailored to your needs.
AWS Cloudformation allows developers to spin up and connect services and infrastructure in a way which is repeatable and reliable. When I started I was trying to build my entire solutions in a single cloudformation, or separating them into segments then connecting them together through direct reference. Nesting stacks became a way to organize infrastructure into segments which were functional. What I missed what that the design pattern which opened up my ability to create highly flexible and adaptable systems was just waiting to be used.
Cloudformation’s nested stacks concept isn’t new, but it is powerful. Taking a look at your serverless infrastructure or traditional infrastructure, you can then start breaking out your micro-services into individual definitions. These definitions could be general purposes or could be custom development for a specific consumer model. Once you’ve created various definitions for these individual components the nested stack can then be used to wire these components together, or to put it another way orchestrate a specific configuration which will cause services to interact without having to be hard coded to do so.
Lets take a look at an example. Lets say you have a telecom customer portal your company provides as a SaaS offering. You have two customers. Customer A has a specific UI which provides a dashboard back to their customers, which is then connected to a middle tier customer profile service, a billing service and various others. The billing service is then tied to other services which handle payment processing, bill history, etc. Customer B is pretty much the same with a few differences around UI and they have different requirements around billing history. In a more traditional model you’d either end up putting all the configuration into the services via transforms which would have to live with the code, or you’d have to have a centralized configuration system, which I’ve built before and just add another layer of complexity and maintenance.
If leveraged correctly, cloudformation nesting can accomplish this same objective, while allowing for an even high degree of flexibility and diversity of your application. This is especially true if you leverage decoupling strategies such as SNS and SQS.
The first step is to define your services and components. In the above example we’re looking at two customer user interfaces, a business processing service, a profile service, two billing history services, a payment service and an upgrade service. Our first step is to define these services as unique cloudformations, exposing configurations, such as other services urls or Arns, as parameters. This does two things. First it ensures your component’s specific configuration is easy to read and understand as you’ve isolated it from other components, and secondly you’ve just made it possible to deploy that specific component to an environment of mock interfaces for isolated unit testing.
The second step is to actually connect your services through cloudformation nesting. Up until this point, your services needed to know the messages which they would send and receive, but wouldn’t know specifically who they were sending them to. Nesting the templates allows you to now connect the services you’ve created by referencing each other, allowing you to easily create customization, standalone deployments or even side by side systems without increasing the complexity of any single component,
While I personally see the benefit of this design pattern really applicable to the serverless world, it can be used in a more traditional infrastructure environment as well.