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.83k stars 962 forks source link

Terragrunt assumes hasicorp/<provider> when generated provider block is used #2530

Open ch9hn opened 1 year ago

ch9hn commented 1 year ago

Hello, we faced some issues with the generated provider blocks from Terragrunt.

In our module we have a file called "versions.tf":

terraform {
  required_version = ">= 1.4"
  required_providers {
    scaleway = {
      source  = "scaleway/scaleway"
      version = ">= 2.16"
    }
  }

}

When we add a provider block in the base terragrunt.hcl:

#Generate a SCW Provider Block
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite"
  contents  = <<-EOF
    provider "scaleway" {
      region          = var.region
      zone            = var.zone
      organization_id = var.organization_id
}

variable "region" {
  description = "SCW Region."
}
variable "zone" {
  description = "SCW Zone."
}

variable "organization_id" {
  description = "SCW Orga ID"
}

  EOF
}

We get the following errors - also with other providers which are not from hashicorp because the merging of the files is not consistent


│ Error: Failed to query available provider packages
│ 
│ Could not retrieve the list of available versions for provider
│ hashicorp/scaleway: provider registry registry.terraform.io does not have a
│ provider named registry.terraform.io/hashicorp/scaleway
│ 
│ Did you intend to use scaleway/scaleway? If so, you must specify that
│ source address in each module which requires that provider. To see which
│ modules are currently depending on hashicorp/scaleway, run the following
│ command:
│     terraform providers
╵

The only solution is, to replicate the provider configuration into every module.

Does someone have similar issues ?

juljaeg commented 1 year ago

Are you referencing the module in a root module where also the base terragrunt lives?

xPiSeaZx commented 10 months ago

Hi, I'm experiencing the same issue with the Doppler provider. Looks like it's trying to install from hashicorp instead of 3rd party registry.

We have the following structure (this is for testing):

terragrunt.hcl

remote_state {
  backend = "local"
  config = {
    path = "${get_parent_terragrunt_dir()}/${path_relative_to_include()}/terraform.tfstate"
  }

  generate = {
    path      = "versions.tf"
    if_exists = "overwrite_terragrunt"
    contents  = <<-EOF
      required_providers {
        doppler = {
          source = "DopplerHQ/doppler"
          version = "1.3.0"
        }
    EOF
  }
}

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite"
  contents  = <<-EOF
    provider "doppler" {
      doppler_token = "<token>"
    }
  EOF
}

Running terragrunt init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/doppler...
╷
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider
│ hashicorp/doppler: provider registry registry.terraform.io does not have a
│ provider named registry.terraform.io/hashicorp/doppler
│
│ All modules should specify their required_providers so that external
│ consumers will get the correct providers when using a module. To see which
│ modules are currently depending on hashicorp/doppler, run the following
│ command:
│     terraform providers
╵

ERRO[0000] Terraform invocation failed in /home/user/repos/GitHub/doppler
ERRO[0000] 1 error occurred:
        * [/home/user/repos/GitHub/doppler] exit status 1
AsoTora commented 8 months ago

Same here with a gitlab provider:

generate "provider" {
  path      = "providers.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "gitlab" {
  token    = var.GITLAB_TOKEN
  base_url = var.BASE_URL
}
EOF
}

versions.tf in a module:

terraform {
  required_version = ">= 1.6.4"

  required_providers {
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = ">= 2.23.0"
    }
    gitlab = {
      source  = "gitlabhq/gitlab"
      version = ">= 16.6.0"
    }
  }
}

output:


Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/kubernetes...
- Finding latest version of hashicorp/gitlab...
- Installing hashicorp/kubernetes v2.23.0...
- Installed hashicorp/kubernetes v2.23.0 (signed by HashiCorp)
╷
│ Error: Failed to query available provider packages
│ 
│ Could not retrieve the list of available versions for provider
│ hashicorp/gitlab: provider registry registry.terraform.io does not have a
│ provider named registry.terraform.io/hashicorp/gitlab
│ 
│ Did you intend to use gitlabhq/gitlab? If so, you must specify that source
│ address in each module which requires that provider. To see which modules
│ are currently depending on hashicorp/gitlab, run the following command:
│     terraform providers
juljaeg commented 8 months ago

You need to add gitlab as a required provider in the root module as well, not just in the module.

ShankyJS commented 2 weeks ago

Same problem here; the main driver of my problems is that my root module might have providers that are true for most of the cases e.g aws/random providers, however on my child-modules I would like to be able to override them in case I wanna use different versions of the providers.

Doing something like:

root Terragrunt:

generate "versions" {
  path      = "versions.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.46.0"
    }
    random = {
      source = "hashicorp/random"
      version = "3.5.1"
    }
  }
}
EOF
}

Child module; same providers as parent config but adding an extra configuration for my extra child provider.

generate "versions_overwrite" {
  path      = "versions.tf"
  if_exists = "overwrite"
  contents  = <<EOF
  terraform {
    required_providers {
      aws = {
        source = "hashicorp/aws"
        version = "~> 5.46.0"
      }
      random = {
        source = "hashicorp/random"
        version = "~> 3.5.1"
      }
      dnsimple = {
        source  = "dnsimple/dnsimple"
        version = "~> 1.6.0"
      }
    }
  }
EOF
}

This gives problems like e.g

git:(main) ✗ terragrunt plan

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/random from the dependency lock file
- Finding latest version of hashicorp/dnsimple...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Using previously-installed hashicorp/random v3.5.1
- Using previously-installed hashicorp/aws v5.46.0
╷
│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider
│ hashicorp/dnsimple: provider registry registry.terraform.io does not have a
│ provider named registry.terraform.io/hashicorp/dnsimple
│
│ Did you intend to use dnsimple/dnsimple? If so, you must specify that
│ source address in each module which requires that provider. To see which
│ modules are currently depending on hashicorp/dnsimple, run the following
│ command:
│     terraform providers