I have a root module that define my providers using generate block in terragrunt.hcl, but I have some child modules that not need all providers defined in root. So, I think that could be very useful to be able of define specific providers used though of child modules.
Implementation suggestion:
terragrunt.hcl:generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
provider "google" {
version = "~> 3.22.0"
credentials = file(var.google_credentials_path)
}
provider "cloudflare" {
version = "~> 2.7.0"
email = var.cloudflare_email
api_token = var.cloudflare_api_token
}
EOF
}
terragrunt.hcl:include {
path = find_in_parent_folders()
providers = ["google", "cloudflare"]
}
But, I have questions about how to read variables defined in root configuration, otherwise would be needed repeat credentials variables in each child module.
Hm, I don't think there's an easy way to do this now. You may need separate terragrunt-xxx.hcl and terragrunt-yyy.hcl root files with the different provider settings and the child modules could use find_In_parent_folders("terragrunt-[xxx|yyy].hcl") to include the appropriate root file.
One way you could do this is to define an hcl file as feature switches in the folder structure, and reference that in the root config to turn on and off certain providers in the template.
E.g.:
folder structure
.
โโโ subset
โย ย โโโ app
โย ย โย ย โโโ terragrunt.hcl
โย ย โโโ provider_switches.hcl
โโโ terragrunt.hcl
provider_switches.hcl
locals {
include_cloudflare = true
include_google = false
}
root terragrunt.hcl
locals {
provider_switches = read_terragrunt_config(find_in_parent_folders("provider_switches.hcl"))
}
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<-EOF
%{ if local.provider_switches.locals.include_google }
provider "google" {
version = "~> 3.22.0"
credentials = file(var.google_credentials_path)
}
%{ endif }
%{ if local.provider_switches.locals.include_cloudflare }
provider "cloudflare" {
version = "~> 2.7.0"
email = var.cloudflare_email
api_token = var.cloudflare_api_token
}
%{ endif }
EOF
}
But, I have questions about how to read variables defined in root configuration, otherwise would be needed repeat credentials variables in each child module.
The best way to do this is to separate out the common variables into a separate HCL file that is then read in in the child config using read_terragrunt_config. Note that you can't use read_terragrunt_config on the parent configuration because of a bug where find_in_parent_folders does not properly work when chaining read_terragrunt_config calls.
Hello @brikis98 and @yorinasub17, firstly I would like to thanks for previous replies.
So, I tried to test this example by @yorinasub17, however doesn't work properly, because root terragrunt.hcl not found provider_switches.hcl. In fact, I don't understand how to referencing provider_switches.hcl using read_terragrunt_config(find_in_parent_folders("provider_switches.hcl")) in root terragrunt.hcl.
Besides that how to do works this conditionals template syntax defined in generate block? Could you explain in more details, please?
The way the system works is as follows:
terragrunt.hcl includes the root terragrunt.hcl by looking up the file in the parent folders using find_in_parent_folders.terragrunt.hcl, find_in_parent_folders is evaluated in reference to the child terragrunt file. This ensures that it will find the provider_switches.hcl file in the parent folders of the child config, and not the parent.Note that there are two gotchas with this:
When running terragrunt xxx-all in the same level as the root, terragrunt will attempt to evaluate the root terragrunt config. This will cause find_in_parent_folders to fail because it is evaluated at the context of the root terragrunt config, where there is no provider_switches.hcl file. To avoid this, you want to use try to return a mock object if it can't find the file.
find_in_parent_folders only finds files in the parent folders. So if provider_switches.hcl is defined in the same folder as the child config, this will not work. If you want it next to the child config, you need to use get_terragrunt_dir.
Besides that how to do works this conditionals template sintax defined in generate block? Could you explain in more details, please?
The conditional template syntax is the same syntax supported by terraform: https://www.terraform.io/docs/configuration/expressions.html#string-templates
I just came across this topic and failed with the if-else solution from @yorinasub17. To save people time, I want to share that the syntax is a little bit wrong. You must use %{ instead of {%
Anw, his solution solves my problem. Thanks a lot
Thanks for the report. Updated!
Hello @yorinasub17. Sorry for my delay, I am go back for to say that this solution solves my problem. Thanks so much for your help.
Most helpful comment
One way you could do this is to define an hcl file as feature switches in the folder structure, and reference that in the root config to turn on and off certain providers in the template.
E.g.:
folder structure
provider_switches.hcl
root terragrunt.hcl
The best way to do this is to separate out the common variables into a separate HCL file that is then read in in the child config using
read_terragrunt_config. Note that you can't useread_terragrunt_configon the parent configuration because of a bug wherefind_in_parent_foldersdoes not properly work when chainingread_terragrunt_configcalls.