Have you ever run terraform apply
expecting a smooth deployment only to get hit with a cryptic dependency cycle error? Or maybe Terraform says, “No changes,” but you know your infrastructure is broken?
You’re not alone.
In this blog, we’ll troubleshoot two common but tricky Terraform issues:
Terraform Apply Fails with Dependency Cycle — How to Fix It
Terraform Plan Diff Shows No Change, But Infra is Broken
Let’s dive in.
Terraform Apply Fails with Dependency Cycle
The Problem
You're working with a multi-module Terraform project. You run terraform apply, and then… BAM
Error: Cycle: module.network.aws_vpc.main, module.compute.aws_instance.web, module.network.aws_route_table_association.assoc
You stare at the screen. What is this cycle? Why now?
What’s Going On?
Terraform builds a directed acyclic graph (DAG) to determine what resources to create or modify. If there's a loop in dependencies, Terraform can't resolve it, and it throws a cycle error.
A Real-World Example
Say you have:
A
network
a module that creates a VPC and associates route tablesA
compute
a module that spins up EC2 instances
If the EC2 instance depends on a subnet (from network
), but the subnet association references the instance’s private IP (for some custom routing logic), you’ve unintentionally created a cycle.
How to Fix It
1. Visualize the Graph
Run:
terraform plan -graph | dot -Tsvg > graph.svg
Open the SVG and trace the dependency loop.
2. Refactor Cross-Dependencies
Decouple tightly coupled modules. Can you replace references with variables or data sources?
3. Use depends_on
Intelligently
Avoid relying on Terraform’s implicit dependencies. Be explicit where necessary.
4. Split State or Apply Order
In some cases, separating modules into different state files (or separate Terraform runs) helps isolate issues.
Terraform Says No Changes, But Infra Is Broken
The Problem
You deploy via terraform apply, and Terraform tells you:
No changes. Infrastructure is up-to-date.
…but your AWS EC2 instance is in stopped
state. Or worse, someone deleted it manually.
Why This Happens
Terraform believes what its state file says. If the real infrastructure has changed outside Terraform, it won’t be known unless you explicitly refresh or compare.
This is called infrastructure drift.
Common Scenarios
Someone manually edited resources in the AWS console
A resource was deleted manually
Auto-scaling replaced a node, and Terraform doesn’t track it
Provider bugs or outdated state
How to Fix It
1. Detect Drift with terraform apply -refresh-only
In Terraform 1.1+, run:
terraform apply -refresh-only
This refreshes the state with the current cloud state and lets you see differences.
2. Use Drift Detection Tools
DriftCTL – Compare Terraform state with live infra
Infracost diff – Understand cost-impacting drifts
3. Force a Resource Recreation
If something’s broken:
terraform taint aws_instance.web
terraform apply
This recreates the resource.
4. Re-import Resources
If Terraform no longer tracks a resource:
terraform import aws_instance.web i-0123456789abcdef0
5. Build Drift Checks into CI/CD
Set up drift detection in GitHub Actions or Jenkins to catch changes outside Terraform.
Congratulations, you made it till here!! Stay ahead; subscribe to the EzyInfra Knowledge Base for more DevOps wisdom.
Key Takeaways
Terraform’s power lies in its state management, but that’s also a common source of pain.
Dependency cycles can often be visualized and broken through smarter module design.
Invisible infrastructure drift is real; build systems to detect and recover from it.
Troubleshooting Terraform isn’t about memorizing fixes but understanding how Terraform thinks.
EzyInfra.dev – Expert DevOps & Infrastructure consulting! We help you set up, optimize, and manage cloud (AWS, GCP) and Kubernetes infrastructure—efficiently and cost-effectively. Need a strategy? Get a free consultation now!
Share this post