Skip to content

Instantly share code, notes, and snippets.

@pkolyvas
Forked from mildwonkey/ps-writing.md
Last active May 15, 2020 21:53
Show Gist options
  • Save pkolyvas/2c0e9673c9328a6ed39445690859659c to your computer and use it in GitHub Desktop.
Save pkolyvas/2c0e9673c9328a6ed39445690859659c to your computer and use it in GitHub Desktop.

Terraform v0.13

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.

Background

  • 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

Provider Source

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 = {}

Local Name

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
}

Third-party Providers

  • 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/

Changes to the provider installer

Advanced topic, most users don't need these details. Exception: local providers!

  • new layout structure
  • new configuration

Upgrade Steps

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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment