Terraform v0.13 introduces a new provider source
attribute that allows you to
declare the registry source of a terraform provider. This attribute is part of
the required_providers
setting inside a terraform
configuration block.
The Registry currently indexes Official and
Partner providers, and later work will allow for community providers as well,
which Terraform will automatically download and install on terraform init
.
- providers in the registry namespace
- benefits: splitting hashi and partner apart for ease of publishing, enabling community providers
- why so complicated? we will inevitably have naming colissions - forks, generic names, etc - and need to be ready for that before it happens
terraform {
required_providers {
// HashiCorp's dns provider
hdns = {
source = "hashicorp/dns"
}
// A hypothetical alternative dns provider
mydns = {
source = "mycorp/dns"
}
}
}
A provider source string is made up of the following parts:
[sourcehost]/[namespace]/type
source
and namespace
are optional for providers in the hashicorp
namespace
in the Terraform Registry. namespace
is always
required when hostname
is set.
Since there is potential for multiple providers with the same name, we are
introducing a new concept along side source
: a provider Fully-Qualified Name (FQN).
Inside Terraform, a provider FQN is created by parsing
the source string and extracting the host, namespace and type.
If "source" is omitted, terraform assumes that the provider is referring to a
provider in the hashicorp
namespace in the public registry. Terraform
therefore determines the following providers all have the same FQN,
"registry.terraform.io/hashicorp/random"
:
# A fully-qualified source string includes the host, namespace and type
random = {
source = "registry.terraform.io/hashicorp/random"
}
# If the host is omitted, terraform assumes that the host is
# "registry.terraform.io".
random = {
source = "hashicorp/random"
}
# This is the same as the example above; source is case-insensitive.
random = {
source = "HashiCorp/random"
}
# If the source string only includes the type, terraform assumes that the host
# is "registry.terraform.io" and the namespace is "hashicorp".
random = {
source = "random"
}
# If there is no source, terraform assumes that the host is "registry.terraform.io",
# the namespace is "hashicorp", and the type is the map key (random).
random = {}
If you have multiple providers with the same type in a single configuration, you can declare a module-specific local name for each provider to easily identify them in your configuration.
In the following example, two providers with the same type ("dns"
) are declared.
One is given the local name "hdns"
and the other is called "mydns"
:
terraform {
required_providers {
// HashiCorp's dns provider
hdns = {
source = "hashicorp/dns"
}
// A hypothetical alternative dns provider
mydns = {
source = "mycorp/dns"
}
}
}
Use the local name as the label when configuring the provider in a provider
block:
provider "hdns" {
// "hashicorp/dns" provider configuration
}
provider "mydns" {
// "mycorp/dns" provider configuration
}
If the local name is not the same as the provider type, you must specify the provider for each resource:
resource "dns_record" {
provider = "hdns"
// resource configuration
}
resource "dns_record_set" {
provider = "mydns"
// resource configuration
}
- terraform needs a way to tell providers on disk apart - binary name is no longer sufficient - so we've created a new Adirectory hierarchy that Terraform can use to precisely determine the FQN of each provider it finds on disk:
$PLUGIN_DIRECTORY/$SOURCEHOST/$SOURCENAMESPACE/$NAME/$VERSION/$OS_$ARCH/
- third-party provider plugins - locally installed providers, not on the registry - need to be assigned an (arbitrary) source and placed in the appropriate subdirectory for terraform to find and use them.
When installing custom plugins, you may choose any arbitrary identifier (comprised of letters and hyphens) for the $SOURCEHOST and $SOURCENAMESPACE subdirectories.
For example, if you wanted to use the community-created dominoes
provider
providers {
customplugin = {
versions = ["0.1"]
source = "example.com/myorg/customplugin"
}
}
The binary must be placed in the following directory:
./plugins/example.com/myorg/customplugin/0.1/linux_amd64/
Advanced topic, most users don't need these details. Exception: local providers!
- new layout structure
- new configuration
You will need to upgrade your configuration by adding a required_providers
entry for any providers in your configuration except HashiCorp-owned
providers.
A new 0.13upgrade command is available. This command will analyze your
configuration and write a required_providers
entry for each provider in your
configuration. [ note about locally installed providers]