How to fix Error: Template directives are not allowed in dynamic blocks in Terraform

TerraformINTERMEDIATEMEDIUMUpdated Dec 30, 2025ยท 122 views

This error occurs when you try to use Terraform template directives (like %{for}, %{if}) inside a dynamic block. Dynamic blocks use their own for_each iteration mechanism and don't support template syntax. The fix is to remove template directives and use dynamic block expressions instead.

Quick fix

Fixes Error: Template directives are not allowed in dynamic blocks

# WRONG - Template directive in dynamic block
dynamic "ingress" {
  for_each = var.rules
  content {
    description = "%{ if ingress.value.add_desc }Custom rule%{ endif }"
  }
}
  1. Identify the template directive in your dynamic block
  2. Replace template directives with conditional expressions
  3. Use Terraform expressions for iteration logic
  4. Verify your syntax by running terraform validate
terraform โ€” error
# WRONG - Template directive in dynamic block
dynamic "ingress" {
for_each = var.rules
content {
description = "%{ if ingress.value.add_desc }Custom rule%{ endif }"
}
}
Error: Template directives are not allowed in dynamic blocks

What this error means

Terraform has two separate mechanisms for iteration and conditional logic: dynamic blocks and template directives. Dynamic blocks (using for_each) generate nested configuration blocks, while template directives (%{for}, %{if}) work inside string templates (heredocs and quoted strings). These two systems cannot be mixed. When you try to include template directives inside a dynamic block's content, Terraform rejects them because dynamic blocks process their iteration at a different stage of configuration parsing than template expressions. The dynamic block's for_each and iterator are the proper way to handle repetition within resource configuration.

Typical symptoms

  • Terraform plan or apply fails with 'Template directives are not allowed in dynamic blocks' error
  • Error points to a specific line within a dynamic block's content section
  • Configuration contains %{for}, %{if}, or %{endif} inside a dynamic block
  • Works correctly when the same logic is in a regular string template or heredoc outside a dynamic block

Common causes

  1. Attempting to use template directives (%{for}, %{if}, %{endfor}, %{endif}) within a dynamic block's content instead of using the dynamic block's native for_each iteration
  2. Misunderstanding the difference between dynamic block iteration and template string directives
  3. Trying to apply conditional logic inside a dynamic block using template syntax instead of conditional expressions

How to fix "Error: Template directives are not allowed in dynamic blocks"

1Identify the template directive in your dynamic block

Look for the error message line number and examine your dynamic block for any %{ syntax:

hcl
# WRONG - Template directive in dynamic block
dynamic "ingress" {
  for_each = var.rules
  content {
    description = "%{ if ingress.value.add_desc }Custom rule%{ endif }"
  }
}

The %{ if } and %{ endif } are template directives and are not allowed here.

2Replace template directives with conditional expressions

Use Terraform's native conditional operator (condition ? true_val : false_val) inside the dynamic block's content:

hcl
# CORRECT - Use conditional expression
dynamic "ingress" {
  for_each = var.rules
  content {
    description = ingress.value.add_desc ? "Custom rule" : ""
  }
}

This achieves the same result without template directives.

3Use Terraform expressions for iteration logic

If you need to process or transform data before using it in the dynamic block, use Terraform functions like map(), filter(), or list comprehension within the for_each argument itself:

hcl
# Transform data before dynamic block processes it
dynamic "ingress" {
  for_each = [for rule in var.rules : rule if rule.enabled]
  content {
    from_port   = ingress.value.from_port
    to_port     = ingress.value.to_port
    protocol    = ingress.value.protocol
  }
}

This keeps all iteration logic in the dynamic block where it belongs.

4Verify your syntax by running terraform validate

After making changes, validate your configuration to ensure no errors remain:

bash
terraform validate

This will confirm that your dynamic block syntax is correct and that template directives have been properly removed or replaced with conditional expressions.

Advanced notes

Template directives are specifically designed for string template processing and work best in heredocs and regular string interpolations. Dynamic blocks are meant for resource configuration generation and have their own expression evaluation rules.

If you need complex templating logic, consider using local values or temporary variables to pre-process your data before passing it to a dynamic block. This keeps your code cleaner and avoids mixing iteration mechanisms.

Related Terraform features: locals, for expressions (list/map comprehensions), conditional operators, and function transformations like map() and flatten() can all help you achieve complex logic without template directives in dynamic blocks.

Frequently asked questions

What does "Error: Template directives are not allowed in dynamic blocks" mean?
Terraform has two separate mechanisms for iteration and conditional logic: dynamic blocks and template directives. Dynamic blocks (using for_each) generate nested configuration blocks, while template directives (%{for}, %{if}) work inside string templates (heredocs and quoted strings). These two systems cannot be mixed.
How do I fix "Error: Template directives are not allowed in dynamic blocks"?
This error occurs when you try to use Terraform template directives (like %{for}, %{if}) inside a dynamic block. Dynamic blocks use their own for_each iteration mechanism and don't support template syntax. The fix is to remove template directives and use dynamic block expressions instead.
What causes "Error: Template directives are not allowed in dynamic blocks"?
Attempting to use template directives (%{for}, %{if}, %{endfor}, %{endif}) within a dynamic block's content instead of using the dynamic block's native for_each iteration Misunderstanding the difference between dynamic block iteration and template string directives Trying to apply conditional logic inside a dynamic block using template syntax instead of conditional expressions
Is the "Error: Template directives are not allowed in dynamic blocks" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading