Terraform: Missing provider error when using alias

Created on 21 Sep 2020  Β·  15Comments  Β·  Source: hashicorp/terraform

After upgrading to 0.13 I get the following error on terraform apply:

Error: missing provider provider["registry.terraform.io/hashicorp/datadog"].eu-central-1

Terraform Version

Terraform v0.13.2
+ provider registry.terraform.io/-/datadog v2.13.0
+ provider registry.terraform.io/terraform-providers/datadog v2.13.0

Terraform Configuration Files

provider "datadog" {
  api_key = var.datadog.us.api_key
}                                                                                                                                                                                                                                                                                                                              

provider "datadog" {                                                           
  alias = "eu-central-1"

  api_url = "https://api.datadoghq.eu/"                                        
  api_key = var.datadog.eu.api_key
  app_key = var.datadog.eu.app_key
}

terraform {
  required_providers {
    datadog = {
      source = "terraform-providers/datadog"
    }
  }

  required_version = ">= 0.13"
  backend "s3" {
  }
} 

Steps to Reproduce

  1. terraform init
  2. terraform apply
bug confirmed v0.13

All 15 comments

Hi @Dissonant-Tech. It looks like you might have some instances of Datadog resources in an 0.12 format state file, which are causing the provider to be associated to hashicorp/datadog.

Can you show the output of terraform providers?

For more on this, please see the 0.13 upgrade guide FAQ, which explains how to use terraform state replace-provider to fix the problem.

Hi @alisdair I've replaced state providers with:

terraform state replace-provider -- -/datadog registry.terraform.io/terraform-providers/datadog

But still get the same error. Here's the output of terraform providers:

.
β”œβ”€β”€ provider[registry.terraform.io/terraform-providers/datadog]
β”œβ”€β”€ module.datadog
β”‚Β Β  └── provider[registry.terraform.io/terraform-providers/datadog]
β”œβ”€β”€ module.datadog-eu-central-1
β”‚Β Β  └── provider[registry.terraform.io/terraform-providers/datadog]
β”œβ”€β”€ module.example-eu-central-1
β”‚Β Β  └── provider[registry.terraform.io/terraform-providers/datadog]
β”œβ”€β”€ module.example
β”‚Β Β  └── provider[registry.terraform.io/terraform-providers/datadog]

    Providers required by state:
    provider[registry.terraform.io/terraform-providers/datadog]

EDIT: I temporarily downgraded to 0.12 to get around this and saw a warning mentioning the new datadog provider is found at datadog/datadog so re-upgraded and tried that but still got the same error.

Huh. Unfortunately, I'm not able to reproduce the issue with a slightly reduced version of the configuration you've given:

provider "datadog" {}
provider "datadog" {                                                           
  alias = "eu-central-1"
  api_url = "https://api.datadoghq.eu/"                                        
}

terraform {
  required_providers {
    datadog = {
      source = "datadog/datadog"
    }
  }

  required_version = ">= 0.13"
} 

Running terraform apply with this works, so I can only guess that there must be something else happening with your configuration or state that we can't see. Can you reproduce this issue with a separate smaller configuration, which you could share the entirety of?

Hi,
we have the same issue with postgresql provider during upgrade to TF 0.13.3.
Neither the state or the configuration have reference to registry.terraform.io/hashicorp/postgresql but tf plan continue to complain about missing missing provider provider["registry.terraform.io/hashicorp/postgresql"]

Worse, even after deleting the 2 resources using postgresql provider from state (terraform state rm ...) the error message is still present.

Terraform configuration:

terraform {
  required_providers {
    aws = {
      version = "=3.7.0"
      source  = "hashicorp/aws"
    }
    helm = {
      version = "=1.3.0"
      source  = "hashicorp/helm"
    }
    local = {
      version = "=1.4.0"
      source  = "hashicorp/local"
    }
    kubernetes = {
      version = "1.12.0"
      source  = "hashicorp/kubernetes"
    }
    null = {
      version = "=2.1.2"
      source  = "hashicorp/null"
    }
    random = {
      version = "=2.3.0"
      source  = "hashicorp/random"
    }
    postgresql = {
      version = "=1.7.1"
      source  = "terraform-providers/postgresql"
    }
    template = {
      version = "=2.1.2"
      source  = "hashicorp/template"
    }
  }
  required_version = "0.13.3"
  backend "s3" {
    key = "REDACTED.tfstate"
  }
}

