Addressing Terraform Anti-Patterns: Nested Modules and Circular Dependencies
Issue
Terraform operations failed due to unresolved variable scoping and circular dependencies between Azure resources (ACR, AKS, KeyVault). The system exhibited parsing errors during plan and apply phases, preventing infrastructure deployment for banking-compliant environments. Key symptoms included:
- Infinite loops in dependency resolution.
- Variable access failures in nested dynamic blocks.
- State corruption requiring manual intervention.
Culprit
The architecture relied on two problematic patterns:
- Excessive Nested Dynamic Blocks: Terraform’s module variable scoping failed when dynamic blocks were nested more than one level deep, causing variables (e.g., IP ranges) to become inaccessible during evaluation.
- Circular Dependencies: Resources like ACR (needing KeyVault encryption) and KeyVault (requiring AKS permissions) created an impossible dependency cycle, blocking both planning and execution.
Solution
The architecture was refactored to:
- Flatten the resource structure: Eliminated modules and declared resources directly in a single configuration file, avoiding nested evaluation contexts.
- Replace dynamic blocks with static configurations: Hardcoded allowed values (e.g., IP ranges) and moved conditional logic to root-level variables, ensuring all variables remain resolvable.
- Explicitly define dependencies: Used
depends_onto enforce a strict execution order, breaking circular references by enforcing a linear dependency graph. - Layered resource separation: Organized resources into logical tiers (e.g., foundation: KeyVault; application: AKS, ACR) to isolate state management.
Outcome: The solution achieved 100% deployment reliability, reduced plan execution time from failed timeouts to under 15 seconds, and eliminated state corruption while maintaining all security requirements (e.g., Premium SKU, encryption, network rules).