Back to all blog posts

10 Biggest Pitfalls of Terraform

Terraform, a popular tool in Infrastructure as Code (IaC), faces challenges with managing multiple environments and scaling, leading to complex and error-prone setups. Terramate, a new CLI tool, addresses these issues by introducing stack concepts, global variables, and code generation to simplify environment management and reduce code complexity. It improves upon Terraform's limitations in versioning, backend configuration, and resource lifecycle management, offering a more streamlined and flexible approach for complex infrastructure management. Terramate's innovative features enhance efficiency and control, making it a valuable addition to the IaC toolset.

Sören Martius
Sören Martius
· 9 min read
10 Biggest Pitfalls of Terraform

Terraform (or OpenTofu if you prefer open source) has emerged as a pivotal player in the evolving Infrastructure as Code (IaC) landscape, facilitating the management and provision of cloud resources through code. However, like any tool, it has drawbacks and tradeoffs. Challenges such as managing multiple environments with workspaces, maintaining module versions and backend configurations, and managing resource lifecycles often make Terraform code hard to read and prone to errors. Moreover, scaling can be cumbersome due to a lack of stack concept, leading to complications in more intricate environments.

Before diving in, why not join the Terramate Community on Discord ? Meet and chat with fellow community members, ask Terramate questions and stay informed about new product releases, community events, and more!

Enter Terramate CLI , a solution designed to address the limitations of Terraform. It leverages features such as global variables and code generation to simplify the management of different environments and reduce code complexity. Terramate introduces the concept of stacks and orchestration , providing more flexibility and control when managing complex environments. It also offers advanced capabilities for merging maps and objects, significantly improving the management of complex configurations.

This article explores the challenges posed by Terraform and how Terramate rises to meet them. Understanding the strengths and weaknesses of both tools can help developers and operators select the one that best aligns with their specific needs and environments, ultimately enhancing the efficiency and simplicity of infrastructure management.

1. Terraform Workspaces

Terraform Workspaces help you manage different environments, like staging, development, and production. However, they can be tricky to handle. For example, the code can be difficult to understand because you have to use the count parameter a lot to create resources based on conditions. Also, it gets harder when you want to scale or grow with Terraform Workspaces because you need to add more connections between them when managing different environments.

On the other hand, there’s an alternative with Terramate. It has a feature called global variables , making changes specific to each environment easier. This reduces the complexity of your code and makes it easier to read.

2. Maintaining Module Versions

In Terraform, a feature called the module block lets users use pre-set modules. But there's a problem with this block. The source and version attributes in this block, which are used to specify where the module comes from and which version of the module to use, don't allow for variable interpolation. Variable interpolation is replacing a placeholder in a string with its actual value. This limitation can cause trouble when you're trying to set up modules in a flexible or dynamic way.

Terramate provides a solution to this problem with its code generation feature. This feature lets users create static or unchanging code from dynamic configurations. This includes configurations in the source and version attributes, which means you can dynamically configure modules more effectively.

3. Hardcoding Backend Configuration

When you’re working with Terraform, you might need to make copies of Root Modules, but this can cause unexpected problems if you’re not careful with the backend configuration. The backend configuration is where Terraform stores information about your infrastructure. If you copy the backend configuration without changing the key or prefix (which identifies the location of the stored information), it can cause problems. For example, you might end up with destructive Terraform Plans, which can potentially damage your infrastructure if the wrong state file (a file that keeps track of the status of your infrastructure) is referenced.

Terramate has a feature that can help avoid this issue. Its code generation feature can create a different state configuration based on the stack ID for each stack. This means that each stack has its unique state configuration, preventing problems that can occur when the wrong state file is referenced.

4. Provider Config

With Terraform, managing the provider configuration involves a lot of repetitive coding and manual work. The provider configuration is part of the code that tells Terraform how to interact with the service you’re using, like AWS or Google Cloud. Duplicating and manually managing this code can lead to mistakes and waste time.

Here’s where Terramate can make things easier with its code generation feature. This feature can take a simple user configuration and generate more complicated provider configurations. This simplifies managing the provider configuration and reduces the duplicate code you need to write.

5. Version Pinning in Providers and Terraform

