Does anyone have publicly documented examples of using a 3 tier module structure working with terragrunt?
For context, see starting at slide 22 of https://www.slideshare.net/VadimSolovey/terraform-modules-restructured-220136382. As described in this post, your “infrastructure” repo would consume “terraform-services” which consume “terraform-resources”.
I’ve also seen people use this methodology with slightly different terms, your “instance”/“infrastructure” repo could consume a “unit” which consumes “modules”.
In the majority of the documentation that I’ve read online, this is not the method that people follow. Most examples I’ve read appear to be following a pattern of having the “infrastructure” repo call “modules”, which do a number of things, directly. The general concept is that there is almost certainly some duplication in the “modules” in this case, that could be further simplified.
I was attempting to mock this out very simply using ‘outputs’ and for whatever reason I was having a difficult time having my “units” pass variables on to my “modules”. For instance:
INFRASTRUCTURE REPO
.
├── instance.tfvars
└── terragrunt.hcl
instance.tfvars:
myvars = {
foo = "bar"
bar = "baz"
baz = "foo"
}
terragrunt.hcl
terraform {
source = "git@github.com:example/terraform-units.git//outputs?ref=master"
}
include {
path = find_in_parent_folders()
}
UNITS REPO (or terraform-services)
main.tf:
terraform {
backend "s3" {}
}
variable myvars {}
module "outputs" {
source = "git@github.com:example/terraform-modules.git//outputs?ref=master"
myvars = var.myvars
}
MODULES REPO (or terraform-modules)
main.tf:
terraform {
backend "s3" {}
}
variable myvars {}
output "myvars" {
value = var.myvars
description = "myvars"
}
MAIN TERRAGRUNT.HCL
remote_state {
backend = "s3"
config = {
bucket = "some-bucket"
key = "state/${path_relative_to_include()}/terraform.tfstate"
region = "some-where"
encrypt = true
}
}
terraform {
extra_arguments "-var-file" {
commands = get_terraform_commands_that_need_vars()
optional_var_files = [
"${get_terragrunt_dir()}/instance.tfvars"
]
}
}
Like I mentioned, I’ve seen it work, I just don’t recall exactly what the magic piece I’m missing was in the “units” or “terraform-services” piece was that allowed me to receive the values in the module. When I run this particular example, I get nothing. If I call the module directly from the infrastructure repo, instead of the ‘unit’, I see the proper output.
In reality, what I want/intend to do in the ‘units’, is do a deep merge of all of the maps, where there may be duplicates (for instance, I may have account.tfvars and region.tfvars), and take the key/value specified further down in the stack.