gruntwork-io / terragrunt

Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.
https://terragrunt.gruntwork.io/
MIT License
7.93k stars 965 forks source link

Unable to apply multiple modules at once. #3181

Open RyanW8 opened 3 months ago

RyanW8 commented 3 months ago

Describe the bug

Our terragrunt file structure is the following, top level is the application name, 2nd level is account & 3rd is the region. E.g. Top Level = example_app 2nd Level = example_account 3rd Level = example_region Would look like

example_app/
  project.hcl
  terragrunt.hcl
  example_account/
    account.hcl
    example_region/
      region.hcl
      terragrunt.hcl

We define what the application terraform should look like at the application/top level like so

terraform {
 ...
}
locals {
  project_locals = read_terragrunt_config(find_in_parent_folders("project.hcl")).locals
  account_locals = read_terragrunt_config(find_in_parent_folders("account.hcl")).locals
  region_locals  = read_terragrunt_config("region.hcl").locals
}
...

child terragrunt.hcl files are located at app_name/account_name/region_name/terragrunt.hcl. And are simple terragrunt files that have an include block for the root terragrunt configuration (defined at the application/top level). In our root terragrunt configuration we define the above locals for all children, basic things like project/app level locals, account level & region level locals.

The issue is we are unable to use the run-all command to apply multiple accounts/regions at any given time as the terragrunt run-all <operation> command first validates/tries to run the root level terragrunt file which is invalid on it's own as the account & region level locals do not exists in that context.

Running plan/apply operation at the region level works correctly as it finds the child terragrunt.hcl

Expected behavior

Be able to run the run-all command from the top/application level

RyanW8 commented 3 months ago

Looks like skip = true would solve this nicely but it doesn't seem to be functioning as intended at the minute https://github.com/gruntwork-io/terragrunt/issues/704. Issue open for a very long time too ):

denis256 commented 3 months ago

Hi, I wondered why to have in the project root terragrunt.hcl file? The include path can reference different file names:

include "root" {
  path = find_in_parent_folders("root.hcl")
}

https://terragrunt.gruntwork.io/docs/reference/built-in-functions/#find_in_parent_folders

pmaterer commented 3 weeks ago

This appears to still be an issue, and it seems using the structure in this repo and from the docs doesn't work with Terragrunt.

I'm using:

❯ terragrunt --version                                
terragrunt version 0.66.9

Here is my directory layout:

~/tmp/example on ☁️  materer-dev (us-east-1) 
❯ tree                   
.
├── dev
│   ├── account.hcl
│   └── key
│       └── terragrunt.hcl
├── prod
│   ├── account.hcl
│   └── key
│       └── terragrunt.hcl
└── terragrunt.hcl

5 directories, 5 files

And the files:

File: terragrunt.hcl
Path: ./terragrunt.hcl

Contents:
locals {
  account_info = read_terragrunt_config(find_in_parent_folders("account.hcl"))
  profile = local.account_info.locals.profile
}

generate "provider" {
    path = "provider.tf"
    if_exists = "overwrite_terragrunt"
    contents = <<EOF
provider "aws" {
    region = "us-east-1"
    profile = "${local.profile}"
}
EOF
}

----------------------------------------

File: account.hcl
Path: ./prod/account.hcl

Contents:
locals {
    profile = "materer-prod"
}

----------------------------------------

File: terragrunt.hcl
Path: ./prod/key/terragrunt.hcl

Contents:
include "root" {
  path = find_in_parent_folders()
}

terraform {
  source = "tfr:///terraform-aws-modules/kms/aws?version=3.1.0"
}

inputs  = {
    description = "Test key"
}

----------------------------------------

File: account.hcl
Path: ./dev/account.hcl

Contents:
locals {
    profile = "materer-dev"
}

----------------------------------------

File: terragrunt.hcl
Path: ./dev/key/terragrunt.hcl

Contents:
include "root" {
  path = find_in_parent_folders()
}

terraform {
  source = "tfr:///terraform-aws-modules/kms/aws?version=3.1.0"
}

inputs = {
    description = "Test key"
}

----------------------------------------

And the error I get:

❯ terragrunt run-all init
ERRO[0000] Error: Error in function call

ERRO[0000]   on /Users/pmaterer/tmp/example/terragrunt.hcl line 2, in locals: 
ERRO[0000]    2:   account_info = read_terragrunt_config(find_in_parent_folders("account.hcl")) 
ERRO[0000]                                              
ERRO[0000] Call to function "find_in_parent_folders" failed: ParentFileNotFoundError: Could not find a account.hcl in any of the parent folders of /Users/pmaterer/tmp/example/terragrunt.hcl. Cause: Traversed all
the way to the root..

ERRO[0000] Error processing module at '/Users/pmaterer/tmp/example/terragrunt.hcl'. How this module was found: Terragrunt config file found in a subdirectory of /Users/pmaterer/tmp/example. Underlying error: /Users/pmaterer/tmp/example/terragrunt.hcl:2,41-64: Error in function call; Call to function "find_in_parent_folders" failed: ParentFileNotFoundError: Could not find a account.hcl in any of the parent folders of /Users/pmaterer/tmp/example/terragrunt.hcl. Cause: Traversed all the way to the root.. 
ERRO[0000] Unable to determine underlying exit code, so Terragrunt will exit with error code 1