Version pinning is a practice where you specify the exact versions of providers and Terraform you want to use. Providers are the services that Terraform interacts with, like AWS or Google Cloud. This is important because it ensures that everyone is using the same versions, which can prevent issues that arise if different versions are used. You can do this by hardcoding the versions into your configurations or using Terraform lockfiles. But, using lockfiles can get complicated because you need to create them for different system architectures.

Terramate offers a solution to this with its code generation feature. It can easily pin or fix versions. Moreover, its global variables feature can even support using different versions for different environments. This means you can use one version of Terraform or a Provider in your staging environment and a different version in your production environment. This gives you more flexibility and control over your setups.

6. Lifecycle Management of Resources in Terraform Modules

In Terraform, there’s something called lifecycle configuration. This helps manage how your resources, like virtual machines or databases, are created, updated, and deleted. However, there’s a limitation to this. It only allows for literal usage, which means you can’t use modules (pre-set pieces of code) to help protect your resources from being accidentally destroyed. A specific rule called prevent_destroy stops resources from being deleted, but you can't use this rule in modules.

But Terramate provides a way around this. It can generate resources that include lifecycle rules, adding an extra safety layer. This means you can have more control over your resources and better protect them from accidental deletion.

7. Missing Stack Concept

Terraform is unique in the world of IaC tools because it doesn’t have a stack concept. A stack is a collection of resources that are managed together. Instead, Terraform only focuses on what’s happening within a single directory, a root module. This can cause problems when dealing with bigger, more complex environments because it’s not designed to handle multiple collections of resources at once.

Terramate has introduced the idea of a Stack and orchestration to tackle this issue. Orchestration is the process of automating and coordinating complex tasks. With this feature, you have more control and flexibility when managing complex environments because you can manage multiple collections of resources more effectively.

8. Code Duplication

In Terraform, when you want to use a module (which is a pre-set piece of code) multiple times, you have to copy the call to the module and the arguments (the specific instructions you give to the module) each time. This leads to repeated code, making your codebase larger and harder to maintain.

Terramate offers a solution to this problem with its Code Generation feature. This feature creates the necessary blocks of code based on your configurations. This means you don’t have to repeat the same blocks of code multiple times, which reduces code duplication and makes your code more efficient.

9. Monostacks

If you’re managing a lot of resources (like virtual machines, databases, etc.) in Terraform, it can cause some problems. For example, if something goes wrong, it could affect many of your resources (this is known as a “big blast radius”). Also, executing plans and applying changes can take a long time when dealing with many resources. Additionally, if there are discrepancies or “drifts” in a single resource, it can prevent you from applying new changes.

Terramate helps tackle these issues by dividing resources into different stacks , which are groups of resources managed together. It also provides easy orchestration, which is the automation and coordination of complex tasks. This approach reduces the potential impact if something goes wrong (reducing the blast radius) and decreases the time it takes to build or apply changes. This ultimately improves team productivity by making the management of resources more efficient.

10. Deep Merging of Maps and Objects

In Terraform, merging or combining maps and objects at multiple levels, also known as “deep merging”, is not allowed. A map is a collection of key-value pairs, and an object is a complex structure containing multiple data types. This limitation makes it hard to merge default configurations with user inputs. For instance, it’s difficult to create keys or attributes that conflict, and changing the value of an attribute in a nested structure is impossible.

Terramate, however, offers solutions to these issues. It includes a map block that lets you set rules for managing conflicts when merging maps. Terramate lets you overwrite deep attributes while keeping the existing object intact. This means you can extend or change a group of attributes using its Labeled Globals feature. This feature allows you to label and manage global variables, making it easier to manage complex configurations.


Terraform has played a key role in popularizing the concept of Infrastructure as Code, where you manage your IT infrastructure using code. However, it’s not without its challenges. These include issues like code that is hard to read, difficulty scaling with workspaces, problems maintaining versions of modules, the need to hardcode backend configurations and the complexity of managing the lifecycle of resources.

Terramate is designed to tackle these problems. It has features like global variables and code generation that simplify infrastructure management. It introduces the stack concept, which provides more control and flexibility. It also has advanced capabilities for merging maps and objects, making managing complex configurations easier.

By understanding the strengths and weaknesses of these tools, developers and operators can pick the one best suited to their specific needs and environments. This can make managing your infrastructure more straightforward and efficient.

Soren is the co-founder and Chief Executive Officer at Terramate. Prior to founding Terramate, he consulted companies such as Flink, 1Komma5 and Nothing to design and implement cloud- and internal developer platforms.