Migrating from Deprecated Attributes
This guide explains how to migrate from the deprecated skip and retryable_errors attributes to their modern, more powerful replacements.
Overview
Section titled “Overview”Terragrunt has deprecated two attributes in favor of more flexible block-based configurations:
skip→ Use theexcludeblock insteadretryable_errors→ Use theerrorsblock withretrysub-blocks instead
These new blocks provide more granular control and composability compared to the simple attributes they replace.
Migrating from skip to exclude
Section titled “Migrating from skip to exclude”Why was skip deprecated?
Section titled “Why was skip deprecated?”The skip attribute was a simple boolean that would exclude a unit from the run queue. The new exclude block provides much more flexibility:
- Exclude the unit only for specific OpenTofu/Terraform commands (e.g., only
planbut notapply) - Use conditional logic to determine when to exclude the unit
- Combine multiple conditions
- Better integration with other Terragrunt features
Basic Migration
Section titled “Basic Migration”Before:
skip = trueAfter:
exclude { if = true actions = ["all"]}Conditional Skip
Section titled “Conditional Skip”Before:
skip = get_env("ENVIRONMENT") == "production"After:
exclude { if = get_env("ENVIRONMENT") == "production" actions = ["all"]}Skip Specific Actions
Section titled “Skip Specific Actions”The new exclude block allows you to exclude the unit only for specific OpenTofu/Terraform commands:
exclude { if = get_env("SKIP_DESTROY") == "true" actions = ["destroy"]}This wasn’t possible with the old skip attribute!
Migrating from retryable_errors to errors Block
Section titled “Migrating from retryable_errors to errors Block”Why was retryable_errors deprecated?
Section titled “Why was retryable_errors deprecated?”The retryable_errors attribute was a simple list of error patterns. The new errors block with retry sub-blocks provides:
- Multiple retry configurations with different patterns and settings
- Named retry blocks for better documentation
- Per-retry configuration of max attempts and sleep intervals
- Composability - combine multiple retry strategies
- Better organization for complex retry logic
Basic Migration
Section titled “Basic Migration”Before:
retryable_errors = [ ".*Error: transient network issue.*", ".*Error: timeout.*"]
retry_max_attempts = 3retry_sleep_interval_sec = 5After:
errors { retry "transient_errors" { retryable_errors = [ ".*Error: transient network issue.*", ".*Error: timeout.*" ] max_attempts = 3 sleep_interval_sec = 5 }}Using Default Retryable Errors
Section titled “Using Default Retryable Errors”If you were using the get_default_retryable_errors() function:
Before:
retryable_errors = concat( get_default_retryable_errors(), [".*custom error.*"])After:
errors { retry "default_errors" { retryable_errors = get_default_retryable_errors() max_attempts = 3 sleep_interval_sec = 5 }
retry "custom_errors" { retryable_errors = [".*custom error.*"] max_attempts = 5 sleep_interval_sec = 10 }}Note: The get_default_retryable_errors() function still works and returns the default list for use within the errors block.
Multiple Retry Strategies
Section titled “Multiple Retry Strategies”The new errors block allows you to define different retry strategies for different types of errors:
errors { # Quick retries for transient network issues retry "network_errors" { retryable_errors = [ ".*connection reset.*", ".*timeout.*" ] max_attempts = 5 sleep_interval_sec = 2 }
# Slower retries for rate limiting retry "rate_limit_errors" { retryable_errors = [ ".*rate limit exceeded.*", ".*too many requests.*" ] max_attempts = 10 sleep_interval_sec = 30 }
# Few retries for potential transient API issues retry "api_errors" { retryable_errors = [ ".*internal server error.*" ] max_attempts = 3 sleep_interval_sec = 15 }}This level of granularity wasn’t possible with the old retryable_errors attribute!
Error Messages
Section titled “Error Messages”If you try to use the deprecated attributes, Terragrunt will fail with an HCL parsing error:
For skip attribute:
Error: Unsupported argument
on terragrunt.hcl line 2: 2: skip = true
An argument named "skip" is not expected here.For retryable_errors attribute:
Error: Unsupported argument
on terragrunt.hcl line 4: 4: retryable_errors = [".*Error: transient.*"]
An argument named "retryable_errors" is not expected here.These errors indicate that the attributes have been completely removed from Terragrunt. Please refer to the migration examples below.
How Retry Errors Are Collected
Section titled “How Retry Errors Are Collected”When you define multiple retry blocks within the errors block, Terragrunt automatically collects all the retryable_errors patterns from all retry blocks and uses them for error matching.
Example:
errors { retry "network_errors" { retryable_errors = [".*timeout.*", ".*connection reset.*"] max_attempts = 5 sleep_interval_sec = 2 }
retry "api_errors" { retryable_errors = [".*rate limit.*", ".*429.*"] max_attempts = 10 sleep_interval_sec = 30 }}In this example, Terragrunt will retry on any error matching:
.*timeout.*.*connection reset.*.*rate limit.*.*429.*
Each retry block can have its own max_attempts and sleep_interval_sec,
allowing fine-grained control over retry behavior for different error types—for example,
one block can retry at 2-second intervals while another uses 30-second intervals.