'How can I use locals defined in terragrunt.hcl in Terraform files?

I've created this folder structure:

.
├── main.tf
└── terragrunt.hcl
# FILE: terragrunt.hcl

include {
  path = find_in_parent_folders()
}

locals {
  common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))
  cluster_name = local.common_vars.locals.cluster_name
}

terraform {
  source = "./main.tf"
}
# FILE: main.tf

module "tags" {
  source = "..."

  eks_cluster_names = [local.cluster_name]
}

module "vpc" {
  source = "..."

  aws_region = local.common_vars.locals.aws_region
  
  ...

  vpc_custom_tags = module.tags.vpc_eks_tags
  
  ...
}

But for every local. I am trying to use I get an error:

A local value with the name "blabla" has not been declared

So now I am trying to figure out a way to make this work. I considered following how-to-access-terragrunt-variables-in-terraform-code, but I didn't want to create a variables.tf. Also, another problem is that I would have to redefine all outputs from modules in main.tf, isn't there a nicer way to do this?

Is there a structure that is a good practice I could follow? How could I "propagate" these locals in terragrunt.hcl to main.tf?



Solution 1:[1]

Terragrunt calls directly TF modules. Meaning get rid of main.tf and use just Terragrunt to wire your modules. There needs to be a separated subfolder (component) with terragrunt.hcl per TF module.

Your project structure will look like this:

.
??? terragrunt.hcl
??? tags
?   ??? terragrunt.hcl
??? vpc
    ??? terragrunt.hcl

Feel free to have a look at how that works and how the variables are passed across the modules at my example here.

Solution 2:[2]

Sorry to disappoint but you do have to create a variables.tf - that is standard terraform. You define the input variables you need in there for your terraform configuration, and in terragrunt you fill these. So your terragrunt file should look something like:

# FILE: terragrunt.hcl  
locals {
  common_vars = read_terragrunt_config(find_in_parent_folders("common.hcl"))
  cluster_name = local.common_vars.locals.cluster_name
}

terraform {
  source = "./main.tf"
}

inputs = {
    cluster_name = local.cluster_name
    aws_region = local.common_vars.locals.aws_region
}

And your terraform main should look like this:

# FILE: main.tf

module "tags" {
  source = "..."

  eks_cluster_names = var.cluster_name
}

module "vpc" {
  source = "..."

  aws_region = var.aws_region
  
  ...

  vpc_custom_tags = module.tags.vpc_eks_tags
  
  ...
}

And your variables.tf would then look like:

variable "aws_region" {
    type = string
}
variable "cluster_name" {
    type = string
}

Additionally, you probably also need to create a provider.tf and a backend configuration to get this to run.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jules