Terragrunt: Restricting terragrunt *-all to specific environment?

Created on 31 Dec 2019  ยท  8Comments  ยท  Source: gruntwork-io/terragrunt

Hey guys,
I have the following configuration in the parent terragrunt.hcl file:

inputs = merge(
  yamldecode(
    file("${get_parent_terragrunt_dir()}/../global/global-values_${get_env("ENVIRONMENT", "")}.yaml"),
  ),
  yamldecode(
    file("${get_terragrunt_dir()}/values_${get_env("ENVIRONMENT", "")}.yaml"),
  )
)

Running terragrunt plan-all/apply-all fails due to some directories which don't contain a yaml file for the specific environment.
Is there a way to restrict terragrunt *-all to run only on modules which contain the environment's yaml file, without resorting to --terragrunt-include-dir or --terragrunt-exclude-dir?

Thanks!

question

All 8 comments

This isn't an answer to your exact question, but should workaround the specific issue you are hitting with the usage of yamldecode and file. The canonical way to address this is to use find_in_parent_folders and default to an empty yaml file at the root of your project. See this repo for an example setup. Specifically: https://github.com/gruntwork-io/terragrunt-infrastructure-live-example/blob/master/non-prod/terragrunt.hcl#L26

Thanks @yorinasub17.
I did try this example, however the module is asking for the missing variables when an empty yaml file is used as input.
Any other suggestions?

I have found a workaround to the missing variables issue, I added the following to the child terragrunt.hcl:

skip = fileexists("../values_${get_env("ENVIRONMENT", "")}.yaml")  ? false : true

However, I'm still not loving the idea of having to create a subdirectory for the terragrunt,hcl file just for the sake of using the find_in_parent_folders function. Is there an alternative?
Thanks

however the module is asking for the missing variables when an empty yaml file is used as input.

What is the normal way you are providing these variables? As in, are these modules designed such that you need the variables to be provided manually and thus want to exclude from the apply-all?

I'm still not loving the idea of having to create a subdirectory for the terragrunt,hcl file

I am confused by this. Are you referring to the terragrunt.hcl inheritance model with include? Or are you referring to the yaml files? What is the ideal way you want to organize your folders?

@yorinasub17 I'm providing the variables with a yaml values file specific for the component within a specific environment:

yamldecode(
    file("${get_terragrunt_dir()}/${find_in_parent_folders("values_${get_env("ENVIRONMENT", "")}.yaml", local.default_yaml_path)}"),
  )

Currently this is my directory structure:

โ”œโ”€โ”€ devops
โ”‚ย ย  โ”œโ”€โ”€ amazing-app
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ ecr
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ terragrunt
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ terragrunt.hcl
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ values_us-east-1_global.yaml
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ k8s
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ terragrunt
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ terragrunt.hcl
โ”‚ย ย  โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ values_us-east-1_dev.yaml
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ s3
โ”‚ย ย  โ”‚ย ย      โ”œโ”€โ”€ terragrunt
โ”‚ย ย  โ”‚ย ย      โ”‚ย ย  โ””โ”€โ”€ terragrunt.hcl
โ”‚ย ย  โ”‚ย ย      โ””โ”€โ”€ values_us-east-1_dev.yaml
โ”œโ”€โ”€ empty.yaml
โ”œโ”€โ”€ global
โ”‚ย ย  โ”œโ”€โ”€ global-values_us-east-1_dev.yaml
โ”‚ย ย  โ”œโ”€โ”€ global-values_us-east-1_global.yaml
โ”‚ย ย  โ”œโ”€โ”€ global-values_us-east-1_prod.yaml
โ”‚ย ย  โ”œโ”€โ”€ global-values_us-east-1_staging.yaml
โ”œโ”€โ”€ modules
โ”‚ย ย  โ”œโ”€โ”€ ecr
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ main.tf
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ outouts.tf
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ variables.tf
โ”‚ย ย  โ”œโ”€โ”€ k8s
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ main.tf
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ outouts.tf
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ variables.tf
โ”‚ย ย  โ””โ”€โ”€ s3
โ”‚ย ย      โ”œโ”€โ”€ main.tf
โ”‚ย ย      โ”œโ”€โ”€ outouts.tf
โ”‚ย ย      โ””โ”€โ”€ variables.tf
โ””โ”€โ”€ terragrunt.hcl

As you can see I had to move the child terragrunt.hcl files to a terragrunt subdirectory due to the use of the find_in_parent_folders function.

Oh in that case, can you use path_relative_from_include for the default path? E.g:

file("${get_terragrunt_dir()}/${find_in_parent_folders("values_${get_env("ENVIRONMENT", "")}.yaml", "${path_relative_from_include()}/global/values_${get_env("ENVIRONMENT", "")}.yaml")}")

Thank @yorinasub17.
I ended up with this workaround:

locals {
  default_yaml_path = find_in_parent_folders("empty.yaml", "empty.yaml")
  file_path = "${get_terragrunt_dir()}/values_${get_env("TF_VAR_environment", "")}.yaml"
  environment_yaml_file = fileexists(local.file_path) ? local.file_path : local.default_yaml_path
}

inputs = merge(
  yamldecode(
    file("${get_parent_terragrunt_dir()}/global/global-values_${get_env("TF_VAR_environment", "")}.yaml")
  ),
  yamldecode(
    file(local.environment_yaml_file),
  ),
  {
    team = "${split("/", path_relative_to_include()).0}"
  },
  {
    account = "${split("_", get_env("TF_VAR_environment", "")).0}"
  }
)

Thanks for closing the loop. Going to close this issue now as we don't intend on implementing complex build logic for the xxx-all commands in terragrunt at the moment.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mmorianos picture mmorianos  ยท  3Comments

ozbillwang picture ozbillwang  ยท  3Comments

shaharmor picture shaharmor  ยท  3Comments

antonbabenko picture antonbabenko  ยท  3Comments

lsc picture lsc  ยท  4Comments