Terraform
Hardcoded backend configuration leads to destructive state file mismatches
9When copying root modules without updating backend configuration (key/prefix), Terraform can reference the wrong state file, resulting in destructive plans that delete infrastructure belonging to another environment or project.
Sensitive data exposure in state and plan artifacts
9Terraform stores real secret values (API tokens, database passwords) in plaintext state files and plan output despite showing (sensitive value) in the CLI. When plan files are uploaded as CI/CD artifacts, they become security liabilities if accessible to unauthorized parties.
Remote state management and concurrent write conflicts at scale
9When multiple team members and CI/CD pipelines run Terraform in parallel, concurrent writes to shared state can cause conflicting updates and painful recovery work. The terraform.tfstate file serves as the source of truth, and unreliable storage or simultaneous modifications lead to state corruption.
Unsafe plan review and hidden destructive changes in large changesets
8Terraform plans with hundreds or thousands of changes are difficult for humans to review reliably. Destructive actions (resource deletion/recreation) hide in the noise of benign changes, making it easy to miss critical issues during code review.
Resource refactoring is destructive and risky
8Renaming or reorganizing resources in Terraform code causes them to be destroyed and recreated rather than updated, risking catastrophic downtime and data loss for stateful resources like databases. There is no native refactoring capability.
Local state files without remote backends cause team collaboration and disaster recovery issues
8State files stored locally (default) instead of on remote backends (S3, GCS) prevent team collaboration, create single points of failure, and make disaster recovery impossible. Developers must manually manage state file access.
Over 50% of users experience state-related issues
7A HashiCorp survey revealed that more than half of Terraform users encounter state-related problems, indicating widespread technical complexity and inadequate state management solutions.
Missing stack concept prevents grouped resource management and scaling
7Unlike other IaC tools, Terraform lacks a stack concept for managing collections of related resources. It only operates at the root module level, making it difficult to manage large, complex environments with multiple resource groupings without custom orchestration.
Monolithic state files with large resource counts cause blast radius and performance degradation
7Managing many resources in a single Terraform state increases blast radius (a single error affects many resources), slows plan/apply execution, and prevents new changes if any resource drifts. Resource drift in one resource blocks the entire apply.
State refactoring and cross-boundary resource moves lack tooling support
7Moving resources between state files or across state boundaries is not supported by terraform mv or other built-in tools. Teams must manually edit JSON state files or write custom tooling to reorganize infrastructure across projects or environments.
Complex state logistics in CI/CD automation pipelines
7Automation pipelines and scripting struggle to handle stateful resource management and state logistics across multiple code paths, despite being critical for continuous integration.
Validation and testing capabilities are immature
7Terraform lacks a robust, built-in testing framework for HCL. Unit testing is difficult and integration testing (spinning up real infrastructure) is slow and expensive. Teams resort to embedding validation scripts or hacks, leading to accidental infrastructure drifts reaching production.
Cloud API rate limits and eventual consistency issues during large applies
7Large Terraform applies trigger API throttling (429 errors) when hitting per-account or per-region cloud provider limits. Additionally, eventually-consistent cloud services may not reflect changes immediately, causing subsequent API calls to fail or return stale data.
Difficulty incorporating existing infrastructure into Terraform
7Terraform users struggle to bring existing infrastructure stacks under management because Terraform cannot automatically incorporate them into its state without manual intervention.
Implicit dependencies and dependency graph resolution failures
7Terraform relies on explicit references to infer resource dependencies, but real-world dependencies are often implicit (side effects, plain string IDs). When Terraform cannot see these relationships, it fails to determine correct resource ordering, causing apply failures or resource conflicts.
Terraform state drift from manual cloud console changes
7Teams circumvent Terraform workflows by making changes directly in cloud provider consoles, causing state files to become out of sync with actual infrastructure. This drift prevents accurate planning and can lead to unexpected behavior during subsequent Terraform operations.
Provider versioning lock file inconsistency and reproducibility failures
7Even with version constraints in code, if the .terraform.lock.hcl file is not committed and consistently used across environments, teams experience "works on my machine" drift where different environments use different provider versions despite identical configuration.
Domain-specific language support and excessive prompt engineering required
6Working with domain-specific languages like Terraform requires excessive prompt engineering with Gemini CLI. The model struggles with DSL semantics, necessitating detailed and repetitive prompt tweaking to achieve correct results.
Terraform Business Source License creates vendor lock-in and product redistribution uncertainty
6Terraform's August 2023 BSL 1.1 license change creates legal uncertainty for organizations redistributing Terraform, embedding it in products, or offering IaC as a hosted service. The ambiguous definition of 'competitive' products triggers legal review and delays infrastructure platform roadmaps.
Module version source attribute does not support variable interpolation
6The source and version attributes in Terraform's module block reject variable interpolation, preventing dynamic module sourcing. This limitation breaks flexible, parameterized module management patterns and forces hardcoded or copy-paste module references.
Terraform core development is slow with many stalled long-term bug fix PRs
6Terraform core development moves slowly with minimal innovation, and many important long-standing PRs fixing critical bugs or adding key features languish for months without maintainer attention. In contrast, the AWS provider releases weekly but has poor core team responsiveness.
Resource sharing between teams requires paid Enterprise Terraform solutions
6Terraform community edition lacks built-in mechanisms for cross-team resource sharing, forcing organizations without Terraform Enterprise to build custom state management solutions or invest in expensive enterprise licensing.
Every organization develops different Terraform conventions and custom tooling
6Terraform's flexibility allows each team to develop unique patterns: custom modules with different naming conventions, varying CI workflows (from simple apply to 8-step pipelines), conflicting use of Terragrunt, and different apply strategies. This fragmentation creates tribal knowledge and complicates onboarding.
Lack of developer abstraction and self-service workflows
6Product teams want higher-level abstractions and self-service capabilities for infrastructure provisioning. Many teams are adopting CDKTF or building internal platforms to bridge the gap, indicating Terraform's abstraction layer is insufficient for modern development velocity.
Cloud provider vendor lock-in through provider-specific modules
6Heavy reliance on Terraform modules and resources specific to particular cloud providers can create inadvertent vendor lock-in, making migration between providers difficult and expensive.
Automation gaps prevent comprehensive infrastructure-as-code adoption
6Terraform can build secure, repeatable infrastructure landing zones, but cannot automate all required components like identity, pipelines, and secrets management, leaving gaps in the automation model.
Workspace-based multi-environment management requires excessive conditional logic
6Using Terraform workspaces to manage multiple environments (dev, staging, prod) requires heavy use of count parameters and conditional expressions, making code difficult to read and understand. Scaling across environments becomes increasingly complex as interconnections multiply.
Complex workflows with modules and multiple environments
6Complex Terraform deployments with modules, multiple environments, split state, and orchestration tools like Terragrunt create challenging issues that require structured planning and disciplined workflows.
CloudFormation lacks cross-platform compatibility
6CloudFormation is AWS-specific and not portable to other cloud providers, creating vendor lock-in. Developers prefer third-party tools like Terraform and Ansible for portability.
Terraform feels deceptively simple but hides deep complexity in real-world usage
5Initial Terraform tasks (provisioning a bucket) appear simple, but complexity emerges across backends, providers, variables, modules, environments, workspaces, and dependency management. Understanding what code actually does in production requires deep system knowledge.
Cryptic error messages and poor documentation
5Terraform error messages are often baffling, especially with complex modules or provider bugs. Documentation quality varies widely and lacks sufficient detail. Error context is insufficient for troubleshooting, making debugging slow and frustrating.
Provider configuration repetition and manual management of duplicated code
5Terraform requires manual, repetitive copy-paste of provider configuration across multiple modules and environments. This duplication increases maintenance burden and introduces errors when updating provider settings.
Long-lived branches in Terraform repos violate infrastructure best practices
5Unlike application code, infrastructure can only have one version deployed at a time. Keeping multiple long-lived branches in a Terraform repository is not common practice, limiting collaboration models and creating merge complexity.
HCL syntax is awkward and creates steep onboarding curve
5The Terraform configuration language (HCL) is unintuitive compared to standard programming languages. Concepts like conditional logic, looping with for_each, and mapping collections are unnecessarily cumbersome. Few developers have deep Terraform experience, slowing team onboarding.
Shallow merge() function prevents nested configuration composition
5Terraform's merge() function only performs shallow merging, not deep merging of nested maps and objects. This prevents clean composition of default configurations with user-supplied overrides and makes merging multi-level data structures awkward.
Monolithic file structures impede navigation and collaboration
5Cramming numerous resources, data sources, and variables into single .tf files becomes increasingly difficult to navigate, troubleshoot, and collaborate on as infrastructure expands, slowing down team productivity.