website: Break up main Modules and Module Development pages
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
2020-11-13 03:21:35 +01:00
---
layout: "language"
page_title: "The Module providers Meta-Argument - Configuration Language"
2021-07-09 21:28:28 +02:00
description: |-
Using the Terraform language `providers` meta-argument to specify which provider configurations from a parent module are available inside a child module.
website: Break up main Modules and Module Development pages
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
2020-11-13 03:21:35 +01:00
---
# The Module `providers` Meta-Argument
2021-01-15 23:13:53 +01:00
In a [module call ](/docs/language/modules/syntax.html ) block, the
website: Break up main Modules and Module Development pages
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
2020-11-13 03:21:35 +01:00
optional `providers` meta-argument specifies which
2021-01-15 23:13:53 +01:00
[provider configurations ](/docs/language/providers/configuration.html ) from the parent
website: Break up main Modules and Module Development pages
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
2020-11-13 03:21:35 +01:00
module will be available inside the child module.
```hcl
# The default "aws" configuration is used for AWS resources in the root
# module where no explicit provider instance is selected.
provider "aws" {
region = "us-west-1"
}
# 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 alternate configuration,
# so any AWS resources it defines will use the us-west-2 region.
module "example" {
source = "./example"
providers = {
aws = aws.usw2
}
}
```
## Default Behavior: Inherit Default Providers
2021-02-12 20:49:00 +01:00
If the child module does not declare any [configuration aliases ](/docs/language/modules/develop/providers.html#provider-aliases-within-modules ),
the `providers` argument is optional. If you omit it, a child module inherits
all of the _default_ provider configurations from its parent module. (Default
provider configurations are ones that don't use the `alias` argument.)
website: Break up main Modules and Module Development pages
This one is a lot like the previous two commits, but slightly more complex:
- Only adding one new meta-argument page, for `providers`; otherwise, it just
re-uses the dual-purpose pages I made in the resources commit.
- About that `providers` argument: The stuff that was relevant to consumers of a
module went in that meta-argument page, but there was also a huge deep dive on
how the _author_ of a re-usable module should handle provider configurations
in cases where inheriting the default providers isn't sufficient. THAT, I
moved into a new page in the module development section. (For the consumer of
a module, this should all be an implementation detail; the module README
should tell you which aliased providers you need to configure and pass, and
then you just do it, without worrying about proxy configuration blocks etc.)
- The "standard module structure" recommendations in the main module development
page gets a page of its own, to make it more prominent and discoverable.
- Same deal with using the old URL as a landing page, at least for the main
module calls page. It didn't seem necessary for the module development page.
2020-11-13 03:21:35 +01:00
If you specify a `providers` argument, it cancels this default behavior, and the
child module will _only_ have access to the provider configurations you specify.
## Usage and Behavior
The value of `providers` is a map, where:
- The keys are the provider configuration names used inside the child module.
- The values are provider configuration names from the parent module.
Both keys and values should be unquoted references to provider configurations.
For default configurations, this is the local name of the provider; for
alternate configurations, this is a `<PROVIDER>.<ALIAS>` reference.
Within a child module, resources are assigned to provider configurations as
normal — either Terraform chooses a default based on the name of the resource
type, or the resource specifies an alternate configuration with the `provider`
argument. If the module receives a `providers` map when it's called, the
provider configuration names used within the module are effectively remapped to
refer the specified configurations from the parent module.
## When to Specify Providers
There are two main reasons to use the `providers` argument:
- Using different default provider configurations for a child module.
- Configuring a module that requires multiple configurations of the same provider.
### Changing Default Provider Configurations
Most re-usable modules only use default provider configurations, which they can
automatically inherit from their caller when `providers` is omitted.
However, in Terraform configurations that use multiple configurations of the
same provider, you might want some child modules to use the default provider
configuration and other ones to use an alternate. (This usually happens when
using one configuration to manage resources in multiple different regions of the
same cloud provider.)
By using the `providers` argument (like in the code example above), you can
accommodate this without needing to edit the child module. Although the code
within the child module always refers to the default provider configuration, the
actual configuration of that default can be different for each instance.
### Modules With Alternate Provider Configurations
In rare cases, a single re-usable module might require multiple configurations
of the same provider. For example, a module that configures connectivity between
networks in two AWS regions is likely to need both a source and a destination
region. In that case, the root module may look something like this:
```hcl
provider "aws" {
alias = "usw1"
region = "us-west-1"
}
provider "aws" {
alias = "usw2"
region = "us-west-2"
}
module "tunnel" {
source = "./tunnel"
providers = {
aws.src = aws.usw1
aws.dst = aws.usw2
}
}
```
Non-default provider configurations are never automatically inherited, so any
module that works like this will always need a `providers` argument. The
documentation for the module should specify all of the provider configuration
names it needs.
## More Information for Module Developers
For more details and guidance about working with providers inside a re-usable
child module, see
2021-01-15 23:13:53 +01:00
[Module Development: Providers Within Modules ](/docs/language/modules/develop/providers.html ).