Choosing Terramate Code Generation vs Manual Modules for DRY Terraform
Guide to deciding when to use Terramate's code generation for DRY Terraform, with a comparison table, trade‑offs, and a step‑by‑step validation example.
06 Jul 2025, 08:55 UTC

Decision and constraints
When you need to keep Terraform configuration DRY across many stacks, you can either let Terramate generate the files from a template or maintain the code yourself with modules or Terragrunt patterns. The decision hinges on:
- Stack metadata must live in a
terramate.hclfile. - The
generateblock must be enabled in that file. - Terramate CLI version 0.10 or newer is required for the
generatecommand.
Supported options comparison
| Option | Ease of use | Duplication | Learning curve |
|---|---|---|---|
Terramate generate with HCL templating | High – one command creates files | Low – template drives all stacks | Medium – learn Terramate syntax |
| Manual Terraform modules | Medium – write and call modules | Medium – risk of drift if versions differ | Low – standard Terraform |
| Terragrunt include/exclude patterns | Medium – extra Terragrunt file | Low – patterns reuse code | Medium – learn Terragrunt |
Trade‑offs
Using Terramate’s code generation reduces boilerplate and guarantees that provider/backend blocks are identical in every generated file. The trade‑off is an additional build step and a dependency on the Terramate CLI. Manual modules avoid extra tooling but can lead to version drift and repetitive module calls. Terragrunt gives pattern‑based reuse but adds another layer of configuration to maintain.
Concrete implementation and validation
Create a stack directory with a
terramate.hclfile that defines the generation:# terramate.hcl terraform { # optional backend/provider config can go here } # Enable code generation generate { path = "generated/main.tf" template = "templates/main.tftpl" }Place your HCL template (e.g.,
templates/main.tftpl) in the same directory. A simple template might look like:# templates/main.tftpl provider "aws" { region = "{{ .var.region }}" } resource "aws_instance" "example" { ami = "{{ .var.ami }}" instance_type = "{{ .var.instance_type }}" }Run the generation step (requires read/write permission on the workspace):
terramate generateAfter execution, verify that
generated/main.tfappears and contains the rendered template.Initialize and validate the generated Terraform code:
terraform init terraform planIf the plan shows the expected resources (e.g., an AWS instance), the generation succeeded.
Limitations and practical checks
- Terramate < 0.10 will error on
generate; runterramate versionfirst. - Generated files are overwritten on each run; manual edits will be lost unless you add an
ignorepattern toterramate.hcl. - To confirm the result, compare the output of
terraform planbefore and after a change to the template; the plan should reflect only the intended differences.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.