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
8.04k stars 975 forks source link

`terragrunt-debug` is printing out invalid commands (and failing to process an S3 credentials file) #2014

Closed pzduniak closed 1 year ago

pzduniak commented 2 years ago

Here's the repro:

deployments
|- dev
  |- terragrunt.hcl
modules
|- cluster
  |- backend.tf
  |- other tf files
terragrunt.hcl

Root terragrunt.hcl (pointed against Oracle's S3-compatible API) contains:

...
remote_state {
  backend = "s3"
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite"
  }
  config = {
    bucket                      = "terraform-state"
    key                         = "${path_relative_to_include()}/terraform.tfstate"
    region                      = local.object_storage_region
    endpoint                    = "https://${local.object_storage_namespace}.compat.objectstorage.${local.object_storage_region}.oraclecloud.com"
    shared_credentials_file     = "${path_relative_from_include()}/../secrets/terraform/aws_credentials"
    skip_region_validation      = true
    skip_credentials_validation = true
    skip_metadata_api_check     = true
    force_path_style            = true
  }
}

Deployment's terragrunt.hcl contains:

terraform {
  source = "../..//modules/cluster"
}

inputs = {
  regions = {
    home    = "us-ashburn-1"
    cluster = "ca-toronto-1"
  }

  base_domain     = "dev.example.com"
  cluster_name    = "dev"
}

include "root" {
  path = find_in_parent_folders()
}

Without the "source" block and a main.tf in the directory, it's all alright and I can run terragrunt init, which correctly reads the credentials from the path. However if not using the current working directory (ie. specifying the terraform.source arg), the shared_credentials_file doesn't work (defaults to whatever's in ~/.aws/credentials). So naturally the next step is to debug it...

deployment/dev $ terragrunt init --terragrunt-log-level debug --terragrunt-debug
...
DEBU[0000] Variables passed to terraform are located in "/base/deployments/dev/terragrunt-debug.tfvars.json"  prefix=[/base/deployments/dev]
DEBU[0000] Run this command to replicate how terraform was invoked:  prefix=[/base/deployments/dev]
DEBU[0000]       terraform init -var-file="/base/deployments/dev/terragrunt-debug.tfvars.json" "/base/deployments/dev/.terragrunt-cache/7jtQ3GlhnddApKuE9uO2MWLqsrY/abgPHKGbJIxg_mezQdYIQF9VrQI/modules/cluster"  prefix=[/base/deployments/dev]

This is not a valid Terraform command, which is the first issue:

terraform init -var-file "/base/deployments/dev/terragrunt-debug.tfvars.json" "/base/deployments/dev/.terragrunt-cache/7jtQ3GlhnddApKuE9uO2MWLqsrY/abgPHKGbJIxg_mezQdYIQF9VrQI/modules/cluster"
Too many command line arguments. Did you mean to use -chdir?

So my suspicion is that... it's actually using chdir? Assuming that also changes the working directory, that would explain why it's failing to look up the file - a ../../../secrets/terraform/aws_credentials points at /base/deployments/dev, rather than /.

I'm super disappointed that this is broken this way. I expected a bit more from a solution that claims to support this particular use case.

FWIW this is also broken with backend managed through flags. Probably for the same reason.

seanthingee commented 1 year ago

Have this same issue. Trying to debug something related to remote_state and the terraform command it provides does not run. Also, I have inputs set but those are not shown in the output to replicate as a comprehensive terraform command.

denis256 commented 1 year ago

Fix released in https://github.com/gruntwork-io/terragrunt/releases/tag/v0.51.3