mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-19 17:59:05 -05:00
Signed-off-by: Ilia Gogotchuri <ilia.gogotchuri0@gmail.com> Co-authored-by: Oleksandr Levchenkov <ollevche@gmail.com>
368 lines
15 KiB
Plaintext
368 lines
15 KiB
Plaintext
---
|
|
sidebar_position: 1
|
|
sidebar_label: Provider Configuration
|
|
description: >-
|
|
Learn how to set up providers, including how to use the alias meta-argument to
|
|
specify multiple configurations for a single provider.
|
|
---
|
|
|
|
import CodeBlock from '@theme/CodeBlock';
|
|
import ExampleDynamicProviderInstances from '!!raw-loader!../meta-arguments/examples/resource-provider-dynamic-instances.tf'
|
|
|
|
# Provider Configuration
|
|
|
|
Providers allow OpenTofu to interact with cloud providers, SaaS providers, and
|
|
other APIs.
|
|
|
|
Some providers require you to configure them with endpoint URLs, cloud regions,
|
|
or other settings before OpenTofu can use them. This page documents how to
|
|
configure settings for providers.
|
|
|
|
Additionally, all OpenTofu configurations must declare which providers they
|
|
require so that OpenTofu can install and use them. The
|
|
[Provider Requirements](requirements.mdx)
|
|
page documents how to declare providers so OpenTofu can install them.
|
|
|
|
## Provider Configuration
|
|
|
|
Provider configurations belong in the root module of an OpenTofu configuration.
|
|
(Child modules receive their provider configurations from the root module; for
|
|
more information, see
|
|
[The Module `providers` Meta-Argument](../../language/meta-arguments/module-providers.mdx)
|
|
and [Module Development: Providers Within Modules](../../language/modules/develop/providers.mdx).)
|
|
|
|
A provider configuration is defined using a `provider` block:
|
|
|
|
```hcl
|
|
provider "google" {
|
|
project = "acme-app"
|
|
region = "us-central1"
|
|
}
|
|
```
|
|
|
|
The name given in the block header (`"google"` in this example) is the
|
|
[local name](../../language/providers/requirements.mdx#local-names) of the provider to
|
|
configure. Each module has its own namespace of provider local names,
|
|
defined in its `required_providers` block.
|
|
|
|
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.
|
|
|
|
You can use [expressions](../../language/expressions/index.mdx) in the values of these
|
|
configuration arguments, but can only refer to values that are known before the
|
|
configuration is applied. This means you can safely reference input variables,
|
|
but not attributes exported by resources unless they are defined directly in
|
|
the configuration or documented as being available during the planning phase.
|
|
|
|
A provider's documentation should list which configuration arguments it expects.
|
|
For providers distributed on the
|
|
[Public OpenTofu Registry](https://registry.opentofu.org), 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 OpenTofu code.
|
|
|
|
There are also two "meta-arguments" that are defined by OpenTofu itself
|
|
and available for all `provider` blocks:
|
|
|
|
- [`alias`, for defining additional configurations for the same provider][inpage-alias]
|
|
- [`for_each`, for defining multiple dynamic instances of a provider configuration][inpage-for_each]
|
|
- [`version`, which we no longer recommend][inpage-versions] (use
|
|
[provider requirements](../../language/providers/requirements.mdx) instead)
|
|
|
|
Unlike many other objects in the OpenTofu language, a `provider` block may
|
|
be omitted if its contents would otherwise be empty. OpenTofu assumes an
|
|
empty default configuration for any provider that is not explicitly configured.
|
|
|
|
## `alias`: Multiple Provider Configurations
|
|
|
|
[inpage-alias]: #alias-multiple-provider-configurations
|
|
|
|
You can optionally define multiple configurations for the same provider, and
|
|
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 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.
|
|
A provider configuration with an alias is called an _alternate provider configuration_.
|
|
For example:
|
|
|
|
```hcl
|
|
# 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"
|
|
}
|
|
|
|
# Alternate provider configuration for west coast region; resources can
|
|
# reference this as `aws.west`.
|
|
provider "aws" {
|
|
alias = "west"
|
|
region = "us-west-2"
|
|
}
|
|
```
|
|
|
|
To declare a configuration alias within a module in order to receive an
|
|
alternate provider configuration from the parent module, add the
|
|
`configuration_aliases` argument to that provider's `required_providers`
|
|
entry. The following example declares both the `mycloud` and
|
|
`mycloud.alternate` provider configuration names within the containing module:
|
|
|
|
```hcl
|
|
terraform {
|
|
required_providers {
|
|
mycloud = {
|
|
source = "mycorp/mycloud"
|
|
version = "~> 1.0"
|
|
configuration_aliases = [ mycloud.alternate ]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Default Provider Configurations
|
|
|
|
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.)
|
|
|
|
If there is no `provider` block defining the default configuration for a
|
|
provider, OpenTofu automatically infers an empty default provider configuration
|
|
for that provider. If the provider's configuration schema includes any required
|
|
arguments then the empty configuration would be invalid, and so an explicit
|
|
`provider` block is required.
|
|
|
|
A default provider configuration is not required nor inferred if all resources
|
|
in a module explicitly select a different provider configuration using the
|
|
`provider` meta-argument in their `resource` or `data` blocks.
|
|
|
|
## `for_each`: Multiple instances of a provider configuration
|
|
|
|
[inpage-for_each]: #for_each-multiple-instances-of-a-provider-configuration
|
|
|
|
Sometimes it's necessary to declare multiple instances of a provider dynamically
|
|
based on some other data available in your configuration, such as an input
|
|
variable.
|
|
|
|
For example, a configuration that declares a foundational set of infrastructure
|
|
for each AWS region that an organization is using might offer an input variable
|
|
for specifying those regions, but the `hashicorp/aws` provider supports only
|
|
one region per instance of the provider and so it would not be possible to
|
|
declare infrastructure across a dynamic set of regions using only static
|
|
provider configurations.
|
|
|
|
Any alternate provider configuration (declared using the `alias` argument)
|
|
can optionally also include the `for_each` argument to declare that the
|
|
configuration should be instantiated multiple times based on a collection
|
|
value:
|
|
|
|
```hcl
|
|
variable "aws_regions" {
|
|
type = map(object({
|
|
vpc_cidr_block = string
|
|
}))
|
|
}
|
|
|
|
provider "aws" {
|
|
alias = "by_region"
|
|
for_each = var.aws_regions
|
|
|
|
region = each.key
|
|
}
|
|
```
|
|
|
|
Without the `for_each` argument, a `provider` block always declares only
|
|
a single instance of the corresponding provider. A provider configuration
|
|
which includes the `for_each` argument instead declares _zero or more_
|
|
provider instances where each corresponds to one element from the `for_each`
|
|
collection, each configured systematically based on the same configuration
|
|
block.
|
|
|
|
Each instance has an _instance key_ which uniquely identifies the instance
|
|
among all instances belonging to the same provider configuration.
|
|
The value assigned to `for_each` must be of either a map type, an object
|
|
type, or be a set of strings. For a map or object type, the element key or
|
|
attribute name becomes the instance key. For a set of strings, the element
|
|
value itself becomes the instance key.
|
|
|
|
An operator of this configuration must provide a map value for the `aws_regions`
|
|
input variable, where each element's key is a valid AWS region name and its
|
|
value is an object describing the unique settings for that region. For example,
|
|
in a `terraform.tfvars` file:
|
|
|
|
```hcl
|
|
aws_regions = {
|
|
eu-central-2 = {
|
|
vpc_cidr_block = "10.1.0.0/16"
|
|
}
|
|
ap-northeast-1 = {
|
|
vpc_cidr_block = "10.2.0.0/16"
|
|
}
|
|
}
|
|
```
|
|
|
|
The `for_each` argument can only be used in combination with `alias`, because
|
|
the default configuration for each provider must always have exactly one
|
|
instance so that OpenTofu can select it automatically when appropriate.
|
|
|
|
## Selecting Alternate Provider Configurations
|
|
|
|
Each resource in your OpenTofu configuration must be bound to one
|
|
provider configuration.
|
|
|
|
By default, each resource is bound to a
|
|
[default provider configuration](#default-provider-configurations)
|
|
chosen automatically based on the first segment of the resource type
|
|
name. For example, a `resource "azurerm_subnet" "example"` block would
|
|
be bound to the default configuration for whichever provider has the
|
|
local name "azurerm" in the module where the resource is declared.
|
|
|
|
To use an alternate provider configuration, a `resource` or `data`
|
|
block must include
|
|
[the `provider` Meta-Argument](../../language/meta-arguments/resource-provider.mdx),
|
|
with a [provider instance reference](#referring-to-provider-instances)
|
|
that includes the selected configuration's alias:
|
|
|
|
```hcl
|
|
resource "aws_instance" "foo" {
|
|
provider = aws.west
|
|
|
|
# ...
|
|
}
|
|
```
|
|
|
|
If the selected configuration uses the `for_each` argument to declare
|
|
multiple instances then the `provider` argument must also include
|
|
an instance key expression to select one instance of the provider
|
|
configuration per resource instance as described in the next section.
|
|
|
|
Omitting the `provider` argument is equivalent to setting it to
|
|
choose the default configuration for the provider whose local name
|
|
matches the resource type name's prefix:
|
|
|
|
```hcl
|
|
resource "aws_instance" "foo" {
|
|
provider = aws
|
|
|
|
# ...
|
|
}
|
|
```
|
|
|
|
## Referring to Provider Instances
|
|
|
|
{/* old section anchor to preserve existing external links */}
|
|
<a id="referring-to-alternate-provider-configurations"></a>
|
|
|
|
To explicitly refer to provider configurations, OpenTofu uses a
|
|
provider-configuration-specific reference syntax of the form
|
|
`<PROVIDER NAME>.<ALIAS>`. For example, `aws.west` refers to the
|
|
`provider "aws"` block with `alias = "west"`.
|
|
|
|
This syntax uses similar symbols to a normal
|
|
[expression reference](../../language/expressions/references.mdx), but
|
|
provider references are not normal expressions and can only be used
|
|
in some special locations:
|
|
|
|
- [The `provider` meta-argument of a `resource` or `data` block](../../language/meta-arguments/resource-provider.mdx)
|
|
- [The `providers` meta-argument of a `module` block](../../language/meta-arguments/module-providers.mdx)
|
|
|
|
For a provider configuration that does not include `for_each`, the same
|
|
syntax used to refer to the configuration is also a reference to its
|
|
single provider instance, so in most cases you can think of a provider
|
|
configuration reference and a provider instance reference as equivalent.
|
|
|
|
However, when a provider configuration declares zero or more dynamic
|
|
instances using `for_each` the reference syntax grows to include an
|
|
additional component which specifies which instance to select using
|
|
the configuration's instance keys. For example, `aws.by_region["eu-west-1"]`
|
|
refers to whichever instance of `aws.by_region` has the instance
|
|
key `"eu-west-1"`.
|
|
|
|
The expression in square brackets uses [normal expression syntax](../../language/expressions/index.mdx),
|
|
and typically the instance key would be selected dynamically for each
|
|
instance of a resource rather than hard-coded. For example:
|
|
|
|
<CodeBlock language="hcl">{ExampleDynamicProviderInstances}</CodeBlock>
|
|
|
|
{/* NOTE: The above example is shared with ../meta-arguments/resource-provider.mdx */}
|
|
|
|
The `resource "aws_vpc" "private"` block uses `for_each` to declare one
|
|
instance of the resource for each non-null element of `var.aws_regions`.
|
|
The `provider` argument then uses `each.key` to select a different
|
|
instance of `aws.by_region` for each instance of the resource, so that
|
|
each would be declared in a different region.
|
|
|
|
You can also choose a dynamic instance from a provider configuration for
|
|
all resources in a child module as part of a `module` block. Refer to
|
|
[Module instances with differing provider instances](../../language/meta-arguments/module-providers.mdx#module-instances-with-differing-provider-instances)
|
|
for more information.
|
|
|
|
Although the instance key expression in square brackets is dynamic, the
|
|
provider configuration reference is static so that OpenTofu can infer the
|
|
dependencies between `resource` blocks and `provider` blocks before
|
|
evaluating any expressions. The dependencies then ensure that OpenTofu
|
|
can resolve dynamic expressions in the correct order. This means that
|
|
all instances of a particular resource must be bound to instances of the
|
|
same provider configuration block, but can they each be bound to a different
|
|
instance.
|
|
|
|
:::warning
|
|
**The `for_each` expression for a resource must not exactly match the
|
|
`for_each` expression for its associated provider configuration.**
|
|
|
|
OpenTofu uses a provider instance to plan and apply _all_ actions related
|
|
to a resource instance, including destroying a resource instance that
|
|
has been removed from the configuration.
|
|
|
|
Therefore the provider instance associated with any resource instance must
|
|
always remain in the configuration for at least one more plan/apply round
|
|
after the resource instance has been removed, or OpenTofu will fail to
|
|
plan to destroy the resource instance.
|
|
|
|
The above example uses a null element in `var.aws_regions` to represent
|
|
that a provider instance is needed but no resource instances should be
|
|
associated with it.
|
|
|
|
Setting a particular region's element to `null` would therefore cause
|
|
OpenTofu to propose to destroy the `aws_vpc.private` instance for that
|
|
region while retaining the provider instance needed to plan and apply that
|
|
action. You can then remove the element altogether on the next round, once
|
|
all of the associated resource instances have been destroyed.
|
|
:::
|
|
|
|
### Passing provider configurations between modules
|
|
|
|
Each module has its own separate namespace of provider configurations, but
|
|
it's possible for a parent module to pass some or all of its provider
|
|
configurations into provider configuration addresses declared in a
|
|
child module.
|
|
|
|
For more information, refer to
|
|
[The `providers` Meta-Argument in `module` blocks](../../language/meta-arguments/module-providers.mdx).
|
|
|
|
<a id="provider-versions"></a>
|
|
|
|
## `version` (Deprecated)
|
|
<!-- TODO: Figure out the best way to link to this, or remove the deprecated setting documentation completely -->
|
|
<!-- lint ignore remark-lint-no-undefined-references -->
|
|
|
|
[inpage-versions]: #provider-versions
|
|
|
|
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](../../language/providers/requirements.mdx). The version
|
|
constraint in a provider configuration is only used if `required_providers`
|
|
does not include one for that provider.
|
|
|
|
Always declare provider version constraints in
|
|
[the `required_providers` block](../../language/providers/requirements.mdx).
|