terraform providers output:

Providers required by configuration:
.
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/local] 1.4.0
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/kubernetes] 1.12.0
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/null] 2.1.2
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/random] 2.3.0
β”œβ”€β”€ provider[registry.terraform.io/terraform-providers/postgresql] 1.7.1
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/template] 2.1.2
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/aws] 3.7.0
β”œβ”€β”€ provider[registry.terraform.io/hashicorp/helm] 1.3.0
β”œβ”€β”€ module.glue
β”‚Β Β  β”œβ”€β”€ provider[registry.terraform.io/hashicorp/local]
β”‚Β Β  └── provider[registry.terraform.io/hashicorp/aws]
β”œβ”€β”€ module.glue-scripts
β”œβ”€β”€ module.sap
β”‚Β Β  β”œβ”€β”€ provider[registry.terraform.io/hashicorp/aws]
β”‚Β Β  └── provider[registry.terraform.io/hashicorp/template] 2.1.2
β”œβ”€β”€ module.command-queue
β”‚Β Β  └── provider[registry.terraform.io/hashicorp/aws]
└── module.db
    └── provider[registry.terraform.io/terraform-providers/postgresql]

Providers required by state:

    provider[registry.terraform.io/hashicorp/template]

    provider[registry.terraform.io/hashicorp/aws]

terraform plan output:

Error: missing provider provider["registry.terraform.io/hashicorp/postgresql"]

I really cannot figure why there is still a reference to registry.terraform.io/hashicorp/postgresql.
Regards

We finally found the issue.
We have a call to a module where an additional provider was set but was not declared in the module configuration.

module config:

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
    template = {
      source = "hashicorp/template"
    }
  }
  required_version = ">= 0.13"
}

Module usage

module "test" {
  ...
  providers = {
    aws                = aws
    postgresql = postgresql
  }
}

remove the wrong postgresql = postgresql declaration in the module call fix the issue.

Thanks, @phenixdotnet, that's super helpful! @Dissonant-Tech, does that help resolve the issue you're seeing? Are you passing an unused provider into a module?

I now have a reproduction for what I assume is the original issue:

main.tf

terraform {
  required_providers {
    javascript = {
      source = "apparentlymart/javascript"
    }
  }

  required_version = ">= 0.13"
} 

module "js" {
  source = "./js"
  providers = {
    javascript = javascript
  }
}

js/main.tf:

resource "null_resource" "none" {}
$ terraform providers

Providers required by configuration:
.
β”œβ”€β”€ provider[registry.terraform.io/apparentlymart/javascript]
└── module.js
    └── provider[registry.terraform.io/hashicorp/null]

$ terraform plan

Error: missing provider provider["registry.terraform.io/hashicorp/javascript"]

While I think the configuration is invalid, I think there must be something we can do here to improve this, if only helping to debug what's going on. I'm not sure what that solution is, so I'll mark this confirmed for now.

Hi @alisdair, I'm also seeing the same issue @Dissonant-Tech mentioned, however I do not have any additional unused provider configured.

I've been able to reproduce in a very simplified setup available here : https://github.com/Gandem/terraform-reproduce-bug

$ terraform providers

Providers required by configuration:
.
β”œβ”€β”€ provider[registry.terraform.io/datadog/datadog] ~> 2.13.0
β”œβ”€β”€ module.eu-prod
β”‚Β Β  └── module.hello
β”‚Β Β      └── provider[registry.terraform.io/datadog/datadog]
└── module.us-prod
    └── module.hello
        └── provider[registry.terraform.io/datadog/datadog]
$ terraform plan

Error: missing provider provider["registry.terraform.io/hashicorp/datadog"].eu-prod

Available to provide more details if needed ! Thanks πŸ™‡

@Gandem it looks like the same bug for me.
you're module doesn't forward provider information to submodule in file hello.tf

Changing config to

module "hello" {
  source        = "./hello-module"
  providers = { datadog = datadog }
}

should do the trick (not tested)

I’ve done this too many times

On Thu, Oct 1, 2020 at 9:20 AM Nicholas Rico armanirico55@gmail.com wrote:

I do not want to get reborn...

