For the following Terragrunt infrastructure code I have
infrastructure/
โโ accounts/
โ โโ dev/
โ โ โโ environments/
| | | โโ tst/
| | | | โโ eb_env/
| | | | | โโ terraform.tfvars
| | | โโ environment.tfvars
The variables defined in terraform.tfvars seem to get overridden from the variables in environment.tfvars which are passed in as optional_var_files. This seems contrary to the idea that the values defined in the lowest leaf node should have precedence.
The variables defined in the lowest terraform.tfvars should have precedence over all values over all the parent var files.
This is something built into Terraform itself. Per their docs:
Definition files passed using the -var-file flag will always be evaluated after those in the working directory.
Your terraform.tfvars leaf is just a file "in the working directory." You may be able to make it higher precedency by explicitly passing it using extra_arguments.
I was just able to get this working this morning by adding a reference to the working directory terraform.tfvars file in the top level terraform.tfvars file (which I've included below).
Live directory structure
terragrunt-live/
โโ site/
โ โโ site.tfvars
โ โโ environment/
โ โ โโ env.tfvars
โ โ โโ app/
โ โ โ โโ app.tfvars
โ โ โ โโ function/
โ โ โ โ โโ terraform.tfvars
โโ terraform.tfvars
โโ account.tfvars
top level terraform.tfvars file
# Terragrunt is a thin wrapper for Terraform that provides extra tools for working with multiple Terraform modules,
# remote state, and locking: https://github.com/gruntwork-io/terragrunt
terragrunt = {
# Configure Terragrunt to automatically store tfstate files in an S3 bucket
remote_state {
backend = "s3"
config {
encrypt = true
bucket = "<BUCKETNAME>"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "<TABLENAME>"
profile = "terraform_role"
}
}
# Configure root level variables that all resources can inherit
terraform {
extra_arguments "bucket" {
commands = ["${get_terraform_commands_that_need_vars()}"]
## The order of these files is reverse order of variable preference.
## (eg. Variables in earlier files will be overriden by variables with the same name in later files)
optional_var_files = [
"${get_tfvars_dir()}/${find_in_parent_folders("account.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("site.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("env.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("app.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("domain.tfvars", "ignore")}",
"${get_tfvars_dir()}/${find_in_parent_folders("ntp.tfvars", "ignore")}",
"${get_tfvars_dir()}/terraform.tfvars",
]
}
}
}
Right, so I suppose the real question is whether this behavior should be by default or not?
To me it just seems natural that the leaf terraform.tfvars values should implicitly have precedence without me explicitly referring to it as a var file argument.
@skang0601 I'd agree that it seems like it should be default. To me it would be logical that if all the files in optional_var_files have overriding functionality and a hierarchical order AND that the working directory terraform.tfvars file is automatically included that it should overwrite the lower ones.
However, I guess that would remove a setup where you didn't want to allow overriding in lower level files. So I suppose a reference to this sort of setup in the documentation would suffice for me.
Most helpful comment
I was just able to get this working this morning by adding a reference to the working directory terraform.tfvars file in the top level terraform.tfvars file (which I've included below).
Live directory structure
top level terraform.tfvars file