terraformterraform0.12+

Do terraform modules need required_providers?


I'm a little confused about what I'm reading in the terraform documentation. Here's what it says about modules:

https://www.terraform.io/docs/language/modules/index.html

Modules are containers for multiple resources that are used together. A module consists of a collection of .tf and/or .tf.json files kept together in a directory.

Here's what it says about providers: https://www.terraform.io/docs/language/providers/requirements.html

Requiring Providers

Each Terraform module must declare which providers it requires, so that Terraform can install and use them. Provider requirements are declared in a required_providers block.

A provider requirement consists of a local name, a source location, and a version constraint:

terraform {
 required_providers {
    mycloud = {
      source  = "mycorp/mycloud"
      version = "~> 1.0"
   }
 }
}

I'm confused about this because I never have specified required_providers in any of my modules, even though I'm using providers and it says I must do so. I didn't even know the documentation said this until today.

So am I misinterpreting the documentation, or is the documentation wrong? Does each of my modules need required_providers or not? My terraform configuration definitely works without them, so are they defaulting to something? If yes, how and where?


Solution

  • For backward compatibility with earlier versions of Terraform, Terraform v0.13 and later treat any use of a provider short name that isn't declared in required_providers as an implicit declaration of a requirement for a provider in the hashicorp namespace.

    For example, we can consider a resource like this:

    resource "aws_instance" "example" {
      # ...
    }
    

    If you haven't declared what provider you mean by aws then Terraform will assume that you mean to write something like this:

    terraform {
      required_providers {
        aws = {
          source = "hashicorp/aws"
        }
      }
    }
    

    This behavior is primarily intended to allow existing modules written against the HashiCorp-distributed providers (previously the only auto-installable providers) to continue working without any modification. You can rely on that backward-compatibility behavior if you wish, but the intention (reflected in the docs) is that all modern Terraform modules should be explicit about which specific providers they are using so that, over time as there are more providers belonging to other namespaces, a reader of the module doesn't need to be aware of this special backward-compatibility rule in order to understand its meaning.

    The terraform 0.13upgrade command included in Terraform v0.13 will automatically generate a suitable source address for each provider your module is using, by referring to a table which maps provider names as understood by Terraform v0.12 and earlier to the fully-qualified provider source addresses expected by Terraform v0.13 and later. Only the ones that are maintained by HashiCorp (as opposed to being maintained by a third-party but previously distributed by HashiCorp) are in the hashicorp namespace, and so using that tool will ensure that you'll specify addresses that correspond to the providers that Terraform v0.12 would've installed for the same configuration.