Cleaner CloudFormation Tip w/ Nested Stacks

Senior Brogrammer
AWS Tip
Published in
3 min readDec 31, 2021

--

Nested Stacks are fairly old as a technology but I see several templates that could utilize this more. The main tip with nested stacks I can give is balancing out the amount of parameters and replicating a logical amount of resources. Ideally, implementing one of these will reduce the number of lines a template will have which makes additions/changes a lot easier down the line.

Reference: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html

Condition Based Values

The common problem amongst many templates is that 1 or 2 values that need to be added based on the unique setup. This usually pops up when you need an extra environment variable, name a specific item, or adding SSL for a connection. Now an initial approach would be to grab the nested stack, duplicate and add the following, but as developers we can do better.

Let’s look at the following example of a simple stack that contains a lambda and SNS topic that a queue subscribes to. The template is below:

AWSTemplateFormatVersion: '2010-09-09'
Parameters:
QueueArn:
Type: String
TopicName:
Type: String
LambdaName:
Type: String
Resources:
Function:
Type: AWS::Lambda::Function
Properties:
Name: !Ref LambdaName
Handler: index.handler
Environment:
Variables:
TopicArn: !Ref SNSTopic
Role: arn:aws:iam::123456789012:role/lambda-role
Code:
S3Bucket: my-bucket
S3Key: function.zip
Runtime: nodejs12.x
Timeout: 5
SNSTopic:
Type: AWS::SNS::Topic
Properties:
Subscription:
- Endpoint: !Ref QueueArn
Protocol: "sqs"
TopicName: !Ref TopicName

As we look at this template it’s very simple (not realistic), with a lambda that submits data to a unique SNS topic for it. Now we pass in two parameters and we could spin up hundreds of these as we need them, but let’s change one thing. A use case comes up that one of the lambdas needs another environment variable outside of the topic name.

One can simply do something like below:

Environment:
Variables:
TopicArn: !Ref SNSTopic
UniqueKey: UniqueVar

However, this means that every lambda has access to this variable which could have unintended issues. So let’s give this only to the specific lambda using a condition:

Conditions:
IsUniqueLambda: !Equals [!Ref LambdaName, "UniqueLambda"]

Then do the following:

Environment:
Variables:
TopicArn: !Ref SNSTopic
UniqueKey: !If [IsUniqueLambda, "UniqueVar", !Ref AWS::NoValue]

Now let’s review, this is an oddball case that we might run into for a unique lambda that only needs access to a certain environment variable. This should be treated as the exception for the rule and not a growing solution. This solution shouldn’t entail adding 500 environment variables just to make things “unique”. Remember that we are trying to add a single variable not modify the entire setup.

Note: If we wanted to expand on this we could change things for environments which is a common use of conditions to build out the stacks correctly, but have the templates organized well.

The idea behind using AWS no value is the omit items we don’t need and this could be applied in several different ways, but keep a nested stack setup instead of duplication.

--

--