CloudFormation failed because it couldn’t create resources in the order you specified, as two or more resources were waiting for each other to be created first.

Here’s how to diagnose and fix those circular dependency errors:

1. Identify the Circular Dependency:

CloudFormation usually points out the specific resources involved in the error message. Look for lines like:

CREATE_FAILED Resource creation cancelled by "w-XXXXXXXXXX" ("Circular dependency between ...")

The key is to note the names of the two (or more) resources mentioned. Let’s say it’s ResourceA and ResourceB.

2. Analyze the Dependencies:

The most common cause is an explicit DependsOn attribute. Check the CloudFormation template for both ResourceA and ResourceB.

  • If ResourceA has DependsOn: [ResourceB] AND ResourceB has DependsOn: [ResourceA]: This is the most straightforward circular dependency.
    • Diagnosis: Examine your template for these explicit DependsOn entries.
    • Fix: Remove one of the DependsOn attributes. For example, if ResourceA doesn’t truly need ResourceB to exist first (or vice-versa), remove the DependsOn from ResourceA targeting ResourceB. CloudFormation will then try to create them in parallel or in an order determined by implicit dependencies.
    • Why it works: Removing the explicit loop allows CloudFormation’s dependency resolver to break the cycle and determine a valid creation order.

3. Implicit Dependencies via Resource Attributes:

Often, dependencies aren’t explicit but implied when one resource’s creation depends on an attribute output by another.

  • Scenario: ResourceA needs the ARN of ResourceB (e.g., a security group ID for a network interface), and ResourceB needs to know about ResourceA (e.g., an EC2 instance needs to be launched into a subnet created by ResourceA).
    • Diagnosis: Look for references like !GetAtt ResourceB.Arn or !Ref ResourceB within the properties of ResourceA, and similarly, !GetAtt ResourceA.SubnetId or !Ref ResourceA within the properties of ResourceB.
    • Fix: Re-evaluate the actual order of operations. Is it always true that ResourceA must exist before ResourceB and ResourceB must exist before ResourceA? Usually, one direction is the true dependency. If ResourceA (e.g., a VPC) must exist before ResourceB (e.g., a Subnet), ensure ResourceB references ResourceA but ResourceA does not explicitly or implicitly reference ResourceB. If ResourceB also needs to know about ResourceA in a way that creates a loop, you might need to split these into two separate CloudFormation stacks that are then chained together, or use a custom resource to provide a value.
    • Why it works: By identifying the primary dependency (e.g., VPC must exist before Subnet) and removing the reverse, you break the circular logic. CloudFormation can then infer the correct order.

4. Cross-Stack References (Less Common for Direct Circularity, but Related):

If you’re using CloudFormation StackSets or nested stacks, a circular dependency can occur if Stack A depends on Stack B, and Stack B depends on Stack A.

  • Diagnosis: Review the Stack or StackSet resources in your templates. See which stack references which.
  • Fix: Restructure your stacks. You cannot have two stacks that directly depend on each other. You’ll need to identify a "root" stack that doesn’t depend on anything else in the cycle, or break the dependency into a third, intermediate stack.
  • Why it works: Similar to single-stack dependencies, the cycle must be broken by establishing a clear linear or branching dependency graph.

5. IAM Roles and Policies:

Sometimes, a circular dependency can manifest indirectly through IAM roles.

  • Scenario: ResourceA (e.g., an EC2 instance) needs an IAM role that grants permissions to ResourceB (e.g., an S3 bucket). ResourceB (the S3 bucket) might have a bucket policy that grants permissions back to ResourceA’s instance profile.
    • Diagnosis: Check the Policies or AssumeRolePolicyDocument for IAM roles associated with ResourceA and ResourceB. Look for cross-resource permissions.
    • Fix: Avoid granting reciprocal permissions directly within CloudFormation definitions that create a loop. If ResourceA needs to write to ResourceB, grant that permission. If ResourceB truly needs to allow ResourceA to access it, that’s often implicitly handled by the service itself when ResourceA attempts access with its valid role. If a bucket policy is involved, ensure it doesn’t grant access based on the existence of ResourceA in a way that ResourceA’s role depends on ResourceB’s policy.
    • Why it works: IAM policies are evaluated at runtime. CloudFormation’s dependency resolver primarily looks at creation-time attributes. By ensuring the IAM permissions don’t create a creation-time dependency loop, you resolve the issue.

6. Resource Naming and Ref Logical IDs:

Ensure you aren’t accidentally creating logical conflicts or misreferencing resources.

  • Diagnosis: Double-check all Ref and !GetAtt functions. Ensure the logical IDs you’re referencing actually exist in your template and are spelled correctly. A typo could lead CloudFormation to believe a resource depends on a non-existent one, which can sometimes manifest as dependency errors.
  • Fix: Correct any typos in logical IDs or resource references.
  • Why it works: Correct references ensure CloudFormation understands the actual relationships between resources.

7. Custom Resources and Lambda Functions:

If you’re using Custom Resources that trigger Lambda functions, a circular dependency can arise if the Lambda function needs permissions from a resource that the Custom Resource is waiting to create.

  • Diagnosis: Examine the Properties of your AWS::CloudFormation::CustomResource and the IAM role associated with the Lambda function. Trace the dependencies.
  • Fix: Ensure the IAM role for the Lambda function has all necessary permissions before the Custom Resource is invoked. This might mean defining the role in a separate template or ensuring its permissions don’t rely on resources created by the Custom Resource itself.
  • Why it works: Custom Resources are treated as resources by CloudFormation. Their execution and the Lambda function’s permissions must be resolvable without creating a loop.

After fixing the dependency, the next error you might encounter is a permissions issue if the corrected order reveals that the IAM role for one of the resources still lacks the necessary permissions to perform its operation on another resource.

Want structured learning?

Take the full Cloudformation course →