website: further copyediting for "Providers within Modules"
The differences between the implicit and explicit modes of passing provider configurations between modules are significant enough to warrant giving these approaches different names and describing them separately. This also includes documentation of the current limitation discussed in #16612, where explicit passing requires a proxy configuration block even for a _default_ provider configuration, because that limitation is being accepted for the 0.11.0 release to limit scope.
This commit is contained in:
parent
2889eded3f
commit
1da2464e72
|
@ -147,16 +147,86 @@ than waiting for the entire module to be complete before proceeding.
|
||||||
|
|
||||||
## Providers within Modules
|
## Providers within Modules
|
||||||
|
|
||||||
For convenience in simple configurations, child modules automatically inherit
|
In a configuration with multiple modules, there are some special considerations
|
||||||
default (un-aliased) provider configurations from their parent. This means that
|
for how resources are associated with provider configurations.
|
||||||
in most cases only the root module needs explicit `provider` blocks, and then
|
|
||||||
any defined provider can be freely used with the same settings in child modules.
|
|
||||||
|
|
||||||
In more complex situations it may be necessary for a child module to use
|
While in principle `provider` blocks can appear in any module, it is recommended
|
||||||
different provider settings than its parent. In this situation it is
|
that they be placed only in the _root_ module of a configuration, since this
|
||||||
possible to define
|
approach allows users to configure providers just once and re-use them across
|
||||||
[multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances)
|
all descendent modules.
|
||||||
and pass them explicitly and selectively to a child module:
|
|
||||||
|
Each resource in the configuration must be associated with one provider
|
||||||
|
configuration, which may either be within the same module as the resource
|
||||||
|
or be passed from the parent module. Providers can be passed down to descendent
|
||||||
|
modules in two ways: either _implicitly_ through inheritance, or _explicitly_
|
||||||
|
via the `providers` argument within a `module` block. These two options are
|
||||||
|
discussed in more detail in the following sections.
|
||||||
|
|
||||||
|
In all cases it is recommended to keep explicit provider configurations only in
|
||||||
|
the root module and pass them (whether implicitly or explicitly) down to
|
||||||
|
descendent modules. This avoids the provider configurations from being "lost"
|
||||||
|
when descendent modules are removed from the configuration. It also allows
|
||||||
|
the user of a configuration to determine which providers require credentials
|
||||||
|
by inspecting only the root module.
|
||||||
|
|
||||||
|
Provider configurations are used for all operations on associated resources,
|
||||||
|
including destroying remote objects and refreshing state. Terraform retains, as
|
||||||
|
part of its state, a reference to the provider configuration that was most
|
||||||
|
recently used to apply changes to each resource. When a `resource` block is
|
||||||
|
removed from the configuration, this record in the state is used to locate the
|
||||||
|
appropriate configuration because the resource's `provider` argument (if any)
|
||||||
|
is no longer present in the configuration.
|
||||||
|
|
||||||
|
As a consequence, it is required that all resources created for a particular
|
||||||
|
provider configuration must be destroyed before that provider configuration is
|
||||||
|
removed, unless the related resources are re-configured to use a different
|
||||||
|
provider configuration first.
|
||||||
|
|
||||||
|
### Implicit Provider Inheritance
|
||||||
|
|
||||||
|
For convenience in simple configurations, a child module automatically inherits
|
||||||
|
default (un-aliased) provider configurations from its parent. This means that
|
||||||
|
explicit `provider` blocks appear only in the root module, and downstream
|
||||||
|
modules can simply declare resources for that provider and have them
|
||||||
|
automatically associated with the root provider configurations.
|
||||||
|
|
||||||
|
For example, the root module might contain only a `provider` block and a
|
||||||
|
`module` block to instantiate a child module:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
provider "aws" {
|
||||||
|
region = "us-west-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
module "child" {
|
||||||
|
source = "./child"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The child module can then use any resource from this provider with no further
|
||||||
|
provider configuration required:
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
resource "aws_s3_bucket" "example" {
|
||||||
|
bucket = "provider-inherit-example"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This approach is recommended in the common case where only a single
|
||||||
|
configuration is needed for each provider across the entire configuration.
|
||||||
|
|
||||||
|
In more complex situations there may be [multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances),
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
child module. For example:
|
||||||
|
|
||||||
```hcl
|
```hcl
|
||||||
# The default "aws" configuration is used for AWS resources in the root
|
# The default "aws" configuration is used for AWS resources in the root
|
||||||
|
@ -182,16 +252,16 @@ module "example" {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `providers` argument within a `module` block serves the same purpose as
|
The `providers` argument within a `module` block is similar to
|
||||||
the `provider` argument within a resource as described for
|
the `provider` argument within a resource as described for
|
||||||
[multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances),
|
[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
|
but is a map rather than a single string because a module may contain resources
|
||||||
from many different providers.
|
from many different providers.
|
||||||
|
|
||||||
Once the `providers` argument is used in a `module` block it overrides all of
|
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
|
the default inheritance behavior, so it is necessary to enumerate mappings
|
||||||
for _all_ of the required providers. This is to avoid confusion and surprises
|
for _all_ of the required providers. This is to avoid confusion and surprises
|
||||||
when mixing both implicit and explicit provider passing.
|
that may result when mixing both implicit and explicit provider passing.
|
||||||
|
|
||||||
Additional provider configurations (those with the `alias` argument set) are
|
Additional provider configurations (those with the `alias` argument set) are
|
||||||
_never_ inherited automatically by child modules, and so must always be passed
|
_never_ inherited automatically by child modules, and so must always be passed
|
||||||
|
@ -223,11 +293,11 @@ module "tunnel" {
|
||||||
In the `providers` map, the keys are provider names as expected by the child
|
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
|
module, while the values are the names of corresponding configurations in
|
||||||
the _current_ module. The subdirectory `./tunnel` must then contain
|
the _current_ module. The subdirectory `./tunnel` must then contain
|
||||||
`alias`-only configuration blocks like the following, to declare that it
|
_proxy configuration blocks_ like the following, to declare that it
|
||||||
requires these names to be passed from a `providers` block in the parent's
|
requires configurations to be passed with these from the `providers` block in
|
||||||
`module` block:
|
the parent's `module` block:
|
||||||
|
|
||||||
```
|
```hcl
|
||||||
provider "aws" {
|
provider "aws" {
|
||||||
alias = "src"
|
alias = "src"
|
||||||
}
|
}
|
||||||
|
@ -240,29 +310,19 @@ provider "aws" {
|
||||||
Each resource should then have its own `provider` attribute set to either
|
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 instances to use.
|
||||||
|
|
||||||
It is recommended to use the default inheritance behavior in most cases where
|
At this time it is required to write an explicit proxy configuration block
|
||||||
only a single default instance of each provider is used, and switch to
|
even for default (un-aliased) provider configurations when they will be passed
|
||||||
passing providers explicitly only if multiple instances are needed.
|
via an explicit `providers` block:
|
||||||
|
|
||||||
In all cases it is recommended to keep explicit provider configurations only in
|
```hcl
|
||||||
the root module and pass them (either implicitly or explicitly) down to
|
provider "aws" {
|
||||||
descendent modules. This avoids the provider configurations being "lost"
|
}
|
||||||
when descendent providers are removed from the configuration. It also allows
|
```
|
||||||
the user of a configuration to determine which providers require credentials
|
|
||||||
by inspecting only the root module.
|
|
||||||
|
|
||||||
Provider configurations are used for all operations on resources, including
|
If such a block is not present, the child module will behave as if it has no
|
||||||
destroying remote objects and refreshing state. Terraform retains, as part of
|
configurations of this type at all, which may cause input prompts to supply
|
||||||
its state, a reference to the provider configuration that was most recently
|
any required provider configuration arguments. This limitation will be
|
||||||
used to apply changes to each resource. When a resource is removed from the
|
addressed in a future version of Terraform.
|
||||||
configuration, this record in state is used to locate the appropriate
|
|
||||||
configuration because the resource's `provider` argument is no longer present
|
|
||||||
in the configuration.
|
|
||||||
|
|
||||||
As a consequence, it is required that all resources created for a particular
|
|
||||||
provider configuration must be destroyed before that provider configuration is
|
|
||||||
removed, unless the related resources are re-configured to use a different
|
|
||||||
provider configuration first.
|
|
||||||
|
|
||||||
## Multiple Instances of a Module
|
## Multiple Instances of a Module
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue