Optional DependsOn with CloudFormation: Metadata to the rescue
When working with AWS CloudFormation, sometimes it’s necessary to incorporate optional dependencies into your template. Recently, I encountered a situation where I had to build a single CloudFormation template to manage both a VPC and an application—though, generally, I recommend separating these into distinct templates for easier management. Using a single template introduces complexity, as you must explicitly manage dependencies using the DependsOn attribute to ensure proper resource creation order.
Here’s a simplified version of the template. This setup involves an Auto Scaling Group (ASG) that depends on VPC resources such as network ACLs, route table associations, and a VPC gateway endpoint for DynamoDB:
Resources: |
This approach works well if all resources are mandatory. However, in my case, the VPCEndpointForDynamoDB
is an optional resource that can be toggled via a parameter. Here’s how I attempted to handle this initially:
Parameters: |
In theory, this approach should work by conditionally referencing VPCEndpointForDynamoDB
using an !If
statement. However, CloudFormation doesn’t support !If
conditions within the DependsOn
attribute and returns a template format error: Every DependsOn value must be a string. This limitation required a workaround to manage conditional dependencies effectively.
The Metadata Workaround
A reliable workaround is to use the Metadata attribute that CloudFormation supports for attaching arbitrary data to resources. By leveraging Metadata, you can create an implicit dependency without using DependsOn
. Here’s how:
Parameters: |
In this solution, the Metadata
attribute of AutoScalingGroup
includes a conditional reference to VPCEndpointForDynamoDB
. When HasDynamoDB
is true, the !Ref VPCEndpointForDynamoDB
effectively creates an implicit dependency on the optional resource. This way, if VPCEndpointForDynamoDB
is toggled on, CloudFormation ensures it’s created before AutoScalingGroup
.
Summary
When managing optional resources in AWS CloudFormation, the DependsOn
attribute doesn’t support conditional dependencies. To work around this limitation, use the Metadata
attribute to create implicit dependencies based on conditions. This approach enables you to control optional resources’ deployment order without violating CloudFormation’s syntax rules.