The terraform block configures how Terragrunt runs OpenTofu/Terraform: where to get the module, which files to copy into the working directory, extra CLI arguments, and commands to run before and after tofu/terraform.
With a source, Terragrunt downloads the module into .terragrunt-cache, copies the unit’s directory into the same place, and runs tofu/terraform there. It skips hidden files and directories in the copy unless include_in_copy names them.
Module sources
A tfr:// source pulls a module from a module registry, in the form tfr://REGISTRY_HOST/MODULE_SOURCE[?version=VERSION]:
Without ?version= or a version attribute, Terragrunt downloads the latest stable version. Pin a version for reproducible runs.
tfr:/// with three slashes uses the default registry: registry.opentofu.org for OpenTofu, and registry.terraform.io for Terraform. When Terragrunt can’t tell which one it runs, it uses registry.opentofu.org. Set TG_TF_DEFAULT_REGISTRY_HOST to use another host.
// selects a submodule, e.g. tfr:///terraform-aws-modules/iam/aws//modules/iam-policy?version=4.3.0.
For a private registry, set TG_TF_REGISTRY_TOKEN to an API token for it.
An oci:// source pulls a module from an OCI registry, in the form oci://REGISTRY_HOST/REPOSITORY[//SUBDIR][?tag=TAG|?digest=DIGEST], e.g. oci://ghcr.io/acme/terraform-modules/vpc?tag=1.0.0. Without a tag or digest, Terragrunt uses the latest tag. See OCI registries.
Version constraints
The version attribute resolves a tfr:// source against the registry’s list of versions:
It applies to tfr:// sources only. Setting it with any other source is an error, and so is also setting ?version= in the source.
The --source flag and TG_SOURCE replace version along with source. They take an exact ?version= only, not a constraint.
Terragrunt checks the registry on every run, so it downloads a newly published version that satisfies the constraint without --source-update.
A prerelease qualifies only when the constraint names one, e.g. >= 2.0.0-rc1, as in OpenTofu/Terraform.
Hook commands
Besides tofu/terraform commands, a hook’s commands can name three stages of a Terragrunt run: terragrunt-read-config, init-from-module, and init. Running terragrunt plan on a unit with a source runs hooks in this order:
When a stage fails, Terragrunt runs that stage’s after hooks that set run_on_error = true, then its error_hook blocks whose on_errors match the error. An error_hook with init-from-module catches download errors.
terragrunt-read-config and init-from-module hooks run in the unit’s directory, and other hooks in the directory Terragrunt runs OpenTofu/Terraform in.
A note about using modules from the registry
Terragrunt runs shared service modules as root modules. OpenTofu/Terraform modules fall into two groups:
A root module is one you run tofu init and tofu apply in directly. It has the blocks that configure OpenTofu/Terraform, such as backend and provider blocks.
A shared module is one other modules call through module blocks. It lacks those blocks.
Terragrunt splits shared modules in two:
A shared service module deploys on its own once something adds the backend and provider blocks, e.g. terraform-aws-modules/vpc.
Terragrunt generates the missing blocks to run a shared service module as a root module. Most registry modules are shared modules meant for composition, so Terragrunt can’t always deploy them. Two limitations block the conversion:
Every complex variable needs a type, or OpenTofu/Terraform reads the input Terragrunt passes as a string. This includes lists and maps.
Derived sensitive outputs must be marked sensitive. See sensitive variables.
If a registry module fails to deploy with Terragrunt, open an issue on the Terragrunt repository with the module and the error message, rather than on the module’s repository.
Attributes
sourceoptional(string)
Where to fetch the OpenTofu/Terraform module from. It takes the same syntax as an OpenTofu/Terraform module source, e.g. a local path or a Git URL with a ref, plus tfr:// registry sources and oci:// sources. Terragrunt downloads the whole repository, the part before //, so relative paths between modules in it keep working. See Module sources.
A version constraint for a tfr:// source, in the same syntax as the version argument of an OpenTofu/Terraform module block. Terragrunt downloads the highest published version that satisfies it. See Version constraints.
Glob patterns for files to copy into the OpenTofu/Terraform working directory that Terragrunt would otherwise skip, e.g. hidden files such as .python-version. Patterns are relative to the source directory. With the symlinks experiment, a pattern can name a symlinked directory, and Terragrunt copies the link target’s contents. It skips a link that points back at a directory it’s already copying, or at a parent of one, and logs a warning.
terragrunt.hcl
terraform {
source ="../modules/networking/vpc"
include_in_copy =[
".security_group_rules.json",
"*.yaml",
]
}
exclude_from_copyoptional(list(string))
Glob patterns for files in the unit’s directory that Terragrunt skips when it copies them into the OpenTofu/Terraform working directory. A file that matches both this and include_in_copy is skipped. To keep files from the module source out of the working directory, use a before_hook.
terragrunt.hcl
terraform {
source ="../modules/networking/vpc"
exclude_from_copy =["*.md"]
}
copy_terraform_lock_fileoptional(bool, true)
Copies the .terraform.lock.hcl file from the OpenTofu/Terraform working directory back to the unit’s directory. Set it to false to keep the lock file out of the unit’s directory, e.g. when you don’t commit it. See Lock files.
terragrunt.hcl
terraform {
source ="../modules/networking/vpc"
copy_terraform_lock_file =false
}
no_dot_terragrunt_cacheoptional(bool, false)
Runs OpenTofu/Terraform in the unit’s directory instead of a copy in .terragrunt-cache. Files a run creates stay in the unit’s directory. Setting it with source or --source is an error. It needs the no-dot-terragrunt-cache experiment.
terragrunt.hcl
terraform {
no_dot_terragrunt_cache =true
}
update_source_with_casoptional(bool, false)
Lets a catalog’s terragrunt.hcl give source as a path relative to the catalog. Terragrunt rewrites it to a reference into its content-addressable store. See CAS integration.
units/service/terragrunt.hcl
terraform {
source ="../..//modules/service"
update_source_with_cas =true
}
mutableoptional(bool, false)
Makes the files Terragrunt copies from its content-addressable store into .terragrunt-cache writable. Terragrunt writes them read-only by default, so an edit can’t reach the shared store. It has no effect when Terragrunt fetches the source without the store, which already writes a separate, writable copy.
Runs a command before tofu/terraform runs one of the commands you list. Hooks run in the order you declare them. See Hooks.
namelabel
Names the hook in Terragrunt’s log output.
commandslist(string)
The tofu/terraform commands to run the hook before. It also takes the hook commandsinit-from-module and init.
executelist(string)
The command to run and its arguments, e.g. ["echo", "Foo"] runs echo Foo.
working_diroptional(string)
The directory to run the command in. Defaults to the directory Terragrunt runs OpenTofu/Terraform in, or the unit’s directory for an init-from-module hook.
run_on_erroroptional(bool, false)
Runs the hook even when an earlier hook failed.
suppress_stdoutoptional(bool, false)
Hides the command’s standard output, e.g. when a script parses OpenTofu/Terraform’s output.
ifoptional(bool, true)
Skips the hook when false.
terragrunt.hcl
terraform {
before_hook "fmt" {
commands =["apply", "plan"]
execute =["tofu", "fmt", "-check"]
}
}
after_hookafter_hook "<name>" { … }
Runs a command after tofu/terraform runs one of the commands you list. Hooks run in the order you declare them. See Hooks.
namelabel
Names the hook in Terragrunt’s log output.
commandslist(string)
The tofu/terraform commands to run the hook after. It also takes the hook commandsterragrunt-read-config, init-from-module, and init.
executelist(string)
The command to run and its arguments, e.g. ["echo", "Foo"] runs echo Foo.
working_diroptional(string)
The directory to run the command in. Defaults to the directory Terragrunt runs OpenTofu/Terraform in, or the unit’s directory for a terragrunt-read-config or init-from-module hook.
run_on_erroroptional(bool, false)
Runs the hook even when an earlier hook or the tofu/terraform command failed.
suppress_stdoutoptional(bool, false)
Hides the command’s standard output, e.g. when a script parses OpenTofu/Terraform’s output.
ifoptional(bool, true)
Skips the hook when false.
terragrunt.hcl
terraform {
after_hook "notify" {
commands =["apply"]
execute =["./scripts/notify.sh"]
run_on_error =true
}
}
error_hookerror_hook "<name>" { … }
Runs a command when tofu/terraform fails with an error that matches one of on_errors. Error hooks run after the before and after hooks.
namelabel
Names the hook in Terragrunt’s log output.
commandslist(string)
The tofu/terraform commands whose errors trigger the hook. Use init-from-module to catch errors while Terragrunt downloads source.
executelist(string)
The command to run and its arguments.
on_errorslist(string)
Regular expressions matched against the error message, e.g. [".*"] for any error.
working_diroptional(string)
The directory to run the command in. Defaults to the directory Terragrunt runs OpenTofu/Terraform in.