From 0e5651560b8e74cbbfddc0a188887c490d3ae4d5 Mon Sep 17 00:00:00 2001 From: Nick Fagerlund Date: Thu, 30 Jul 2020 21:07:36 -0700 Subject: [PATCH] Website: 0.13 docs edits, mostly around provider requirements (#25686) * Make sidebar nav in language docs more intuitive * Minor display fixes for registry docs * Explain providers in the registry in the providers index * Revise a bunch of language docs around provider reqs This is mostly an effort to smooth out some of the explanations, make sure things are presented in a helpful order, make sure terminology lines up, draw connections between related concepts, make default behavior more apparent, and the like. It shouldn't include very much new information, but there might be one or two things that came out of a conversation somewhere. Co-authored-by: Judith Malnick --- .../docs/commands/cli-config.html.markdown | 13 +- .../docs/configuration/data-sources.html.md | 13 +- website/docs/configuration/index.html.md | 9 + website/docs/configuration/modules.html.md | 193 ++++++----- .../provider-requirements.html.md | 318 +++++++++++------- website/docs/configuration/providers.html.md | 205 +++++------ website/docs/configuration/resources.html.md | 126 +++++-- website/docs/configuration/terraform.html.md | 13 +- .../provider-registry-protocol.html.md | 2 +- website/docs/modules/publish.html.markdown | 4 +- website/docs/providers/index.html.markdown | 56 ++- website/docs/registry/providers/os-arch.md | 10 +- .../registry/providers/publishing.html.md | 8 +- website/layouts/docs.erb | 8 +- 14 files changed, 588 insertions(+), 390 deletions(-) diff --git a/website/docs/commands/cli-config.html.markdown b/website/docs/commands/cli-config.html.markdown index 9e76cb5ad..20f19a66b 100644 --- a/website/docs/commands/cli-config.html.markdown +++ b/website/docs/commands/cli-config.html.markdown @@ -93,6 +93,10 @@ credentials "app.terraform.io" { } ``` +If you are running the Terraform CLI interactively on a computer with a web browser, you can use [the `terraform login` command](./login.html) +to get credentials and automatically save them in the CLI configuration. If +not, you can manually write `credentials` blocks. + You can have multiple `credentials` blocks if you regularly use services from multiple hosts. Many users will configure only one, for either Terraform Cloud (at `app.terraform.io`) or for their organization's own @@ -112,11 +116,6 @@ is available at multiple hostnames, use only one of them consistently. Terraform Cloud responds to API calls at both its current hostname `app.terraform.io`, and its historical hostname `atlas.hashicorp.com`. -If you are running the Terraform CLI interactively on a computer that is capable -of also running a web browser, you can optionally obtain credentials and save -them in the CLI configuration automatically using -[the `terraform login` command](./login.html). - ### Credentials Helpers If you would prefer not to store your API tokens directly in the CLI @@ -154,8 +153,8 @@ The default way to install provider plugins is from a provider registry. The origin registry for a provider is encoded in the provider's source address, like `registry.terraform.io/hashicorp/aws`. For convenience in the common case, Terraform allows omitting the hostname portion for providers on -`registry.terraform.io`, so we'd normally write `hashicorp/aws` instead in -this case. +`registry.terraform.io`, so you can write shorter public provider addresses like +`hashicorp/aws`. Downloading a plugin directly from its origin registry is not always appropriate, though. For example, the system where you are running Terraform diff --git a/website/docs/configuration/data-sources.html.md b/website/docs/configuration/data-sources.html.md index 8a650c340..d9042985a 100644 --- a/website/docs/configuration/data-sources.html.md +++ b/website/docs/configuration/data-sources.html.md @@ -188,24 +188,23 @@ support the same [meta-arguments](./resources.html#meta-arguments) of resources with the exception of the [`lifecycle` configuration block](./resources.html#lifecycle-lifecycle-customizations). -### Multiple Provider Instances +### Non-Default Provider Configurations -Similarly to [resources](./resources.html), the -`provider` meta-argument can be used where a configuration has -multiple aliased instances of the same provider: +Similarly to [resources](./resources.html), when a module has multiple configurations for the same provider you can specify which configuration to use with the `provider` meta-argument: ```hcl data "aws_ami" "web" { - provider = "aws.west" + provider = aws.west # ... } ``` -See [Resources: Multiple Provider Instances](./resources.html#provider-selecting-a-non-default-provider-configuration) +See +[Resources: Selecting a Non-Default Provider Configuration](./resources.html#provider-selecting-a-non-default-provider-configuration) for more information. -### Data Source Lifecycle +## Data Source Lifecycle If the arguments of a data instance contain no references to computed values, such as attributes of resources that have not yet been created, then the diff --git a/website/docs/configuration/index.html.md b/website/docs/configuration/index.html.md index c7d05816b..0287b1105 100644 --- a/website/docs/configuration/index.html.md +++ b/website/docs/configuration/index.html.md @@ -125,6 +125,15 @@ practical network configuration will often contain additional elements not shown here. ```hcl +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 1.0.4" + } + } +} + variable "aws_region" {} variable "base_cidr_block" { diff --git a/website/docs/configuration/modules.html.md b/website/docs/configuration/modules.html.md index 7952a8fb5..64cd3cf45 100644 --- a/website/docs/configuration/modules.html.md +++ b/website/docs/configuration/modules.html.md @@ -61,7 +61,7 @@ and used for its own purposes; we will discuss those throughout the rest of this section. All modules require a `source` argument, which is a meta-argument defined by -Terraform CLI. Its value is either the path to a local directory of the +Terraform. Its value is either the path to a local directory containing the module's configuration files, or a remote module source that Terraform should download and use. This value must be a literal string with no template sequences; arbitrary expressions are not allowed. For more information on @@ -98,10 +98,72 @@ resource "aws_elb" "example" { For more information about referring to named values, see [Expressions](./expressions.html). +## Transferring Resource State Into Modules + +When refactoring an existing configuration to split code into child modules, +moving resource blocks between modules causes Terraform to see the new location +as an entirely different resource from the old. Always check the execution plan +after moving code across modules to ensure that no resources are deleted by +surprise. + +If you want to make sure an existing resource is preserved, use +[the `terraform state mv` command](/docs/commands/state/mv.html) to inform +Terraform that it has moved to a different module. + +When passing resource addresses to `terraform state mv`, resources within child +modules must be prefixed with `module..`. If a module was called +with `count` or `for_each` ([see below][inpage-multiple]), its resource +addresses must be prefixed with `module.[].` instead, where +`` matches the `count.index` or `each.key` value of a particular module +instance. + +Full resource addresses for module contents are used within the UI and on the +command line, but cannot be used within a Terraform configuration. Only +[outputs](docs/configuration/outputs.html) from a module can be referenced from +elsewhere in your configuration. + +## Other Meta-arguments + +Along with the `source` meta-argument described above, module blocks have +some optional meta-arguments that have special meaning across all modules, +described in more detail below: + +- `version` - A [version constraint string](./version-constraints.html) + that specifies acceptable versions of the module. Described in detail under + [Module Versions][inpage-versions] below. + +- `count` and `foreach` - Both of these arguments create multiple instances of a + module from a single `module` block. Described in detail under + [Multiple Instances of a Module][inpage-multiple] below. + +- `providers` - A map whose keys are provider configuration names + that are expected by child module and whose values are the corresponding + provider configurations in the calling module. This allows + [provider configurations to be passed explicitly to child modules](#passing-providers-explicitly). + If not specified, the child module inherits all of the default (un-aliased) + provider configurations from the calling module. Described in detail under + [Providers Within Modules][inpage-providers] + +- `depends_on` - Creates explicit dependencies between the entire + module and the listed targets. This will delay the final evaluation of the + module, and any sub-modules, until after the dependencies have been applied. + Modules have the same dependency resolution behavior + [as defined for managed resources](./resources.html#resource-dependencies). + +In addition to the above, the `lifecycle` argument is not currently used by +Terraform but is reserved for planned future features. + +Since modules are a complex feature in their own right, further detail +about how modules can be used, created, and published is included in +[the dedicated section on modules](/docs/modules/index.html). + ## Module Versions -We recommend explicitly constraining the acceptable version numbers for -each external module to avoid unexpected or unwanted changes. +[inpage-versions]: #module-versions + +When using modules installed from a module registry, we recommend explicitly +constraining the acceptable version numbers to avoid unexpected or unwanted +changes. Use the `version` attribute in the `module` block to specify versions: @@ -130,6 +192,12 @@ version as their caller. ## Multiple Instances of a Module +[inpage-multiple]: #multiple-instances-of-a-module + +-> **Note:** Module support for the `for_each` and `count` meta-arguments was +added in Terraform 0.13. Previous versions can only use these arguments with +individual resources. + Use the `for_each` or the `count` argument to create multiple instances of a module from a single `module` block. These arguments have the same syntax and type constraints as @@ -172,7 +240,7 @@ a bucket. We declare multiple module instances by using the `for_each` attribute, which accepts a map (with string keys) or a set of strings as its value. Additionally, -we use the `each.key` in our module block, because the +we use the special `each.key` value in our module block, because the [`each`](/docs/configuration/resources.html#the-each-object) object is available when we have declared `for_each` on the module block. When using the `count` argument, the [`count`](/docs/configuration/resources.html#the-count-object) object is available. @@ -184,45 +252,11 @@ name suffices to reference the module. In our example, the `./publish_bucket` module contains `aws_s3_bucket.example`, and so the two instances of this module produce S3 bucket resources with [resource addresses](/docs/internals/resource-addressing.html) of `module.bucket["assets"].aws_s3_bucket.example` -and `module.bucket["media"].aws_s3_bucket.example` respectively. These full addresses -are used within the UI and on the command line, but only [outputs](docs/configuration/outputs.html) -from a module can be referenced from elsewhere in your configuration. +and `module.bucket["media"].aws_s3_bucket.example` respectively. -When refactoring an existing configuration to introduce modules, moving -resource blocks between modules causes Terraform to see the new location -as an entirely separate resource to the old. Always check the execution plan -after performing such actions to ensure that no resources are surprisingly -deleted. +## Providers Within Modules -## Other Meta-arguments - -Along with the `source` meta-argument described above, module blocks have -some more meta-arguments that have special meaning across all modules, -described in more detail in other sections: - -* `version` - (Optional) A [version constraint string](./version-constraints.html) - that specifies acceptable versions of the module. Described in detail above. - -* `providers` - (Optional) A map whose keys are provider configuration names - that are expected by child module and whose values are corresponding - provider names in the calling module. This allows - [provider configurations to be passed explicitly to child modules](#passing-providers-explicitly). - If not specified, the child module inherits all of the default (un-aliased) - provider configurations from the calling module. - -* `depends_on` - (Optional) Create explicit dependencies between the entire - module and the listed targets. This will delay the final evaluation of the - module, and any sub-modules, until after the dependencies have been applied. - Modules have the same dependency resolution behavior [as defined for managed resources](./resources.html#resource-dependencies). - -In addition to the above, the `lifecycle` argument is not currently used by -Terraform but is reserved for planned future features. - -Since modules are a complex feature in their own right, further detail -about how modules can be used, created, and published is included in -[the dedicated section on modules](/docs/modules/index.html). - -## Providers within Modules +[inpage-providers]: #providers-within-modules In a configuration with multiple modules, there are some special considerations for how resources are associated with provider configurations. @@ -247,7 +281,7 @@ below. For backward compatibility with configurations targeting Terraform v0.10 and earlier Terraform does not produce an error for a `provider` block in a shared module if the `module` block only uses features available in Terraform v0.10, -but that is a legacy usage pattern that is no longer recommended and a legacy +but that is a legacy usage pattern that is no longer recommended. A legacy module containing its own provider configurations is not compatible with the `for_each`, `count`, and `depends_on` arguments that were introduced in Terraform v0.13. For more information, see @@ -335,20 +369,20 @@ resource "aws_s3_bucket" "example" { } ``` -This approach is recommended in the common case where only a single -configuration is needed for each provider across the entire configuration. +We recommend using this approach when a single configuration for each provider +is sufficient for an entire configuration. -In more complex situations there may be [multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances), +In more complex situations there may be +[multiple provider configurations](/docs/configuration/providers.html#alias-multiple-provider-configurations), or a child module may need to use different provider settings than -its parent. For such situations, it's necessary to pass providers explicitly -as we will see in the next section. +its parent. For such situations, you must pass providers explicitly. ### Passing Providers Explicitly When child modules each need a different configuration of a particular provider, or where the child module requires a different provider configuration -than its parent, the `providers` argument within a `module` block can be -used to define explicitly which provider configs are made available to the +than its parent, you can use the `providers` argument within a `module` block +to explicitly define which provider configurations are available to the child module. For example: ```hcl @@ -358,14 +392,14 @@ provider "aws" { region = "us-west-1" } -# A non-default, or "aliased" configuration is also defined for a different -# region. +# An alternate configuration is also defined for a different +# region, using the alias "usw2". provider "aws" { alias = "usw2" region = "us-west-2" } -# An example child module is instantiated with the _aliased_ configuration, +# An example child module is instantiated with the alternate configuration, # so any AWS resources it defines will use the us-west-2 region. module "example" { source = "./example" @@ -376,10 +410,13 @@ module "example" { ``` The `providers` argument within a `module` block is similar to -the `provider` argument within a resource as described for -[multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances), -but is a map rather than a single string because a module may contain resources -from many different providers. +[the `provider` argument](resources.html#provider-selecting-a-non-default-provider-configuration) +within a resource, but is a map rather than a single string because a module may +contain resources from many different providers. + +The keys of the `providers` map are provider configuration names as expected by +the child module, and the values are the names of corresponding configurations +in the _current_ module. Once the `providers` argument is used in a `module` block, it overrides all of the default inheritance behavior, so it is necessary to enumerate mappings @@ -407,18 +444,15 @@ provider "aws" { module "tunnel" { source = "./tunnel" providers = { - aws.src = "aws.usw1" - aws.dst = "aws.usw2" + aws.src = aws.usw1 + aws.dst = aws.usw2 } } ``` -In the `providers` map, the keys are provider names as expected by the child -module, while the values are the names of corresponding configurations in -the _current_ module. The subdirectory `./tunnel` must then contain -_proxy configuration blocks_ like the following, to declare that it -requires configurations to be passed with these from the `providers` block in -the parent's `module` block: +The subdirectory `./tunnel` must then contain _proxy configuration blocks_ like +the following, to declare that it requires its calling module to pass +configurations with these names in its `providers` argument: ```hcl provider "aws" { @@ -431,22 +465,22 @@ provider "aws" { ``` Each resource should then have its own `provider` attribute set to either -`"aws.src"` or `"aws.dst"` to choose which of the two provider instances to use. +`aws.src` or `aws.dst` to choose which of the two provider configurations to +use. ### Proxy Configuration Blocks -A proxy configuration block is one that is either completely empty or that -contains only the `alias` argument. It serves as a placeholder for -provider configurations passed between modules. Although an empty proxy -configuration block is valid, it is not necessary: proxy configuration blocks -are needed only to establish which _alias_ provider configurations a child -module is expecting. +A proxy configuration block is one that contains only the `alias` argument. It +serves as a placeholder for provider configurations passed between modules, and +declares that a module expects to be explicitly passed an additional (aliased) +provider configuration. -A proxy configuration block declares that a module is expecting to be -explicitly passed an additional (aliased) provider configuration. Don't use a -proxy configuration block if a module only needs a single default provider -configuration, and don't use proxy configuration blocks only to imply -[provider requirements](provider-requirements.html). +-> **Note:** Although a completely empty proxy configuration block is also +valid, it is not necessary: proxy configuration blocks are needed only to +establish which _aliased_ provider configurations a child module expects. +Don't use a proxy configuration block if a module only needs a single default +provider configuration, and don't use proxy configuration blocks only to imply +[provider requirements](./provider-requirements.html). ## Legacy Shared Modules with Provider Configurations @@ -480,9 +514,8 @@ those unfortunately conflicted with the support for the legacy pattern. To retain the backward compatibility as much as possible, Terraform v0.13 continues to support the legacy pattern for module blocks that do not use these new features, but a module with its own provider configurations is not -compatible with `for_each`, `count`, or `depends_on` and so Terraform will -produce an error announcing that if you attempt to combine these features. For -example: +compatible with `for_each`, `count`, or `depends_on`. Terraform will produce an +error if you attempt to combine these features. For example: ``` Error: Module does not support count @@ -533,7 +566,7 @@ module "child" { } ``` -Due to the association between resources and provider configurations being +Since the association between resources and provider configurations is static, module calls using `for_each` or `count` cannot pass different provider configurations to different instances. If you need different instances of your module to use different provider configurations then you diff --git a/website/docs/configuration/provider-requirements.html.md b/website/docs/configuration/provider-requirements.html.md index a6ac7d403..c906d3d4a 100644 --- a/website/docs/configuration/provider-requirements.html.md +++ b/website/docs/configuration/provider-requirements.html.md @@ -3,29 +3,73 @@ layout: "docs" page_title: "Provider Requirements - Configuration Language" --- -## Provider Requirements +# Provider Requirements --> **Note:** If you are using Terraform 0.11 or -earlier, see +-> **Note:** This page is about a feature of Terraform 0.13 and later; it also +describes how to use the more limited version of that feature that was available +in Terraform 0.12. If you are using Terraform 0.11 or earlier, see [0.11 Configuration Language: Provider Versions](../configuration-0-11/providers.html#provider-versions) instead. Terraform relies on plugins called "providers" to interact with remote systems. -Each provider offers a set of named + +Terraform configurations must declare which providers they require, so that +Terraform can install and use them. Additionally, some providers require +configuration (like endpoint URLs or cloud regions) before they can be used. + +- This page documents how to declare providers so Terraform can install them. + +- The [Provider Configuration](./providers.html) page documents how to configure + settings for providers. + +## About Providers + +Providers are plugins. They are released on a separate rhythm from Terraform +itself, and each provider has its own series of version numbers. + +Each provider plugin offers a set of [resource types](resources.html#resource-types-and-arguments), and defines for each resource type which arguments it accepts, which attributes it exports, and how changes to resources of that type are actually applied to remote APIs. -You can discover publicly-available providers -[via the Terraform Registry](https://registry.terraform.io/browse/providers). -Which providers you will use will depend on which remote cloud services you are -intending to configure. Additionally, some Terraform providers provide -local-only functionality which is useful to integrate functionality offered by -different providers, such as generating random numbers to help construct -unique resource names. +Most providers configure a specific infrastructure platform (either cloud or +self-hosted). Providers can also offer local utilities for tasks like +generating random numbers for unique resource names. -Once you've selected one or more providers, use a `required_providers` block to -declare them so that Terraform will make them available for use. A provider -dependency consists of both a source location and a version constraint: +The [Terraform Registry](https://registry.terraform.io/browse/providers) +is the main directory of publicly available Terraform providers, and hosts +providers for most major infrastructure platforms. You can also write and +distribute your own Terraform providers, for public or private use. + +### Provider Installation + +Terraform finds and installs providers when +[initializing a working directory](/docs/commands/init.html). It can +automatically download providers from a Terraform registry, or load them from a +local mirror or cache. + +When a new provider is added to a configuration, Terraform must install the +provider before it can be used. If you are using a persistent working directory, +you can run `terraform init` again to install new providers. + +Providers downloaded by `terraform init` are only installed for the current +working directory; other working directories can have their own installed +provider plugins, which might be different versions. + +To save time and bandwidth, Terraform supports an optional plugin cache. You can +enable the cache using the `plugin_cache_dir` setting in +[the CLI configuration file](/docs/commands/cli-config.html). + +For more information about provider installation, see +[the `terraform init` command](/docs/commands/init.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: ```hcl terraform { @@ -38,14 +82,12 @@ terraform { } ``` -The `required_providers` block must be nested inside a -[`terraform` block](terraform.html). The `terraform` block can include other -settings too, but we'll only focus on `required_providers` here. +The `required_providers` block must be nested inside the top-level +[`terraform` block](terraform.html) (which can also contain other settings). -The keys inside the `required_providers` block represent each provider's -[local name](#local-names), which is the unique identifier for a provider within -a particular module. Each item inside the `required_providers` block is an -object expecting the following arguments: +Each argument in the `required_providers` block enables one provider. The key +determines the provider's [local name](#local-names) (its unique identifier +within this module), and the value is an object with the following elements: * `source` - the global [source address](#source-addresses) for the provider you intend to use, such as `hashicorp/aws`. @@ -53,51 +95,32 @@ object expecting the following arguments: * `version` - a [version constraint](#version-constraints) specifying which subset of available provider versions the module is compatible with. --> **Note:** The `required_providers` object syntax described above was added in Terraform v0.13. Previous versions of Terraform used a single string instead of an object, with the string specifying only a version constraint. For example, `mycloud = "~> 1.0"`. Explicit provider source addresses are supported only in Terraform v0.13 and later. If you want to write a module that works with both Terraform v0.12 and v0.13, see [v0.12-Compatible Provider Requirements](#v012-compatible-provider-requirements) below. +-> **Note:** The `name = { source, version }` syntax for `required_providers` +was added in Terraform v0.13. Previous versions of Terraform used a version +constraint string instead of an object (like `mycloud = "~> 1.0"`), and had no +way to specify provider source addresses. If you want to write a module that +works with both Terraform v0.12 and v0.13, see [v0.12-Compatible Provider +Requirements](#v012-compatible-provider-requirements) below. -### Source Addresses +## Names and Addresses -A provider _source address_ both globally identifies a particular provider and -specifies the primary location from which Terraform can download it. -Source addresses consist of three parts delimited by slashes (`/`), as -follows: +Each provider has two identifiers: -* **Hostname**: the hostname of the Terraform registry that indexes the provider. - You can omit the hostname portion and its following slash if the provider - is hosted on [the public Terraform Registry](https://registry.terraform.io/), - whose hostname is `registry.terraform.io`. +- A unique _source address,_ which is only used when requiring a provider. +- A _local name,_ which is used everywhere else in a Terraform module. -* **Namespace**: an organizational namespace within the specified registry. - For the public Terraform Registry and Terraform Cloud's private registry, - this represents the organization that is publishing the provider. This field - may have other meanings for other registry hosts. - -* **Type**: The provider type name, which must be unique within a particular - namespace on a particular registry host. - -For example, -[the official HTTP provider](https://registry.terraform.io/providers/hashicorp/http) -belongs to the `hashicorp` namespace on `registry.terraform.io`, so its -source address can be written as either `registry.terraform.io/hashicorp/http` -or, more commonly, just `hashicorp/http`. - --> **Note**: As a concession for backward compatibility with earlier versions of -Terraform, the `source` argument is actually optional. If you omit it, Terraform -will construct an implied source address by appending the local name to the prefix -`hashicorp/`. For example, a provider dependency with local name `http` that -does not have an explicit `source` will be treated as equivalent to -`hashicorp/http`. We recommend using explicit source addresses for all providers -in modules that require Terraform 0.13 or later, so a future reader of your -module can clearly see exactly which provider is required, without needing to -first understand this default behavior. +-> **Note:** Prior to Terraform 0.13, providers only had local names, since +Terraform could only automatically download providers distributed by HashiCorp. ### Local Names -Full [source addresses](#source-addresses) are verbose, so the Terraform -language uses them only when declaring dependencies. We associate each required -provider with a module-specific _local name_, which is a short identifier that -will refer to the associated source address within declarations inside a -particular module. +Local names are module-specific, and are assigned when requiring a provider. +Local names must be unique per-module. + +Outside of the `required_providers` block, Terraform configurations always refer +to providers by their local names. For example, the following configuration +declares `mycloud` as the local name for `mycorp/mycloud`, then uses that local +name when [configuring the provider](./providers.html): ```hcl terraform { @@ -108,31 +131,77 @@ terraform { } } } -``` -The above example declares `mycloud` as the local name for `mycorp/mycloud` -(which is short for `registry.terraform.io/mycorp/mycloud`) in the current -module only. That means we will refer to this provider as `mycloud` elsewhere -in the module, such as in a `provider "mycloud"` block used to create a -[provider configuration](providers.html): - -```hcl provider "mycloud" { # ... } ``` -We strongly recommend setting the local name of a provider to match the "type" -portion of its source address, as in the above example. Consistent use of the -provider's canonical type can help avoid the need for readers of the rest of -the module to refer to the `required_providers` block to understand which -provider the module is using. +Users of a provider can choose any local name for it. However, nearly every +provider has a _preferred local name,_ which it uses as a prefix for all of its +resource types. (For example, resources from `hashicorp/aws` all begin with +`aws`, like `aws_instance` or `aws_security_group`.) -The one situation where it is reasonable to use a different local name is the -relatively-rare case of having two providers in the same module that have the -same type name. In that case, Terraform requires choosing a unique local name -for each one. In that situation, we recommend to combine the namespace with -the type name to produce a compound local name to disambiguate: +Whenever possible, you should use a provider's preferred local name. This makes +your configurations easier to understand, and lets you omit the `provider` +meta-argument from most of your resources. (If a resource doesn't specify which +provider configuration to use, Terraform interprets the first word of the +resource type as a local provider name.) + +### Source Addresses + +A provider's source address is its global identifier. It also specifies the +primary location where Terraform can download it. + +Source addresses consist of three parts delimited by slashes (`/`), as +follows: + +`[/]/` + +* **Hostname** (optional): The hostname of the Terraform registry that + distributes the provider. If omitted, this defaults to + `registry.terraform.io`, the hostname of + [the public Terraform Registry](https://registry.terraform.io/). + +* **Namespace:** An organizational namespace within the specified registry. + For the public Terraform Registry and for Terraform Cloud's private registry, + this represents the organization that publishes the provider. This field + may have other meanings for other registry hosts. + +* **Type:** A short name for the platform or system the provider manages. Must + be unique within a particular namespace on a particular registry host. + + The type is usually the provider's preferred local name. (There are + exceptions; for example, + [`hashicorp/google-beta`](https://registry.terraform.io/providers/hashicorp/google-beta/latest) + is an alternate release channel for `hashicorp/google`, so its preferred + local name is `google`. If in doubt, check the provider's documentation.) + +For example, +[the official HTTP provider](https://registry.terraform.io/providers/hashicorp/http) +belongs to the `hashicorp` namespace on `registry.terraform.io`, so its +source address is `registry.terraform.io/hashicorp/http` or, more commonly, just +`hashicorp/http`. + +-> **Note:** If you omit the `source` argument when requiring a provider, +Terraform uses an implied source address of +`registry.terraform.io/hashicorp/`. This is a backward compatibility +feature to support the transition to Terraform 0.13; in modules that require +0.13 or later, we recommend using explicit source addresses for all providers. + +### Handling Local Name Conflicts + +Whenever possible, we recommend using a provider's preferred local name, which +is usually the same as the "type" portion of its source address. + +However, it's sometimes necessary to use two providers with the same preferred +local name in the same module, usually when the providers are named after a +generic infrastructure type. Terraform requires unique local names for each +provider in a module, so you'll need to use a non-preferred name for at least +one of them. + +When this happens, we recommend combining each provider's namespace with +its type name to produce compound local names: ```hcl terraform { @@ -156,9 +225,20 @@ terraform { provider "mycorp_http" { # ... } + +data "http" "example" { + provider = hashicorp_http + #... +} ``` -### Version Constraints +Terraform won't be able to guess either provider's name from its resource types, +so you'll need to specify a `provider` meta-argument for every affected +resource. However, readers and maintainers of your module will be able to easily +understand what's happening, and avoiding confusion is much more important than +avoiding typing. + +## Version Constraints A [source address](#source-addresses) uniquely identifies a particular provider, but each provider can have one or more distinct _versions_, allowing @@ -166,10 +246,16 @@ the functionality of the provider to evolve over time. Each provider dependency you declare should have a [version constraint](./version-constraints.html) given in the `version` argument. +The `version` argument is optional; if omitted, Terraform will accept any +version of the provider as compatible. However, we strongly recommend specifying +a version constraint for every provider your module depends on. + +### Best Practices for Provider Versions + Each module should at least declare the minimum provider version it is known to work with, using the `>=` version constraint syntax: -``` +```hcl terraform { required_providers { mycloud = { @@ -180,13 +266,13 @@ terraform { } ``` -A module intended to be used as the root of a configuration -- that is, as the -directory where you'd run `terraform apply` -- should also specify the +A module intended to be used as the root of a configuration — that is, as the +directory where you'd run `terraform apply` — should also specify the _maximum_ provider version it is intended to work with, to avoid accidental -upgrading when new versions are released. The `~>` operator is a convenient +upgrades to incompatible new versions. The `~>` operator is a convenient shorthand for allowing only patch releases within a specific minor release: -``` +```hcl terraform { required_providers { mycloud = { @@ -197,21 +283,14 @@ terraform { } ``` -_Do not_ use the `~>` or other maximum-version constraints for modules you -intend to reuse across many configurations. All of the version constraints -across all modules in a configuration must work collectively to select a -single version to use, so many modules all specifying maximum version -constraints would require those upper limits to all be updated simultaneously -if one module begins requiring a newer provider version. +Do not use `~>` (or other maximum-version constraints) for modules you intend to +reuse across many configurations, even if you know the module isn't compatible +with certain newer versions. Doing so can sometimes prevent errors, but more +often it forces users of the module to update many modules simultaneously when +performing routine upgrades. Specify a minimum version, document any known +incompatibilities, and let the root module manage the maximum version. -The `version` argument is optional. If you omit it, Terraform will accept -_any_ version of the provider as compatible. That's risky for a provider -distributed by a third-party, because they may release a version containing -breaking changes at any time and prevent you from making progress until you -update your configuration. We strongly recommend always specifying a version -constraint, as described above, for every provider your module depends on. - -### Built-in Providers +## Built-in Providers While most Terraform providers are distributed separately as plugins, there is currently one provider that is built in to Terraform itself, which @@ -232,9 +311,14 @@ that was used by older versions of Terraform. `hashicorp/terraform` is not compatible with Terraform v0.11 or later and should never be declared in a `required_providers` block. -### In-house Providers +## In-house Providers -Some organizations develop their own providers to allow interacting with +Anyone can develop and distribute their own Terraform providers. (See +the [Call APIs with Terraform Providers](https://learn.hashicorp.com/terraform/providers/provider-use?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) +track on HashiCorp Learn for more +about provider development.) + +Some organizations develop their own providers to configure proprietary systems, and wish to use these providers from Terraform without publishing them on the public Terraform Registry. @@ -243,19 +327,19 @@ registry, by implementing [the provider registry protocol](/docs/internals/provider-registry-protocol.html). Running an additional service just to distribute a single provider internally -may be undesirable though, so Terraform also supports -[other provider installation methods](https://github.com/hashicorp/terraform/blob/master/website/docs/commands/cli-config.html.markdown#provider-installation), +may be undesirable, so Terraform also supports +[other provider installation methods](/docs/commands/cli-config.html#provider-installation), including placing provider plugins directly in specific directories in the local filesystem, via _filesystem mirrors_. All providers must have a [source address](#source-addresses) that includes -(or implies) the hostname of a host registry, but for an in-house provider that -you intend only to distribute from a local filesystem directory you can choose -an artificial hostname in a domain your organization controls and use that to -mark your in-house providers. +(or implies) the hostname of a registry, but that hostname does not need to +provide an actual registry service. For in-house providers that you intend to +distribute from a local filesystem directory, you can use an arbitrary hostname +in a domain your organization controls. For example, if your corporate domain were `example.com` then you might choose -to use `terraform.example.com` as your artificial hostname, even if that +to use `terraform.example.com` as your placeholder hostname, even if that hostname doesn't actually resolve in DNS. You can then choose any namespace and type you wish to represent your in-house provider under that hostname, giving a source address like `terraform.example.com/examplecorp/ourcloud`: @@ -285,27 +369,27 @@ platform where you are running Terraform, such as `linux_amd64` for Linux on an AMD64/x64 processor, and then place the provider plugin executable and any other needed files in that directory. -The provider plugin executable file might therefore be at the following path, -on a Windows system for the sake of example: +Thus, on a Windows system, the provider plugin executable file might be at the +following path: ``` terraform.example.com/examplecorp/ourcloud/1.0.0/windows_amd64/terraform-provider-ourcloud.exe ``` -If you later decide to switch to using a real private provider registry, rather -than an artifical local hostname, you can deploy the registry server at +If you later decide to switch to using a real private provider registry rather +than distribute binaries out of band, you can deploy the registry server at `terraform.example.com` and retain the same namespace and type names, in which case your existing modules will require no changes to locate the same provider -using your registry server instead. +using your registry server. -### v0.12-Compatible Provider Requirements +## v0.12-Compatible Provider Requirements Explicit provider source addresses were introduced with Terraform v0.13, so the full provider requirements syntax is not supported by Terraform v0.12. However, in order to allow writing modules that are compatible with both -Terraform v0.12 and v0.13 at the same time, later versions of Terraform v0.12 -will accept but ignore the `source` argument in a required_providers block. +Terraform v0.12 and v0.13, versions of Terraform between v0.12.26 and v0.13 +will accept but ignore the `source` argument in a `required_providers` block. Consider the following example written for Terraform v0.13: @@ -339,7 +423,7 @@ When writing a module that is compatible with both Terraform v0.12.26 and Terraform v0.13.0 or later, you must follow the following additional rules so that both versions will select the same provider to install: -* Use only providers that are automatically-installable under Terraform v0.12. +* Use only providers that can be automatically installed by Terraform v0.12. Third-party providers, such as community providers in the Terraform Registry, cannot be selected by Terraform v0.12 because it does not support the hierarchical source address namespace. @@ -351,7 +435,7 @@ that both versions will select the same provider to install: * If the provider belongs to the `hashicorp` namespace, as with the `hashicorp/aws` provider shown above, omit the `source` argument and allow - Terraform v0.13 select the `hashicorp` namespace by default. + Terraform v0.13 to select the `hashicorp` namespace by default. * Provider type names must always be written in lowercase. Terraform v0.13 treats provider source addresses as case-insensitive, but Terraform v0.12 @@ -360,6 +444,6 @@ that both versions will select the same provider to install: versions. This compatibility mechanism is provided as a temporary transitional aid only. -When Terraform v0.12 detects the use of the new `source` argument it doesn't +When Terraform v0.12 detects a use of the new `source` argument it doesn't understand, it will emit a warning to alert the user that it is disregarding the source address given in that argument. diff --git a/website/docs/configuration/providers.html.md b/website/docs/configuration/providers.html.md index 3c5cba3d3..7b1335867 100644 --- a/website/docs/configuration/providers.html.md +++ b/website/docs/configuration/providers.html.md @@ -13,21 +13,23 @@ earlier, see [0.11 Configuration Language: Providers](../configuration-0-11/providers.html). Terraform relies on plugins called "providers" to interact with remote systems. -Each provider offers a set of named -[resource types](resources.html#resource-types-and-arguments), and defines for -each resource type which arguments it accepts, which attributes it exports, and -how changes to resources of that type are actually applied to remote APIs. -Before you can use a particular provider, you must declare a dependency on it -using [provider requirements syntax](./provider-requirements.html). +Terraform configurations must declare which providers they require, so that +Terraform can install and use them. Additionally, some providers require +configuration (like endpoint URLs or cloud regions) before they can be used. -Some providers require additional configuration to specify information such -as endpoint URLs and regions. A _provider configuration_ allows specifying that -information once and then reusing it for many resources in the same -configuration. +- This page documents how to configure settings for providers. + +- The [Provider Requirements](./provider-requirements.html) page documents how + to declare providers so Terraform can install them. ## Provider Configuration +Provider configurations belong in the root module of a Terraform configuration. +(Child modules receive their provider configurations from the root module; for +more information, see +[Providers Within Modules](./modules.html#providers-within-modules).) + A provider configuration is created using a `provider` block: ```hcl @@ -38,79 +40,44 @@ provider "google" { ``` The name given in the block header (`"google"` in this example) is the -[local name](./provider-requirements.html#local-names) of the provider -to configure. +[local name](./provider-requirements.html#local-names) of the provider to +configure. This provider should already be included in a `required_providers` +block. -The body of the block (between `{` and `}`) contains configuration arguments -for the provider itself. Most arguments in this section are defined by -the provider itself; in this example both `project` and `region` -are specific to the `google` provider. +The body of the block (between `{` and `}`) contains configuration arguments for +the provider. Most arguments in this section are defined by the provider itself; +in this example both `project` and `region` are specific to the `google` +provider. -The configuration arguments defined by the provider may be assigned using -[expressions](./expressions.html), which can for example -allow them to be parameterized by input variables. However, since provider -configurations must be evaluated in order to perform any resource type action, -provider configurations may refer only to values that are known before -the configuration is applied. In particular, avoid referring to attributes -exported by other resources unless their values are specified directly in the -configuration. +You can use [expressions](./expressions.html) in the values of these +configuration arguments, but can only reference values that are known before the +configuration is applied. This means you can safely reference input variables, +but not attributes exported by resources (with an exception for resource +arguments that are specified directly in the configuration). + +A provider's documentation should list which configuration arguments it expects. +For providers distributed on the +[Terraform Registry](https://registry.terraform.io), versioned documentation is +available on each provider's page, via the "Documentation" link in the +provider's header. + +Some providers can use shell environment variables (or other alternate sources, +like VM instance profiles) as values for some of their arguments; when +available, we recommend using this as a way to keep credentials out of your +version-controlled Terraform code. There are also two "meta-arguments" that are defined by Terraform itself and available for all `provider` blocks: -- [`version`, for constraining the allowed provider versions][inpage-versions] - [`alias`, for using the same provider with different configurations for different resources][inpage-alias] +- [`version`, which we no longer recommend][inpage-versions] (use + [provider requirements](./provider-requirements.html) instead) Unlike many other objects in the Terraform language, a `provider` block may be omitted if its contents would otherwise be empty. Terraform assumes an empty default configuration for any provider that is not explicitly configured. -## Installation - -Each time a new provider is added to configuration -- either explicitly via -a `provider` block or by adding a resource from that provider without an -associated `provider` block -- Terraform must install the provider before -it can be used. Installation locates and downloads the provider's plugin so -that it can be executed later. - -Provider initialization is one of the actions of `terraform init`. Running -this command will install any providers that are not already installed. - -Providers downloaded by `terraform init` are only installed for the current -working directory; other working directories can have their own installed -provider plugins, which may be of differing versions. - -For more information, see -[the `terraform init` command](/docs/commands/init.html). - -## Provider Versions - -[inpage-versions]: #provider-versions - -Providers are plugins released on a separate rhythm from Terraform itself, and -so they have their own version numbers. For production use, you should -constrain the acceptable provider versions via configuration, to ensure that -new versions with breaking changes will not be automatically installed by -`terraform init` in future. - -For more information on specifying version constraints, see -[Provider Requirements](./provider-requirements.html). - -When you re-run `terraform init` with providers already installed, Terraform -will use an already-installed provider that meets the constraints in preference -to downloading a new version. To upgrade to the latest acceptable version -of each provider, run `terraform init -upgrade`. This command also upgrades -to the latest versions of all remote Terraform modules. - -In versions of Terraform prior to Terraform 0.12, provider version constraints -could be specified using a `version` argument within a `provider` block, which -would simultaneously declare a new provider requirement _and_ provider -configuration, but that overloading can cause problems particularly when -writing shared modules. For that reason, we recommend always omitting the -`version` argument within `provider` blocks, and specifying version -constraints instead using [Provider Requirements](./provider-requirements.html). - -## `alias`: Multiple Provider Instances +## `alias`: Multiple Provider Configurations [inpage-alias]: #alias-multiple-provider-instances @@ -119,32 +86,42 @@ select which one to use on a per-resource or per-module basis. The primary reason for this is to support multiple regions for a cloud platform; other examples include targeting multiple Docker hosts, multiple Consul hosts, etc. -To include multiple configurations for a given provider, include multiple -`provider` blocks with the same provider name, but set the `alias` meta-argument -to an alias name to use for each additional configuration. For example: +To create multiple configurations for a given provider, include multiple +`provider` blocks with the same provider name. For each additional non-default +configuration, use the `alias` meta-argument to provide an extra name segment. +For example: ```hcl -# The default provider configuration +# The default provider configuration; resources that begin with `aws_` will use +# it as the default, and it can be referenced as `aws`. provider "aws" { region = "us-east-1" } -# Additional provider configuration for west coast region +# Additional provider configuration for west coast region; resources can +# reference this as `aws.west`. provider "aws" { alias = "west" region = "us-west-2" } ``` -The `provider` block without `alias` set is known as the _default_ provider -configuration. When `alias` is set, it creates an _additional_ provider -configuration. For providers that have no required configuration arguments, the -implied _empty_ configuration is considered to be the _default_ provider -configuration. +### Default Provider Configurations -### Referring to Alternate Providers +A `provider` block without an `alias` argument is the _default_ configuration +for that provider. Resources that don't set the `provider` meta-argument will +use the default provider configuration that matches the first word of the +resource type name. (For example, an `aws_instance` resource uses the default +`aws` provider configuration unless otherwise stated.) -When Terraform needs the name of a provider configuration, it always expects a +If every explicit configuration of a provider has an alias, Terraform uses the +implied empty configuration as that provider's default configuration. (If the +provider has any required configuration arguments, Terraform will raise an error +when resources default to the empty configuration.) + +### Referring to Alternate Provider Configurations + +When Terraform needs the name of a provider configuration, it expects a reference of the form `.`. In the example above, `aws.west` would refer to the provider with the `us-west-2` region. @@ -153,15 +130,13 @@ entities (for example, `var.image_id`), they aren't strings and don't need to be quoted. But they are only valid in specific meta-arguments of `resource`, `data`, and `module` blocks, and can't be used in arbitrary expressions. -### Selecting Alternate Providers +### Selecting Alternate Provider Configurations -By default, resources use a default provider configuration inferred from the -first word of the resource type name. For example, a resource of type -`aws_instance` uses the default (un-aliased) `aws` provider configuration unless -otherwise stated. +By default, resources use a default provider configuration (one without an +`alias` argument) inferred from the first word of the resource type name. -To select an aliased provider for a resource or data source, set its `provider` -meta-argument to a `.` reference: +To use an alternate provider configuration for a resource or data source, set +its `provider` meta-argument to a `.` reference: ```hcl resource "aws_instance" "foo" { @@ -171,9 +146,9 @@ resource "aws_instance" "foo" { } ``` -To select aliased providers for a child module, use its `providers` -meta-argument to specify which aliased providers should be mapped to which local -provider names inside the module: +To select alternate provider configurations for a child module, use its +`providers` meta-argument to specify which provider configurations should be +mapped to which local provider names inside the module: ```hcl module "aws_vpc" { @@ -185,41 +160,29 @@ module "aws_vpc" { ``` Modules have some special requirements when passing in providers; see -[Providers within Modules](./modules.html#providers-within-modules) +[Providers Within Modules](./modules.html#providers-within-modules) for more details. In most cases, only _root modules_ should define provider configurations, with all child modules obtaining their provider configurations from their parents. -## Third-party Plugins + -Anyone can develop and distribute their own Terraform providers. (See -[Writing Custom Providers](/docs/extend/writing-custom-providers.html) for more -about provider development.) +## `version`: An Older Way to Manage Provider Versions -The main way to distribute a provider is via a provider registry, and the main -provider registry is -[part of the public Terraform Registry](https://registry.terraform.io/browse/providers), -along with public shared modules. +[inpage-versions]: #provider-versions -Installing directly from a registry is not appropriate for all situations, -though. If you are running Terraform from a system that cannot access some or -all of the necessary registry hosts, you can configure Terraform to obtain -providers from a local mirror instead. For more information, see -[Provider Installation](../commands/cli-config.html#provider-installation) -in the CLI configuration documentation. +The `version` meta-argument specifies a version constraint for a provider, and +works the same way as the `version` argument in a +[`required_providers` block](./provider_requirements.html). The version +constraint in a provider configuration is only used if `required_providers` +does not include one for that provider. -## Provider Plugin Cache +**We do not recommend using the `version` argument in provider configurations.** +In Terraform 0.13 and later, version constraints should always be declared in +[the `required_providers` block](./provider_requirements.html). -By default, `terraform init` downloads plugins into a subdirectory of the -working directory so that each working directory is self-contained. As a -consequence, if you have multiple configurations that use the same provider -then a separate copy of its plugin will be downloaded for each configuration. +-> **Note:** The `version` meta-argument made sense before Terraform 0.13, since +Terraform could only install providers that were distributed by HashiCorp. Now +that Terraform can install providers from multiple sources, it makes more sense +to keep version constraints and provider source addresses together. -Given that provider plugins can be quite large (on the order of hundreds of -megabytes), this default behavior can be inconvenient for those with slow -or metered Internet connections. Therefore Terraform optionally allows the -use of a local directory as a shared plugin cache, which then allows each -distinct plugin binary to be downloaded only once. - -To enable the plugin cache, use the `plugin_cache_dir` setting in -[the CLI configuration file](/docs/commands/cli-config.html). diff --git a/website/docs/configuration/resources.html.md b/website/docs/configuration/resources.html.md index 981772d10..080e0ec01 100644 --- a/website/docs/configuration/resources.html.md +++ b/website/docs/configuration/resources.html.md @@ -36,7 +36,7 @@ resource "aws_instance" "web" { A `resource` block declares a resource of a given type ("aws_instance") with a given local name ("web"). The name is used to refer to this resource from elsewhere in the same Terraform module, but has no significance outside -of the scope of a module. +that module's scope. The resource type and name together serve as an identifier for a given resource and so must be unique within a module. @@ -49,19 +49,45 @@ arguments defined specifically for [the `aws_instance` resource type](/docs/prov -> **Note:** Resource names must start with a letter or underscore, and may contain only letters, digits, underscores, and dashes. -## Resource Types and Arguments +## Resource Types Each resource is associated with a single _resource type_, which determines the kind of infrastructure object it manages and what arguments and other attributes the resource supports. -Each resource type in turn belongs to a [provider](./providers.html), +### Providers + +Each resource type is implemented by a [provider](./provider-requirements.html), which is a plugin for Terraform that offers a collection of resource types. A provider usually provides resources to manage a single cloud or on-premises -infrastructure platform. +infrastructure platform. Providers are distributed separately from Terraform +itself, but Terraform can automatically install most providers when initializing +a working directory. -Most of the items within the body of a `resource` block are specific to the -selected resource type. These arguments can make full use of +In order to manage resources, a Terraform module must specify which providers it +requires. Additionally, most providers need some configuration in order to +access their remote APIs, and the root module must provide that configuration. + +For more information, see: + +- [Provider Requirements](./provider-requirements.html), for declaring which + providers a module uses. +- [Provider Configuration](./providers.html), for configuring provider settings. + +Terraform usually automatically determines which provider to use based on a +resource type's name. (By convention, resource type names start with their +provider's preferred local name.) When using multiple configurations of a +provider (or non-preferred local provider names), you must use the `provider` +meta-argument to manually choose an alternate provider configuration. See +[the section on `provider` below][inpage-provider] for more details. + +### Resource Arguments + +Most of the arguments within the body of a `resource` block are specific to the +selected resource type. The resource type's documentation lists which arguments +are available and how their values should be formatted. + +The values for resource arguments can make full use of [expressions](./expressions.html) and other dynamic Terraform language features. @@ -70,24 +96,30 @@ and apply across all resource types. (See [Meta-Arguments](#meta-arguments) belo ### Documentation for Resource Types -[Terraform's provider documentation][providers] is the primary place to -learn which resource types are available and which arguments to use for each -resource type. Once you understand Terraform's basic syntax, the provider -documentation will be where you spend the majority of your time on this website. +Every Terraform provider has its own documentation, describing its resource +types and their arguments. -The "[Providers][]" link at the top level of the navigation sidebar will take -you to an alphabetical list of all of the providers distributed by HashiCorp. -You can find a specific provider in this master list, or choose a category from -the navigation sidebar to browse a more focused list of providers. +Most publicly available providers are distributed on the +[Terraform Registry](https://registry.terraform.io/browse/providers), which also +hosts their documentation. When viewing a provider's page on the Terraform +Registry, you can click the "Documentation" link in the header to browse its +documentation. Provider documentation on the registry is versioned, and you can +use the dropdown version menu in the header to switch which version's +documentation you are viewing. -You can also search GitHub or other sources for third-party providers, which can -be installed as plugins to enable an even broader selection of resource types. +To browse the publicly available providers and their documentation, see +[the providers section of the Terraform Registry](https://registry.terraform.io/browse/providers). -[providers]: /docs/providers/index.html +-> **Note:** Provider documentation used to be hosted directly on terraform.io, +as part of Terraform's core documentation. Although some provider documentation +might still be hosted here, the Terraform Registry is now the main home for all +public provider docs. (The exception is the built-in +[`terraform` provider](/docs/providers/terraform/index.html) for reading state +data, since it is not available on the Terraform Registry.) ## Resource Behavior -A `resource` block describes your intent for a particular infrastructure object +A `resource` block declares that you want a particular infrastructure object to exist with the given settings. If you are writing a new configuration for the first time, the resources it defines will exist _only_ in the configuration, and will not yet represent real infrastructure objects in the target platform. @@ -113,6 +145,28 @@ The meta-arguments within `resource` blocks, documented in the sections below, allow some details of this standard resource behavior to be customized on a per-resource basis. +### Accessing Resource Attributes + +[Expressions](./expressions.html) within a Terraform module can access +information about resources in the same module, and you can use that information +to help configure other resources. Use the `..` +syntax to reference a resource attribute in an expression. + +In addition to arguments specified in the configuration, resources often provide +read-only attributes with information obtained from the remote API; this often +includes things that can't be known until the resource is created, like the +resource's unique random ID. + +Many providers also include [data sources](./data-sources.html), which are a +special type of resource used only for looking up information. + +For a list of the attributes a resource or data source type provides, consult +its documentation; these are generally included in a second list below its list +of configurable arguments. + +For more information about referencing resource attributes in expressions, see +[Expressions: References to Resource Attributes](./expressions.html#references-to-resource-attributes). + ### Resource Dependencies Most resources in a configuration don't have any particular relationship, and @@ -466,21 +520,24 @@ resource "aws_instance" "server" { [inpage-provider]: #provider-selecting-a-non-default-provider-configuration -As described in [the Providers page](./providers.html), -Terraform optionally allows the definition of multiple alternative ("aliased") -configurations for a single provider, to allow management of resources -in different regions in multi-region services, etc. -The `provider` meta-argument overrides Terraform's default behavior of -selecting a provider configuration based on the resource type name. +The `provider` meta-argument specifies which provider configuration to use, +overriding Terraform's default behavior of selecting one based on the resource +type name. Its value should be an unquoted `.` reference. -By default, Terraform takes the initial word in the resource type name -(separated by underscores) and selects the default configuration for that -named provider. For example, the resource type `google_compute_instance` -is associated automatically with the default configuration for the provider -named `google`. +As described in [Provider Configuration](./providers.html), you can optionally +create multiple configurations for a single provider (usually to manage +resources in different regions of multi-region services). Each provider can have +one default configuration, and any number of alternate configurations that +include an extra name segment (or "alias"). -By using the `provider` meta-argument, an aliased provider configuration -can be selected: +By default, Terraform interprets the initial word in the resource type name +(separated by underscores) as the local name of a provider, and uses that +provider's default configuration. For example, the resource type +`google_compute_instance` is associated automatically with the default +configuration for the provider named `google`. + +By using the `provider` meta-argument, you can select an alternate provider +configuration for a resource: ```hcl # default configuration @@ -488,7 +545,7 @@ provider "google" { region = "us-central1" } -# alternative, aliased configuration +# alternate configuration, whose alias is "europe" provider "google" { alias = "europe" region = "europe-west1" @@ -508,8 +565,9 @@ A resource always has an implicit dependency on its associated provider, to ensure that the provider is fully configured before any resource actions are taken. -The `provider` meta-argument expects [a `.` reference](./providers.html#referring-to-alternate-providers), which -does not need to be quoted. Arbitrary expressions are not permitted for +The `provider` meta-argument expects +[a `.` reference](./providers.html#referring-to-alternate-providers), +which does not need to be quoted. Arbitrary expressions are not permitted for `provider` because it must be resolved while Terraform is constructing the dependency graph, before it is safe to evaluate expressions. diff --git a/website/docs/configuration/terraform.html.md b/website/docs/configuration/terraform.html.md index 88e6ca08e..4367710bd 100644 --- a/website/docs/configuration/terraform.html.md +++ b/website/docs/configuration/terraform.html.md @@ -60,17 +60,18 @@ ensure that everyone is using a specific Terraform version, or using at least a minimum Terraform version that has behavior expected by the configuration. The `required_version` setting applies only to the version of Terraform CLI. -Various behaviors of Terraform are actually implemented by Terraform providers, -which are released on a cycle independent of Terraform CLI and of each other. -Use [provider version constraints](./providers.html#provider-versions) -to make similar constraints on which provider versions may be used. +Terraform's resource types are implemented by provider plugins, +whose release cycles are independent of Terraform CLI and of each other. +Use [the `required_providers` block](./provider-requirements.html) to manage +the expected versions for each provider you use. ## Specifying Provider Requirements [inpage-source]: #specifying-provider-requirements The `required_providers` block specifies all of the providers required by the -current module. +current module, mapping each local provider name to a source address and a +version constraint. ```hcl terraform { @@ -83,7 +84,7 @@ terraform { } ``` -For more information, see [Provider Requirements](provider-requirements.html). +For more information, see [Provider Requirements](./provider-requirements.html). ## Experimental Language Features diff --git a/website/docs/internals/provider-registry-protocol.html.md b/website/docs/internals/provider-registry-protocol.html.md index f8a909e7b..b81dead37 100644 --- a/website/docs/internals/provider-registry-protocol.html.md +++ b/website/docs/internals/provider-registry-protocol.html.md @@ -98,7 +98,7 @@ version selection. ## Service Discovery The providers protocol begins with Terraform CLI using -[./remote-service-discovery.html](Terraform's remote service discovery protocol), +[Terraform's remote service discovery protocol](./remote-service-discovery.html), with the hostname in the provider address acting as the "User-facing Hostname". The service identifier for the provider registry protocol is `providers.v1`. diff --git a/website/docs/modules/publish.html.markdown b/website/docs/modules/publish.html.markdown index 317ec46cd..1768b09de 100644 --- a/website/docs/modules/publish.html.markdown +++ b/website/docs/modules/publish.html.markdown @@ -6,7 +6,7 @@ description: |- A module is a container for multiple resources that are used together. --- -## Publishing Modules +# Publishing Modules If you've built a module that you intend to be reused, we recommend [publishing the module](/docs/registry/modules/publish.html) on the @@ -28,7 +28,7 @@ If you do not wish to publish your modules in the public registry, you can instead use a [private registry](/docs/registry/private.html) to get the same benefits. -### Distribution via other sources +## Distribution via other sources Although the registry is the native mechanism for distributing re-usable modules, Terraform can also install modules from diff --git a/website/docs/providers/index.html.markdown b/website/docs/providers/index.html.markdown index 79074edf7..8ab5cf294 100644 --- a/website/docs/providers/index.html.markdown +++ b/website/docs/providers/index.html.markdown @@ -13,12 +13,58 @@ as physical machines, VMs, network switches, containers, and more. Almost any infrastructure type can be represented as a resource in Terraform. A provider is responsible for understanding API interactions and exposing -resources. Providers generally are an IaaS (e.g. Alibaba Cloud, AWS, GCP, Microsoft Azure, -OpenStack), PaaS (e.g. Heroku), or SaaS services (e.g. Terraform Cloud, -DNSimple, Cloudflare). +resources. Most providers configure a specific infrastructure platform (either +cloud or self-hosted). Providers can also offer local utilities for tasks like +generating random numbers for unique resource names. -Use the navigation to the left to find available providers by type or scroll -down to see all providers. +## Providers in the Terraform Registry + +The [Terraform Registry](https://registry.terraform.io/browse/providers) +is the main directory of publicly available Terraform providers, and hosts +providers for most major infrastructure platforms. + +Once you've found a provider you want to use, you can require it in your +Terraform configuration and start using the resource types it provides. +Terraform can automatically install providers from the Terraform Registry when +you run `terraform init`. + +- To find providers for the infrastructure platforms you use, browse + [the providers section of the Terraform Registry](https://registry.terraform.io/browse/providers). +- For details about how to use providers in your Terraform configurations, see + [Provider Requirements](../configuration/provider-requirements.html) and + [Provider Configuration](../configuration/providers.html). + +### Provider Documentation + +Every Terraform provider has its own documentation, describing its resource +types and their arguments. + +The Terraform Registry is also the main home for provider documentation. +When viewing a provider's page on the Terraform Registry, you can click the +"Documentation" link in the header to browse its documentation. Provider +documentation in the registry is versioned, and you can use the dropdown version +menu in the header to switch which version's documentation you are viewing. + +## Lists of Terraform Providers + +Provider documentation used to be hosted directly on terraform.io, as part of +Terraform's core documentation. Although some provider documentation might still +be hosted here, the Terraform Registry is now the main home for all public +provider docs. (The exception is the built-in +[`terraform` provider](/docs/providers/terraform/index.html) for reading state +data, since it is not available on the Terraform Registry.) + +As part of the old provider documentation, this section of the site included +categorized lists of all of the providers that could be automatically installed +by older versions of Terraform, plus a supplemental list of community providers +that needed to be manually installed. Many of these providers have already moved +to the Terraform Registry, but we will continue to host these lists for a while +as part of the transition. Links to provider documentation URLs on terraform.io +should still work, but will now redirect to the equivalent page in the Terraform +Registry. + +Use the navigation to the left to browse the categorized lists, or see the main +list of historical providers below.
diff --git a/website/docs/registry/providers/os-arch.md b/website/docs/registry/providers/os-arch.md index 2419d4cb1..e44c287e9 100644 --- a/website/docs/registry/providers/os-arch.md +++ b/website/docs/registry/providers/os-arch.md @@ -1,16 +1,16 @@ --- layout: "registry" -page_title: "Recommended Provider Binary OS and Architecture - Terraform Registry" +page_title: "Recommended Provider Binary Operating Systems and Architectures - Terraform Registry" sidebar_current: "docs-registry-provider-os-arch" description: |- - Recommended Provider Binary OS and Architecture + Recommended Provider Binary Operating Systems and Architectures --- +# Recommended Provider Binary Operating Systems and Architectures + -> __Publishing Beta__
Welcome! Thanks for your interest participating in our Providers in the Registry beta! Paired with Terraform 0.13, our vision is to make it easier than ever to discover, distribute, and maintain your provider(s). We welcome any feedback you have throughout the process and encourage you to reach out if you have any questions or issues by emailing terraform-registry-beta@hashicorp.com. -## Recommended Provider Binary OS and Architecture - -We recommend the following OS / architecture combinations for compiled binaries available in the registry (this list is already satisfied by our [recommended **.goreleaser.yml** configuration file](https://github.com/hashicorp/terraform-provider-scaffolding/blob/master/.goreleaser.yml)): +We recommend the following operating system / architecture combinations for compiled binaries available in the registry (this list is already satisfied by our [recommended **.goreleaser.yml** configuration file](https://github.com/hashicorp/terraform-provider-scaffolding/blob/master/.goreleaser.yml)): * Darwin / AMD64 * Linux / AMD64 diff --git a/website/docs/registry/providers/publishing.html.md b/website/docs/registry/providers/publishing.html.md index c18bd27d9..d75688f75 100644 --- a/website/docs/registry/providers/publishing.html.md +++ b/website/docs/registry/providers/publishing.html.md @@ -6,6 +6,8 @@ description: |- Publishing Providers to the Terraform Registry --- +# Publishing Providers + -> __Publishing Beta__
Welcome! Thanks for your interest participating in our Providers in the Registry beta! Paired with Terraform 0.13, our vision is to make it easier than ever to discover, distribute, and maintain your provider(s). We welcome any feedback you have throughout the process and encourage you to reach out if you have any questions or issues by emailing terraform-registry-beta@hashicorp.com. ## Preparing your Provider @@ -14,7 +16,7 @@ description: |- Providers published to the Terraform Registry are written and built in the same way as other Terraform Providers. For guidance on how to write a provider, see [Writing Custom Providers](/docs/extend/writing-custom-providers.html). -The provider repository on GitHub must match the pattern `terraform-provider-{NAME}`, and the repository must be public. +The provider repository on GitHub must match the pattern `terraform-provider-{NAME}`, and the repository must be public. #### Licensing a Verified Provider @@ -22,14 +24,14 @@ All Terraform Verified providers must contain one of the following open source l * CDDL 1.0, 2.0 * CPL 1.0 -* Eclipse Public License (EPL) 1.0 +* Eclipse Public License (EPL) 1.0 * MPL 1.0, 1.1, 2.0 * APSL 2.0 * Ruby's Licensing * AFL 2.1, 3.0 * Apache License 2.0 * Artistic License 1.0, 2.0 -* Apache Software License (ASL) 1.1 +* Apache Software License (ASL) 1.1 * Boost Software License * BSD, BSD 3-clause, "BSD-new" * CC-BY diff --git a/website/layouts/docs.erb b/website/layouts/docs.erb index a6ddd344e..9988112d1 100644 --- a/website/layouts/docs.erb +++ b/website/layouts/docs.erb @@ -11,7 +11,11 @@