Sometimes you may need to pass extra CLI arguments every time you run certain tofu
/terraform
commands. For example, you may want to set the lock-timeout
setting to 20 minutes for all commands that may modify remote state so that OpenTofu/Terraform will keep trying to acquire a lock for up to 20 minutes if someone else already has the lock rather than immediately exiting with an error.
You can configure Terragrunt to pass specific CLI arguments for specific commands using an extra_arguments
block in your terragrunt.hcl
file:
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 = [
"init",
"apply",
"refresh",
"import",
"plan",
"taint",
"untaint"
]
arguments = [
"-lock-timeout=20m"
]
env_vars = {
TF_VAR_var_from_environment = "value"
}
}
}
Each extra_arguments
block includes an arbitrary name (in the example above, retry_lock
), a list of commands
to which the extra arguments should be added, and a list of arguments
or required_var_files
or optional_var_files
to add. You can also pass custom environment variables using env_vars
block, which stores environment variables in key value pairs. With the configuration above, when you run terragrunt apply
, Terragrunt will call OpenTofu/Terraform as follows:
$ terragrunt apply
# terraform apply -lock-timeout=20m
You can even use built-in functions such as get_terraform_commands_that_need_locking to automatically populate the list of OpenTofu/Terraform commands that need locking:
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"]
}
}
You can specify one or more extra_arguments
blocks. The arguments
in each block will be applied any time you call terragrunt
with one of the commands in the commands
list. If more than one extra_arguments
block matches a command, the arguments will be added in the order of appearance in the configuration. For example, in addition to lock settings, you may also want to pass custom -var-file
arguments to several commands:
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"]
}
# Pass custom var files to OpenTofu/Terraform
extra_arguments "custom_vars" {
commands = [
"apply",
"plan",
"import",
"push",
"refresh"
]
arguments = [
"-var", "foo=bar",
"-var", "region=us-west-1"
]
}
}
With the configuration above, when you run terragrunt apply
, Terragrunt will call OpenTofu/Terraform as follows:
$ terragrunt apply
# tofu apply -lock-timeout=20m -var foo=bar -var region=us-west-1
extra_arguments
for init
Extra arguments for the init
command have some additional behavior and constraints.
In addition to being appended to the tofu init
/terraform init
command that is run when you explicitly run terragrunt init
, extra_arguments
for init
will also be appended to the init
commands that are automatically run during other commands (see Auto-Init).
You must not specify the -from-module
option (aka. the SOURCE
argument for terraform < 0.10.0) or the DIR
argument in the extra_arguments
for init
. This option and argument will be provided automatically by terragrunt.
Here’s an example of configuring extra_arguments
for init
in an environment in which OpenTofu/Terraform plugins are manually installed, rather than relying on OpenTofu/Terraform to automatically download them.
terraform {
# ...
extra_arguments "init_args" {
commands = [
"init"
]
arguments = [
"-plugin-dir=/my/tofu/plugin/dir",
]
}
}
One common usage of extra_arguments is to include tfvars files. Instead of using arguments, it is simpler to use either required_var_files
or optional_var_files
. Both options require only to provide the list of file to include. The only difference is that required_var_files
will add the extra argument -var-file=<your file>
for each file specified and if they don’t exist, exit with an error. optional_var_files
, on the other hand, will skip over files that don’t exists. This allows many conditional configurations based on environment variables as you can see in the following example:
├── terragrunt.hcl
├── prod.tfvars
├── us-west-2.tfvars
├── backend-app
│ ├── main.tf
│ ├── dev.tfvars
│ └── terragrunt.hcl
├── frontend-app
│ ├── main.tf
│ ├── us-east-1.tfvars
│ └── terragrunt.hcl
terraform {
extra_arguments "conditional_vars" {
commands = [
"apply",
"plan",
"import",
"push",
"refresh"
]
required_var_files = [
"${get_parent_terragrunt_dir()}/tofu.tfvars"
]
optional_var_files = [
"${get_parent_terragrunt_dir()}/${get_env("TF_VAR_env", "dev")}.tfvars",
"${get_parent_terragrunt_dir()}/${get_env("TF_VAR_region", "us-east-1")}.tfvars",
"${get_terragrunt_dir()}/${get_env("TF_VAR_env", "dev")}.tfvars",
"${get_terragrunt_dir()}/${get_env("TF_VAR_region", "us-east-1")}.tfvars"
]
}
}
See the get_terragrunt_dir() and get_parent_terragrunt_dir() documentation for more details.
With the configuration above, when you run terragrunt run-all apply
, Terragrunt will call OpenTofu/Terraform as follows:
$ terragrunt run-all apply
[backend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/backend-app/dev.tfvars
[frontend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/frontend-app/us-east-1.tfvars
$ TF_VAR_env=prod terragrunt run-all apply
[backend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/prod.tfvars
[frontend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/prod.tfvars -var-file=/my/tf/frontend-app/us-east-1.tfvars
$ TF_VAR_env=prod TF_VAR_region=us-west-2 terragrunt run-all apply
[backend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/prod.tfvars -var-file=/my/tf/us-west-2.tfvars
[frontend-app] tofu apply -var-file=/my/tf/tofu.tfvars -var-file=/my/tf/prod.tfvars -var-file=/my/tf/us-west-2.tfvars
The list of arguments cannot include whitespaces, so if you need to pass command line arguments that include spaces (e.g. -var bucket=example.bucket.name
), then each of the arguments will need to be a separate item in the arguments
list:
terraform {
extra_arguments "bucket" {
commands = [
"apply",
"plan",
"import",
"push",
"refresh"
]
arguments = [
"-var", "bucket=example.bucket.name",
]
}
}
With the configuration above, when you run terragrunt apply
, Terragrunt will call OpenTofu/Terraform as follows:
$ terragrunt apply
# tofu apply -var bucket=example.bucket.name