Functions
Terragrunt allows you to use built-in functions anywhere in terragrunt.hcl, just like OpenTofu/Terraform!
OpenTofu/Terraform built-in functions
Section titled “OpenTofu/Terraform built-in functions”All OpenTofu/Terraform built-in functions (as of v0.15.3) are supported in Terragrunt config files:
terraform { source = "../modules/${basename(get_terragrunt_dir())}"}
remote_state { backend = "s3" config = { bucket = trimspace(" my-tofu-bucket ") region = join("-", ["us", "east", "1"]) key = format("%s/tofu.tfstate", path_relative_to_include()) }}Note: Any file* functions (file, fileexists, filebase64, etc.) are relative to the directory containing the terragrunt.hcl file they’re used in.
Given the following structure:
Directoryterragrunt
- common.tfvars
Directoryassets
Directorymysql
- assets.txt
- terragrunt.hcl
Then assets.txt could be read with the following function call:
file("assets/mysql/assets.txt")Note:
Terragrunt was originally able to take advantage of built-in OpenTofu/Terraform built-in functions automatically, as they were exposed via an exported package. Since v0.15.3, however, these functions are now internal to the respective codebases.
As a result, Terragrunt users typically use different functions to resolve the same problems. e.g. Terragrunt users can execute arbitrary shell commands with run_cmd in whatever language they like instead of using a bespoke HCL function to solve a given problem. In the future, OpenTofu may expose these functions via a public package, which would allow Terragrunt to access them directly. Until such a time, Terragrunt will continue to provide its own set of functions to solve problems relevant to Terragrunt users.
If there is a specific function you would like to see supported directly in Terragrunt, please open an issue requesting it. Make sure to include the use case you have in mind so we can understand the problem you are trying to solve, and why existing Terragrunt functions are not sufficient.
find_in_parent_folders
Section titled “find_in_parent_folders”find_in_parent_folders searches up the directory tree from the current terragrunt.hcl file, and returns the absolute path to the first file in a parent folder with a given name, or exits with an error if no such file is found. This is primarily useful in an include block to automatically find the path to a parent Terragrunt configuration:
include "root" { path = find_in_parent_folders("root.hcl")}The function can also be used to find parent folders.
include "root" { path = find_in_parent_folders("some")}You can also pass an optional second fallback parameter, which causes the function to return the fallback value (instead of exiting with an error) if the file in the name parameter cannot be found:
include "root" { path = find_in_parent_folders("some-other-file-name.hcl", "fallback.hcl")}Note that this function searches relative to the terragrunt.hcl file when called from a parent config. For
example, if you had the following folder structure:
- root.hcl
Directoryprod
- env.hcl
Directorymysql
- terragrunt.hcl
And the root root.hcl contained the following:
locals { env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))}The find_in_parent_folders will search from the child terragrunt.hcl (prod/mysql/terragrunt.hcl) config,
finding the env.hcl file in the prod directory.
NOTE: This function has undocumented behavior that has since been deprecated. To learn more about this, see the Migrating from root terragrunt.hcl guide.
path_relative_to_include
Section titled “path_relative_to_include”path_relative_to_include() returns the relative path between the current terragrunt.hcl file and the path specified in its include block. For example, consider the following folder structure:
- root.hcl
Directoryprod
Directorymysql
- terragrunt.hcl
Directorystage
Directorymysql
- terragrunt.hcl
Imagine prod/mysql/terragrunt.hcl and stage/mysql/terragrunt.hcl include all settings from the root root.hcl file:
include "root" { path = find_in_parent_folders("root.hcl")}The root root.hcl can use the path_relative_to_include() in its remote_state configuration to ensure each child stores its remote state at a different key:
remote_state { backend = "s3" config = { bucket = "my-tofu-bucket" region = "us-east-1" key = "${path_relative_to_include()}/tofu.tfstate" }}The resulting key will be prod/mysql/tofu.tfstate for the prod mysql module and stage/mysql/tofu.tfstate for the stage mysql module.
If you have include blocks, this function requires a name parameter when used in the child config to specify which
include block to base the relative path on.
Example:
include "root" { path = find_in_parent_folders("root.hcl")}
include "region" { path = find_in_parent_folders("region.hcl")}
terraform { source = "../modules/${path_relative_to_include("root")}"}path_relative_from_include
Section titled “path_relative_from_include”path_relative_from_include() returns the relative path between the path specified in its include block and the current terragrunt.hcl file (it is the counterpart of path_relative_to_include()). For example, consider the following folder structure:
Directorysources
Directorymysql
- *.tf
Directorysecrets
Directorymysql
- *.tf
Directoryterragrunt
- root.hcl
- common.tfvars
Directorymysql
- terragrunt.hcl
Directorysecrets
Directorymysql
- terragrunt.hcl
Imagine terragrunt/mysql/terragrunt.hcl and terragrunt/secrets/mysql/terragrunt.hcl include all settings from the root root.hcl file:
include "root" { path = find_in_parent_folders("root.hcl")}The root root.hcl can use the path_relative_from_include() in combination with path_relative_to_include() in its source configuration to retrieve the relative OpenTofu/Terraform source code from the terragrunt configuration file:
terraform { source = "${path_relative_from_include()}/../sources//${path_relative_to_include()}"}The resulting source will be ../../sources//mysql for mysql module and ../../../sources//secrets/mysql for secrets/mysql module.
Another use case would be to add an extra argument to include the common.tfvars file for all subdirectories:
terraform { extra_arguments "common_var" { commands = [ "apply", "plan", "import", "push", "refresh" ]
arguments = [ "-var-file=${get_terragrunt_dir()}/${path_relative_from_include()}/common.tfvars", ] }}This allows proper retrieval of the common.tfvars from whatever the level of subdirectories we have.
If you have include blocks, this function requires a name parameter when used in the child config to specify which
include block to base the relative path on.
Example:
include "root" { path = find_in_parent_folders("root.hcl")}
include "region" { path = find_in_parent_folders("region.hcl")}
terraform { source = "../modules/${path_relative_from_include("root")}"}get_env
Section titled “get_env”get_env(NAME) return the value of variable named NAME or throws exceptions if that variable is not set. Example:
remote_state { backend = "s3" config = { bucket = get_env("BUCKET") }}get_env(NAME, DEFAULT) returns the value of the environment variable named NAME or DEFAULT if that environment variable is not set. Example:
remote_state { backend = "s3" config = { bucket = get_env("BUCKET", "my-tofu-bucket") }}Note that OpenTofu/Terraform will read environment variables that start with the prefix TF_VAR_, so one way to share a variable named foo between OpenTofu/Terraform and Terragrunt is to set its value as the environment variable TF_VAR_foo and to read that value in using this get_env() built-in function.
get_platform
Section titled “get_platform”get_platform() returns the current Operating System. Example:
inputs = { platform = get_platform()}This function can also be used in a comparison to evaluate what to do based on the current operating system. Example:
output "platform" { value = var.platform == "darwin" ? "(value for MacOS)" : "(value for other OS's)"}Some of the returned values can be:
darwinfreebsdlinuxwindows
get_repo_root
Section titled “get_repo_root”get_repo_root() returns the absolute path to the root of the Git repository:
inputs { very_important_config = "${get_repo_root()}/config/strawberries.conf"}This function will error if the file is not located in a Git repository.
get_path_from_repo_root
Section titled “get_path_from_repo_root”get_path_from_repo_root() returns the path from the root of the Git repository to the current directory:
remote_state { backend = "s3"
config = { bucket = "tofu" dynamodb_table = "tofu" encrypt = true key = "${get_path_from_repo_root()}/tofu.tfstate" session_name = "tofu" region = "us-east-1" }}This function will error if the file is not located in a Git repository.
get_path_to_repo_root
Section titled “get_path_to_repo_root”get_path_to_repo_root() returns the relative path to the root of the Git repository:
terraform { source = "${get_path_to_repo_root()}//modules/example"}This function will error if the file is not located in a Git repository.
get_terragrunt_dir
Section titled “get_terragrunt_dir”get_terragrunt_dir() returns the directory where the Terragrunt configuration file (by default terragrunt.hcl) lives. This is useful when you need to use relative paths with remote OpenTofu/Terraform configurations and you want those paths relative to your Terragrunt configuration file and not relative to the temporary directory where Terragrunt downloads the code.
For example, imagine you have the following file structure:
- common.tfvars
Directoryfrontend-app
- terragrunt.hcl
Inside tofu-code/frontend-app/terragrunt.hcl you might try to write code that looks like this:
terraform { source = "git::git@github.com:foo/modules.git//frontend-app?ref=v0.0.3"
extra_arguments "custom_vars" { commands = [ "apply", "plan", "import", "push", "refresh" ]
arguments = [ "-var-file=../common.tfvars" # Note: This relative path will NOT work correctly! ] }}Note how the source parameter is set, so Terragrunt will download the frontend-app code from the modules repo into a temporary folder and run tofu/terraform in that temporary folder. Note also that there is an extra_arguments block that is trying to allow the frontend-app to read some shared variables from a common.tfvars file. Unfortunately, the relative path (../common.tfvars) won’t work, as it will be relative to the temporary folder! Moreover, you can’t use an absolute path, or the code won’t work on any of your teammates’ computers.
To make the relative path work, you need to use get_terragrunt_dir() to combine the path with the folder where the terragrunt.hcl file lives:
terraform { source = "git::git@github.com:foo/modules.git//frontend-app?ref=v0.0.3"
extra_arguments "custom_vars" { commands = [ "apply", "plan", "import", "push", "refresh" ]
# With the get_terragrunt_dir() function, you can use relative paths! arguments = [ "-var-file=${get_terragrunt_dir()}/../common.tfvars" ] }}get_working_dir
Section titled “get_working_dir”get_working_dir() returns the absolute path where Terragrunt runs OpenTofu/Terraform commands. This is useful when you need to manage substitutions of vars inside a *.tfvars file located right inside terragrunt’s tmp dir.
get_parent_terragrunt_dir
Section titled “get_parent_terragrunt_dir”get_parent_terragrunt_dir() returns the absolute directory where the Terragrunt parent configuration file lives (regardless of what it’s called). This is useful when you need to use relative paths with remote OpenTofu/Terraform configurations and you want those paths relative to your parent Terragrunt configuration file and not relative to the temporary directory where Terragrunt downloads the code.
This function is very similar to get_terragrunt_dir() except it returns the root instead of the leaf of your terragrunt configurations.
- root.hcl
- common.tfvars
Directoryapp1
- terragrunt.hcl
Directorytests
Directoryapp2
- terragrunt.hcl
Directoryapp3
- terragrunt.hcl
terraform { extra_arguments "common_vars" { commands = [ "apply", "plan", "import", "push", "refresh" ]
arguments = [ "-var-file=${get_parent_terragrunt_dir()}/common.tfvars" ] }}The common.tfvars located in the root folder will be included by all applications, whatever their relative location to the root.
If you have include blocks, this function requires a name parameter when used in the child config to specify which
include block to base the parent dir on.
Example:
include "root" { path = find_in_parent_folders("root.hcl")}
include "region" { path = find_in_parent_folders("region.hcl")}
terraform { source = "${get_parent_terragrunt_dir("root")}/modules/vpc"}get_original_terragrunt_dir
Section titled “get_original_terragrunt_dir”get_original_terragrunt_dir() returns the directory where the original Terragrunt configuration file (by default
terragrunt.hcl) lives. This is primarily useful when one Terragrunt config is being read from another: e.g., if
/tofu-code/terragrunt.hcl calls read_terragrunt_config("/foo/bar.hcl"), and within bar.hcl, you call
get_original_terragrunt_dir(), you’ll get back /tofu-code.
get_terraform_commands_that_need_vars
Section titled “get_terraform_commands_that_need_vars”get_terraform_commands_that_need_vars() returns the list of OpenTofu/Terraform commands that accept -var and -var-file parameters. This function is used when defining extra_arguments.
terraform { extra_arguments "common_var" { commands = get_terraform_commands_that_need_vars() arguments = ["-var-file=${get_aws_account_id()}.tfvars"] }}get_terraform_commands_that_need_input
Section titled “get_terraform_commands_that_need_input”get_terraform_commands_that_need_input() returns the list of OpenTofu/Terraform commands that accept the -input=(true or false) parameter. This function is used when defining extra_arguments.
terraform { # Force OpenTofu/Terraform to not ask for input value if some variables are undefined. extra_arguments "disable_input" { commands = get_terraform_commands_that_need_input() arguments = ["-input=false"] }}get_terraform_commands_that_need_locking
Section titled “get_terraform_commands_that_need_locking”get_terraform_commands_that_need_locking() returns the list of terraform commands that accept the -lock-timeout parameter. This function is used when defining extra_arguments.
terraform { # Force OpenTofu/Terraform to keep trying to acquire a lock for up to 20 minutes if someone else already has the lock extra_arguments "retry_lock" { commands = get_terraform_commands_that_need_locking() arguments = ["-lock-timeout=20m"] }}get_terraform_commands_that_need_parallelism
Section titled “get_terraform_commands_that_need_parallelism”get_terraform_commands_that_need_parallelism() returns the list of terraform commands that accept the -parallelism parameter. This function is used when defining extra_arguments.
terraform { # Force OpenTofu/Terraform to run with reduced parallelism extra_arguments "parallelism" { commands = get_terraform_commands_that_need_parallelism() arguments = ["-parallelism=5"] }}get_aws_account_alias
Section titled “get_aws_account_alias”get_aws_account_alias() returns the AWS account alias associated with the current set of credentials. If the alias cannot be found, it will return an empty string. Example:
inputs = { account_alias = get_aws_account_alias()}Note: value returned by get_aws_account_alias() can change during parsing of HCL code, for example after evaluation of iam_role attribute.
get_aws_account_id
Section titled “get_aws_account_id”get_aws_account_id() returns the AWS account id associated with the current set of credentials. Example:
remote_state { backend = "s3" config = { bucket = "mycompany-${get_aws_account_id()}" }}Note: value returned by get_aws_account_id() can change during parsing of HCL code, for example after evaluation of iam_role attribute.
get_aws_caller_identity_arn
Section titled “get_aws_caller_identity_arn”get_aws_caller_identity_arn() returns the ARN of the AWS identity associated with the current set of credentials. Example:
inputs = { caller_arn = get_aws_caller_identity_arn()}Note: value returned by get_aws_caller_identity_arn() can change during parsing of HCL code, for example after evaluation of iam_role attribute.
get_terraform_command
Section titled “get_terraform_command”get_terraform_command() returns the current terraform command in execution. Example:
inputs = { current_command = get_terraform_command()}get_terraform_cli_args
Section titled “get_terraform_cli_args”get_terraform_cli_args() returns cli args for the current terraform command in execution. Example:
inputs = { current_cli_args = get_terraform_cli_args()}get_default_retryable_errors
Section titled “get_default_retryable_errors”get_default_retryable_errors() returns the default list of retryable error patterns Terragrunt uses for transient failures. Use it within the errors block to seed a retry configuration.
errors { retry "default_errors" { retryable_errors = get_default_retryable_errors() max_attempts = 3 sleep_interval_sec = 5 }
retry "custom_errors" { retryable_errors = [".*my custom error.*"] max_attempts = 5 sleep_interval_sec = 10 }}get_aws_caller_identity_user_id
Section titled “get_aws_caller_identity_user_id”get_aws_caller_identity_user_id() returns the UserId of the AWS identity associated with the current set of credentials. Example:
inputs = { caller_user_id = get_aws_caller_identity_user_id()}This allows uniqueness of the storage bucket per AWS account (since bucket name must be globally unique).
It is also possible to configure variables specifically based on the account used:
terraform { extra_arguments "common_var" { commands = get_terraform_commands_that_need_vars() arguments = ["-var-file=${get_aws_account_id()}.tfvars"] }}Note: value returned by get_aws_caller_identity_user_id() can change during parsing of HCL code, for example after evaluation of iam_role attribute.
run_cmd
Section titled “run_cmd”run_cmd(command, arg1, arg2…) runs a shell command and returns the stdout as the result of the interpolation. The command is executed at the same folder as the terragrunt.hcl file. This is useful whenever you want to dynamically fill in arbitrary information in your Terragrunt configuration.
Basic Usage
Section titled “Basic Usage”As an example, you could write a script that determines the bucket and DynamoDB table name based on the AWS account, instead of hardcoding the name of every account:
remote_state { backend = "s3" config = { bucket = run_cmd("./get_names.sh", "bucket") dynamodb_table = run_cmd("./get_names.sh", "dynamodb") }}Special Parameters
Section titled “Special Parameters”The run_cmd function accepts some special flags that can alter how the function evaluates commands on your behalf. Placing these --terragrunt- prefixed flags as the first argument(s) of a run_cmd call will result in the behavior of run_cmd being adjusted. You can mix and match the flags in any order, so long as they precede the command you are running with run_cmd.
| Parameter | Description | Example |
|---|---|---|
--terragrunt-quiet | Redacts run_cmd stdout from Terragrunt logs while still returning the value to HCL. This keeps sensitive information out of log files. | run_cmd("--terragrunt-quiet", "./decrypt_secret.sh", "foo") |
--terragrunt-global-cache | Stores and reuses results in a global cache so the command only runs once per set of arguments, no matter which configuration references it. Useful when the output is directory-independent. | run_cmd("--terragrunt-global-cache", "aws", "sts", "get-caller-identity", "--query", "Account", "--output", "text") |
--terragrunt-no-cache | Skips the cache entirely and forces the command to run on every evaluation. Use this when the output changes frequently (timestamps, tokens, random IDs, etc.). | run_cmd("--terragrunt-no-cache", "date", "+%s") |
Terragrunt caches run_cmd results by default to avoid running the same command multiple times during parsing. The cache key includes the directory of the terragrunt.hcl file and the command arguments unless you opt into global caching or disable caching entirely.
Parameters --terragrunt-global-cache and --terragrunt-no-cache are mutually exclusive, Terragrunt will return an error if both are provided.
Examples
Section titled “Examples”Suppress output for sensitive values:
# Output is redacted in logs, but still available to Terragruntsuper_secret_value = run_cmd("--terragrunt-quiet", "./decrypt_secret.sh", "foo")Note: This will prevent terragrunt from displaying the output from the command in its output. However, the value could still be displayed in the OpenTofu/Terraform output if OpenTofu/Terraform does not treat it as a sensitive value.
Use global cache for directory-independent commands:
# Same result regardless of which directory run_cmd is called fromaccount_id = run_cmd("--terragrunt-global-cache", "aws", "sts", "get-caller-identity", "--query", "Account", "--output", "text")Disable caching for dynamic values:
# Generates a new UUID every time run_cmd is evaluatedbuild_id = run_cmd("--terragrunt-no-cache", "uuidgen")
# Gets current timestamp on each parse of the Terragrunt configurationtimestamp = run_cmd("--terragrunt-no-cache", "date", "+%s")Combine multiple parameters:
# Disable cache AND suppress output for a sensitive dynamic valuesession_token = run_cmd("--terragrunt-no-cache", "--terragrunt-quiet", "./generate-temp-token.sh")
### Caching Behavior
By default, invocations of `run_cmd` are cached based on the current directory and executed command, so cached values are reused later rather than executed multiple times. Here's an example:
```hcl# terragrunt.hcl
locals { uuid = run_cmd("echo", "uuid1", uuid()) uuid2 = run_cmd("echo", "uuid2", uuid()) uuid3 = run_cmd("echo", "uuid3", uuid()) potato = run_cmd("echo", "potato") potato2 = run_cmd("echo", "potato") carrot = run_cmd("echo", "carrot")}inputs = { potato3 = run_cmd("echo", "potato") uuid3 = run_cmd("echo", "uuid3", uuid()) uuid4 = run_cmd("echo", "uuid4", uuid()) carrot2 = run_cmd("echo", "carrot")}Output:
$ terragrunt inituuid1 b48379e1-924d-2403-8789-c72d50be964cuuid1 9f3a8398-b11f-5314-7783-dad176ee487duuid1 649ac501-e5db-c935-1499-c59fb7a75625uuid2 2d65972b-3fa9-181f-64fe-dcd574d944d0uuid3 e345de60-9cfa-0455-79b7-af0d053a15a5potatouuid3 7f90a4ed-96e3-1dd8-5fee-91b8c8e07650uuid2 8638fe79-c589-bebd-2a2a-3e6b96f7fc34uuid3 310d0447-f0a6-3f67-efda-e6b1521fa1fbuuid4 f8e80cc6-1892-8db7-bd63-6089fef00c01uuid2 289ff371-8021-54c6-2254-72de9d11392auuid3 baa19863-1d99-e0ef-11f2-ede830d1c58acarrotKey observations from the output:
carrotandpotatoappear once because subsequent invocations used cached valuesuuid1,uuid2, anduuid3appear multiple times because each call touuid()generates a different cache keyuuid3appears one extra time because it’s declared in bothlocalsandinputsuuid4appears once since it’s declared ininputs, which is evaluated once
This caching behavior can be modified using the special parameters described in the Special Parameters section above.
read_terragrunt_config
Section titled “read_terragrunt_config”read_terragrunt_config(config_path, [default_val]) parses the terragrunt config at the given path and serializes the
result into a map that can be used to reference the values of the parsed config. This function will expose all blocks
and attributes of a terragrunt config.
For example, suppose you had a config file called common.hcl that contains common input variables:
inputs = { stack_name = "staging" account_id = "1234567890"}You can read these inputs in another config by using read_terragrunt_config, and merge them into the inputs:
locals { common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))}
inputs = merge( local.common_vars.inputs, { # additional inputs })This function also takes in an optional second parameter which will be returned if the file does not exist:
locals { common_vars = read_terragrunt_config(find_in_parent_folders("i-dont-exist.hcl", "i-dont-exist.hcl"), {inputs = {}})}
inputs = merge( local.common_vars.inputs, # This will be {} { # additional inputs })Note that this function will also render dependency blocks. That is, the parsed config will make the outputs of the
dependency blocks available. For example, suppose you had the following config in a file called common_deps.hcl:
dependency "vpc" { config_path = "${get_terragrunt_dir()}/../vpc"}You can access the outputs of the vpc dependency through the parsed outputs of read_terragrunt_config:
locals { common_deps = read_terragrunt_config(find_in_parent_folders("common_deps.hcl"))}
inputs = { vpc_id = local.common_deps.dependency.vpc.outputs.vpc_id}Notes:
read_terragrunt_configcan be also used to readterragrunt.stack.hclandterragrunt.values.hclfiles.
sops_decrypt_file
Section titled “sops_decrypt_file”sops_decrypt_file(file_path) decrypts a yaml, json, ini, env or “raw text” file encrypted with sops.
sops is an editor of encrypted files that supports YAML, JSON, ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, Hashicorp Vault and PGP.
This allows static secrets to be stored encrypted within your Terragrunt repository.
For example, suppose you have some static secrets required to bootstrap your
infrastructure in secrets.yaml, you can decrypt and merge them into the inputs
by using sops_decrypt_file:
locals { secret_vars = yamldecode(sops_decrypt_file(find_in_parent_folders("secrets.yaml")))}
inputs = merge( local.secret_vars, { # additional inputs })If you absolutely need to fallback to a default value you can make use of the OpenTofu/Terraform try function:
locals { secret_vars = try(jsondecode(sops_decrypt_file(find_in_parent_folders("no-secrets-here.json"))), {})}
inputs = merge( local.secret_vars, # This will be {} { # additional inputs })get_terragrunt_source_cli_flag
Section titled “get_terragrunt_source_cli_flag”get_terragrunt_source_cli_flag() returns the value passed in via the CLI --source or an environment variable TG_SOURCE. Note that this will return an empty string when either of those values are not provided.
This is useful for constructing before and after hooks, or TF flags that only apply to local development (e.g., setting up debug flags, or adjusting the iam_role parameter).
Some example use cases are:
- Setting debug logging when doing local development.
- Adjusting the kubernetes provider configuration so that it targets minikube instead of real clusters.
- Providing special mocks pulled in from the local dev source (e.g., something like
mock_outputs = jsondecode(file("${get_terragrunt_source_cli_arg()}/dependency_mocks/vpc.json"))).
read_tfvars_file
Section titled “read_tfvars_file”read_tfvars_file(file_path) reads a .tfvars or .tfvars.json file and returns a map of the variables defined in it.
This is useful for reading variables from a .tfvars file, merging them into the inputs, or using them in a locals block:
locals { inputs_from_tfvars = jsondecode(read_tfvars_file("common.tfvars"))}
inputs = merge( local.inputs_from_tfvars, { # additional inputs })Another example:
locals { backend = jsondecode(read_tfvars_file("backend.tfvars"))}
remote_state { backend = "s3" config = { bucket = "${get_env("TG_BUCKET_PREFIX", "tf-bucket")}-${get_aws_account_id()}" key = "${path_relative_to_include()}/terraform-${local.aws_region}.tfstate" region = local.backend.region } generate = { path = "backend.tf" if_exists = "overwrite_terragrunt" }}mark_as_read
Section titled “mark_as_read”mark_as_read(file_path) marks a file as read so that it can be picked up for inclusion by the queue-include-units-reading flag.
This is useful for situations when you want to mark a file as read, but are not reading it using a native Terragrunt HCL function.
For example:
locals { filename = mark_as_read("/path/to/my/file-read-by-tofu.txt") many_files = [for f in fileset("./config", "*.yaml") : file(mark_as_read(abspath("${get_terragrunt_dir()}/config/${f}")))]}
inputs = { filename = local.filename many_files = local.many_files}By using mark_as_read on file-read-by-tofu.txt, you can ensure that the terragrunt.hcl file passing in the file-read-by-tofu.txt file as an input will be included in
any run --all run where the flag --queue-include-units-reading file-read-by-tofu.txt is set.
The same technique can be used to mark a file as read when a file is read using code in run_cmd.
NOTE: Due to the way that Terragrunt enqueues files we require an absolute path for mark_as_read to avoid multiple inclusions.
NOTE: Due to the way that Terragrunt parses configurations during a run --all, functions will only properly mark files as read
if they are used in the locals block. Reading a file directly in the inputs block will not mark the file as read, as the inputs
block is not evaluated until after the queue has been populated with units to run.
constraint_check
Section titled “constraint_check”constraint_check(version, constraint) checks if a given version satisfies a given constraint.
This particularly is useful for situations where you want to change the runtime behavior of Terragrunt based on the version of an OpenTofu/Terraform module.
For example:
feature "module_version" { default = "1.2.3"}
locals { module_version = feature.module_version.value needs_v2_adjustments = constraint_check(local.module_version, ">= 2.0.0")}
terraform { source = "github.com/my-org/my-module.git//?ref=v${local.module_version}"}
inputs = !local.needs_v2_adjustments ? { old_module_input_name = "old_module_input_value"} : { new_module_input_name = "new_module_input_value"}In this example, the v2.0.0 version of the module made a breaking change to rename an input variable from old_module_input_name to new_module_input_name.
Instead of carefully coordinating the version update with the corresponding input change, users can set a feature flag to control opt-in of the new module version, and have Terragrunt dynamically adjust the input variable name based on the constraint check, that the module version is greater than or equal to 2.0.0.
The HCL function supports all the same constraints that you can use for version constraints in terragrunt_version_constraint and terraform_version_constraint.