On Thu, Oct 1, 2020 at 9:07 AM Vincent LainΓ© notifications@github.com
wrote:

>
>

@Gandem https://github.com/Gandem it looks like the same bug for me.

you're module doesn't forward provider information to submodule in file
hello.tf

Changing config to

module "hello" {

source = "./hello-module"

providers = { datadog = datadog }

}

should do the trick (not tested)

β€”
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/hashicorp/terraform/issues/26312#issuecomment-702160065,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AREJXMVH4OOVJ5NDD3JPVJDSISEKVANCNFSM4RUOX7CA
.

Hey @phenixdotnet,

Doing as you suggested does not solve the issue unfortunately. However, adding the following in resources/ does seem to do the trick:

terraform {
  required_providers {
    datadog = {
      source  = "datadog/datadog"
    }
  }
}

Not sure if this is an expected behaviour.

I do not want to get reborn...

On Thu, Oct 1, 2020 at 9:07 AM Vincent LainΓ© notifications@github.com
wrote:

>
>

@Gandem https://github.com/Gandem it looks like the same bug for me.

you're module doesn't forward provider information to submodule in file
hello.tf

Changing config to

module "hello" {

source = "./hello-module"

providers = { datadog = datadog }

}

should do the trick (not tested)

β€”
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/hashicorp/terraform/issues/26312#issuecomment-702160065,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AREJXMVH4OOVJ5NDD3JPVJDSISEKVANCNFSM4RUOX7CA
.

I've encountered the same thing.

Terraform v0.13.5

I am also encountering this after moving resources (tf state mv module. module..module.) to a nested module structure that each one of them uses a different aws region provider.

Gettng messages like this in a non deterministic fashion (every time a different alias pops up):

missing provider module.guard-duty.provider["registry.terraform.io/hashicorp/aws"].lo

It seems that the now nested modules expect the providers to be at the same level, explicitly defined as aliases, as if they were before.

This is fixed if I explicitly define again the provider blocks aliased inside the module source code (same way I do in the root level). But this shouldn't be necessary as I already have modules in the state that don't need this and work fine as is.

@alisdair Could you add this case in the future fix? It is quite common that someone would move resources to another place. It should not create these kind of issues and mess up the nested provider aliases. They should be sourced from root's module's definition, like this:

module "guard-duty" {
  source = "./modules/guard_duty_all"

  providers = {
    aws.vi = aws.virginia
    ...
    aws.cp = aws.capetown
  }
}

and nested module definitions, use them like this:

module "capetown" {
  ...

  providers = {
    aws = aws.cp
  }
}

with no need of defining:

provider "aws" {
  region = "af-south-1"
  alias  = "cp"
}

inside the module's source code.

Thanks in advance for looking into this.

EDIT: 5/11

Ok from here, this seems to be the intended behavior when multiple aliases of the same provider are passed down to a module: https://www.terraform.io/docs/configuration/modules.html#passing-providers-explicitly

In my example, I have a main entry point including moduleA which then includes moduleB. moduleA and moduleB are both independent, re-usable modules.

My main entrypoint declares:

module "module_a" {
  ...
  providers = {
    postgresql = postgresql.correct_alias
  }
}

provider "postgresql" {
  alias     = "correct_alias"
  ...
}

and

terraform {
  required_version = ">= 0.13"
  required_providers {
    postgresql = {
      source = "terraform-providers/postgresql"
    }
  }
}

Module B uses the postgresql provider and declares:

terraform {
  required_version = ">= 0.13"
  required_providers {
    postgresql = {
      source = "terraform-providers/postgresql"
    }
  }
}

Module A declares:

module "module_b" {
  ...
}

Crucially, module A does not directly use the postgresql provider and so does not declare it as a required provider (it doesn't require it.... but its dependency does).
This magically worked in 0.11 and 0.12, but not in 0.13.5 (possibly others).

The fix was to add to the require providers in module A and explicitly pass it through to module B when including.

What made this hard to figure out was that there is no information provided by the error pointing to what was trying to use the undeclared provider.

Agreed that Terraform is not very helpful in this situation. We'd like to be able to catch these situations and provide more useful diagnostics. I'm not sure at this point how we'd do that, but just noting for now that this is something we would like to improve.

Was this page helpful?
0 / 5 - 0 ratings