website: Configuration Language navigation refactoring

The "Configuration Language" section was becoming rather unweildy, both
by having a lot of pages and by some of the pages being quite large in
themselves.

This is a first step towards breaking things up a little more, starting
with two changes:

 - The "Configuration Language" navigation is now split into two
   sub-headings "Configuration Blocks" and "Syntax".

 - Some of the information about sub-blocks of the "terraform" block are
   now given their own pages, because their content is quite complex
   in itself.

 - "Version Constraints" is now a page in its own right, rather than this
   content being duplicated in slightly different forms across multiple
   contexts that make use of user-specified version constraints.
This commit is contained in:
Nick Fagerlund 2020-03-23 14:00:11 -04:00 committed by Martin Atkins
parent aefead2207
commit b1eb9dcfcf
6 changed files with 397 additions and 165 deletions

View File

@ -0,0 +1,172 @@
---
layout: "docs"
page_title: "Backend Configuration - Configuration Language"
---
# Backend Configuration
-> **Note:** This page is about Terraform 0.12 and later. For Terraform 0.11 and
earlier, see
[0.11 Configuration Language: Terraform Settings](../configuration-0-11/terraform.html).
Each Terraform configuration can specify a backend, which defines exactly where
and how operations are performed, where [state](/docs/state/index.html)
snapshots are stored, etc. Most non-trivial Terraform configurations configure
a remote backend so that multiple people can work with the same infrastructure.
## Using a Backend Block
Backends are configured with a nested `backend` block within the top-level
`terraform` block:
```hcl
terraform {
backend "remote" {
organization = "example_corp"
workspaces {
name = "my-app-prod"
}
}
}
```
There are some important limitations on backend configuration:
- A configuration can only provide one backend block.
- A backend block cannot refer to named values (like input variables, locals, or data source attributes).
### Backend Types
The block label of the backend block (`"remote"`, in the example above) indicates which backend type to use. Terraform has a built-in selection of backends, and the configured backend must be available in the version of Terraform you are using.
The arguments used in the block's body are specific to the chosen backend type; they configure where and how the backend will store the configuration's state, and in some cases configure other behavior.
Some backends allow providing access credentials directly as part of the configuration for use in unusual situations, for pragmatic reasons. However, in normal use we _do not_ recommend including access credentials as part of the backend configuration. Instead, leave those arguments completely unset and provide credentials via the credentials files or environment variables that are conventional for the target system, as described in the documentation for each backend.
See _[Backend Types](/docs/backends/types/index.html)_ for details about each supported backend type and its configuration arguments.
### Default Backend
If a configuration includes no backend block, Terraform defaults to using the `local` backend, which performs operations on the local system and stores state as a plain file in the current working directory.
## Initialization
Whenever a configuration's backend changes, you must run `terraform init` again
to validate and configure the backend before you can perform any plans, applies,
or state operations.
When changing backends, Terraform will give you the option to migrate
your state to the new backend. This lets you adopt backends without losing
any existing state.
To be extra careful, we always recommend manually backing up your state
as well. You can do this by simply copying your `terraform.tfstate` file
to another location. The initialization process should create a backup
as well, but it never hurts to be safe!
## Partial Configuration
You do not need to specify every required argument in the backend configuration.
Omitting certain arguments may be desirable if some arguments are provided
automatically by an automation script running Terraform. When some or all of
the arguments are omitted, we call this a _partial configuration_.
With a partial configuration, the remaining configuration arguments must be
provided as part of
[the initialization process](/docs/backends/init.html#backend-initialization).
There are several ways to supply the remaining arguments:
* **File**: A configuration file may be specified via the `init` command line.
To specify a file, use the `-backend-config=PATH` option when running
`terraform init`. If the file contains secrets it may be kept in
a secure data store, such as
[Vault](https://www.vaultproject.io/), in which case it must be downloaded
to the local disk before running Terraform.
* **Command-line key/value pairs**: Key/value pairs can be specified via the
`init` command line. Note that many shells retain command-line flags in a
history file, so this isn't recommended for secrets. To specify a single
key/value pair, use the `-backend-config="KEY=VALUE"` option when running
`terraform init`.
* **Interactively**: Terraform will interactively ask you for the required
values, unless interactive input is disabled. Terraform will not prompt for
optional values.
If backend settings are provided in multiple locations, the top-level
settings are merged such that any command-line options override the settings
in the main configuration and then the command-line options are processed
in order, with later options overriding values set by earlier options.
The final, merged configuration is stored on disk in the `.terraform`
directory, which should be ignored from version control. This means that
sensitive information can be omitted from version control, but it will be
present in plain text on local disk when running Terraform.
When using partial configuration, Terraform requires at a minimum that
an empty backend configuration is specified in one of the root Terraform
configuration files, to specify the backend type. For example:
```hcl
terraform {
backend "consul" {}
}
```
A backend configuration file has the contents of the `backend` block as
top-level attributes, without the need to wrap it in another `terraform`
or `backend` block:
```hcl
address = "demo.consul.io"
path = "example_app/terraform_state"
scheme = "https"
```
The same settings can alternatively be specified on the command line as
follows:
```
$ terraform init \
-backend-config="address=demo.consul.io" \
-backend-config="path=example_app/terraform_state" \
-backend-config="scheme=https"
```
The Consul backend also requires a Consul access token. Per the recommendation
above of omitting credentials from the configuration and using other mechanisms,
the Consul token would be provided by setting either the `CONSUL_HTTP_TOKEN`
or `CONSUL_HTTP_AUTH` environment variables. See the documentation of your
chosen backend to learn how to provide credentials to it outside of its main
configuration.
## Changing Configuration
You can change your backend configuration at any time. You can change
both the configuration itself as well as the type of backend (for example
from "consul" to "s3").
Terraform will automatically detect any changes in your configuration
and request a [reinitialization](/docs/backends/init.html). As part of
the reinitialization process, Terraform will ask if you'd like to migrate
your existing state to the new configuration. This allows you to easily
switch from one backend to another.
If you're using multiple [workspaces](/docs/state/workspaces.html),
Terraform can copy all workspaces to the destination. If Terraform detects
you have multiple workspaces, it will ask if this is what you want to do.
If you're just reconfiguring the same backend, Terraform will still ask if you
want to migrate your state. You can respond "no" in this scenario.
## Unconfiguring a Backend
If you no longer want to use any backend, you can simply remove the
configuration from the file. Terraform will detect this like any other
change and prompt you to [reinitialize](/docs/backends/init.html).
As part of the reinitialization, Terraform will ask if you'd like to migrate
your state back down to normal local state. Once this is complete then
Terraform is back to behaving as it does by default.

View File

@ -31,7 +31,7 @@ created, and published in [the dedicated _Modules_
section](/docs/modules/index.html). You can also learn more about how to use and
create modules with our hands-on [modules track on
learn.hashicorp.com](https://learn.hashicorp.com/terraform/modules/modules-overview?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
## Calling a Child Module
To _call_ a module means to include the contents of that module into the
@ -114,26 +114,14 @@ module "consul" {
}
```
The `version` attribute value may either be a single explicit version or
a version constraint expression. Constraint expressions use the following
syntax to specify a _range_ of versions that are acceptable:
* `>= 1.2.0`: version 1.2.0 or newer
* `<= 1.2.0`: version 1.2.0 or older
* `~> 1.2.0`: any non-beta version `>= 1.2.0` and `< 1.3.0`, e.g. `1.2.X`
* `~> 1.2`: any non-beta version `>= 1.2.0` and `< 2.0.0`, e.g. `1.X.Y`
* `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive
When depending on third-party modules, references to specific versions are
recommended since this ensures that updates only happen when convenient to you.
For modules maintained within your organization, a version range strategy
may be appropriate if a semantic versioning methodology is used consistently
or if there is a well-defined release process that avoids unwanted updates.
The `version` attribute accepts a [version constraint string](./version-constraints.html).
Terraform will use the newest installed version of the module that meets the
constraint; if no acceptable versions are installed, it will download the newest
version that meets the constraint.
Version constraints are supported only for modules installed from a module
registry, such as the [Terraform Registry](https://registry.terraform.io/) or
[Terraform Cloud's private module registry](/docs/cloud/registry/index.html).
registry, such as the public [Terraform Registry](https://registry.terraform.io/)
or [Terraform Cloud's private module registry](/docs/cloud/registry/index.html).
Other module sources can provide their own versioning mechanisms within the
source string itself, or might not support versions at all. In particular,
modules sourced from local file paths do not support `version`; since
@ -146,10 +134,8 @@ 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](#module-versions)
string that specifies which versions of the referenced module are acceptable.
The newest version matching the constraint will be used. `version` is supported
only for modules retrieved from module registries.
* `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

View File

@ -19,7 +19,7 @@ apply your configuration.
## Terraform Block Syntax
Terraform-specific settings are gathered together into `terraform` blocks:
Terraform settings are gathered together into `terraform` blocks:
```hcl
terraform {
@ -37,118 +37,59 @@ following sections.
## Configuring a Terraform Backend
The selected _backend_ for a Terraform configuration defines exactly where
and how operations are performed, where [state](/docs/state/index.html) is
stored, etc. Most non-trivial Terraform configurations will have a backend
configuration that configures a remote backend to allow collaboration within
a team.
The nested `backend` block configures which backend Terraform should use.
A backend configuration is given in a nested `backend` block within a
`terraform` block:
```hcl
terraform {
backend "s3" {
# (backend-specific settings...)
}
}
```
More information on backend configuration can be found in
[the _Backends_ section](/docs/backends/index.html).
The syntax and behavior of the `backend` block is described in [Backend
Configuration](./backend.html).
## Specifying a Required Terraform Version
The `required_version` setting can be used to constrain which versions of
the Terraform CLI can be used with your configuration. If the running version of
Terraform doesn't match the constraints specified, Terraform will produce
an error and exit without taking any further actions.
The `required_version` setting accepts a [version constraint
string,](./version-constraints.html) which specifies which versions of Terraform
can be used with your configuration.
When you use [child modules](./modules.html), each module
can specify its own version requirements. The requirements of all modules
in the tree must be satisfied.
If the running version of Terraform doesn't match the constraints specified,
Terraform will produce an error and exit without taking any further actions.
When you use [child modules](./modules.html), each module can specify its own
version requirements. The requirements of all modules in the tree must be
satisfied.
Use Terraform version constraints in a collaborative environment to
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,
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.
The value for `required_version` is a string containing a comma-separated
list of constraints. Each constraint is an operator followed by a version
number, such as `> 0.12.0`. The following constraint operators are allowed:
## Specifying Provider Requirements
* `=` (or no operator): exact version equality
[inpage-source]: #specifying-provider-requirements
* `!=`: version not equal
* `>`, `>=`, `<`, `<=`: version comparison, where "greater than" is a larger
version number
* `~>`: pessimistic constraint operator, constraining both the oldest and
newest version allowed. For example, `~> 0.9` is equivalent to
`>= 0.9, < 1.0`, and `~> 0.8.4`, is equivalent to `>= 0.8.4, < 0.9`
Re-usable modules should constrain only the minimum allowed version, such
as `>= 0.12.0`. This specifies the earliest version that the module is
compatible with while leaving the user of the module flexibility to upgrade
to newer versions of Terraform without altering the module.
## Specifying Required Provider Versions
The `required_providers` setting is a map specifying a version constraint for
each provider required by your configuration.
```hcl
terraform {
required_providers {
aws = ">= 2.7.0"
}
}
```
Version constraint strings within the `required_providers` block use the
same version constraint syntax as for
[the `required_version` argument](#specifying-a-required-terraform-version)
described above.
When a configuration contains multiple version constraints for a single
provider -- for example, if you're using multiple modules and each one has
its own constraint -- _all_ of the constraints must hold to select a single
provider version for the whole configuration.
Re-usable modules should constrain only the minimum allowed version, such
as `>= 1.0.0`. This specifies the earliest version that the module is
compatible with while leaving the user of the module flexibility to upgrade
to newer versions of the provider without altering the module.
Root modules should use a `~>` constraint to set both a lower and upper bound
on versions for each provider they depend on, as described in
[Provider Versions](providers.html#provider-versions).
An alternate syntax is also supported, but not intended for use at this time.
It exists to support future enhancements.
The `required_providers` block specifies all of the providers required by the
current module.
```hcl
terraform {
required_providers {
aws = {
version = ">= 2.7.0"
source = "hashicorp/aws"
}
}
}
```
For more information, see [Provider Requirements](provider-requirements.html).
## Experimental Language Features
From time to time the Terraform team will introduce new language features
initially via an opt-in experiment, so that the community can try the new
feature and give feedback on it prior to it becoming a backward-compatibility
constraint.
The Terraform team will sometimes introduce new language features initially via
an opt-in experiment, so that the community can try the new feature and give
feedback on it prior to it becoming a backward-compatibility constraint.
In releases where experimental features are available, you can enable them on
a per-module basis by setting the `experiments` argument inside a `terraform`
@ -184,6 +125,7 @@ if any, are available in a particular Terraform release.
The `terraform` block can have a nested `provider_meta` block for each
provider a module is using, if the provider defines a schema for it. This
allows the provider to receive module-specific information. No interpolations
are performed on this block. For more information, see the
[`provider_meta` page](/docs/internals/provider-meta.html).
allows the provider to receive module-specific information, and is primarily
intended for modules distributed by the same vendor as the associated provider.
For more information, see [Provider Metadata](/docs/internals/provider-meta.html).

View File

@ -0,0 +1,95 @@
---
layout: "docs"
page_title: "Version Constraints - Configuration Language"
---
# Version Constraints
Anywhere that Terraform lets you specify a range of acceptable versions for
something, it expects a specially formatted string known as a version
constraint. Version constraints are used when configuring:
- [Modules](./modules.html)
- [Provider requirements](./provider-requirements.html)
- [The `required_version` setting](./terraform.html#specifying-a-required-terraform-version) in the `terraform` block.
## Version Constraint Syntax
Terraform's syntax for version constraints is very similar to the syntax used by
other dependency management systems like Bundler and NPM.
```hcl
version = ">= 1.2.0, < 2.0.0"
```
A version constraint is a [string literal](./expressions.html#string-literals)
containing one or more conditions, which are separated by commas.
Each condition consists of an operator and a version number.
Version numbers should be a series of numbers separated by periods (like
`1.2.0`), optionally with a suffix to indicate a beta release.
The following operators are valid:
- `=` (or no operator): Allows only one exact version number. Cannot be combined
with other conditions.
- `!=`: Excludes an exact version number.
- `>`, `>=`, `<`, `<=`: Comparisons against a specified version, allowing
versions for which the comparison is true. "Greater-than" requests newer
versions, and "less-than" requests older versions.
- `~>`: Allows the specified version, plus newer versions that only
increase the _most specific_ segment of the specified version number. For
example, `~> 0.9` is equivalent to `>= 0.9, < 1.0`, and `~> 0.8.4`, is
equivalent to `>= 0.8.4, < 0.9`. This is usually called the pessimistic
constraint operator.
## Version Constraint Behavior
A version number that meets every applicable constraint is considered acceptable.
Terraform consults version constraints to determine whether it has acceptable
versions of itself, any required provider plugins, and any required modules. For
plugins and modules, it will use the newest installed version that meets the
applicable constraints.
If Terraform doesn't have an acceptable version of a required plugin or module,
it will attempt to download the newest version that meets the applicable
constraints.
If Terraform isn't able to obtain acceptable versions of external dependencies,
or if it doesn't have an acceptable version of itself, it won't proceed with any
plans, applies, or state manipulation actions.
Both the root module and any child module can constrain the acceptable versions
of Terraform and any providers they use. Terraform considers these constraints
equal, and will only proceed if all of them can be met.
A prerelease version is a version number that contains a suffix introduced by
a dash, like `1.2.0-beta`. A prerelease version can be selected only by an
_exact_ version constraint (the `=` operator or no operator). Prerelease
versions do not match inexact operators such as `>=`, `~>`, etc.
## Best Practices
### Module Versions
- When depending on third-party modules, require specific versions to ensure
that updates only happen when convenient to you.
- For modules maintained within your organization, specifying version ranges
may be appropriate if semantic versioning is used consistently or if there is
a well-defined release process that avoids unwanted updates.
### Terraform Core and Provider Versions
- Reusable modules should constrain only their minimum allowed versions of
Terraform and providers, such as `>= 0.12.0`. This helps avoid known
incompatibilities, while allowing the user of the module flexibility to
upgrade to newer versions of Terraform without altering the module.
- Root modules should use a `~>` constraint to set both a lower and upper bound
on versions for each provider they depend on.

View File

@ -10,8 +10,19 @@ description: |-
In some situations it's beneficial for a provider to offer an interface
through which modules can pass it information unrelated to the resources
in the module, but scoped on a per-module basis. The provider metadata
functionality allows a provider to do this in a straightforward way.
in the module, but scoped on a per-module basis.
Provider Metadata allows a provider to declare metadata fields it expects,
which individual modules can then populate independently of any provider
configuration. While provider configurations are often shared between modules,
provider metadata is always module-specific.
Provider Metadata is intended primarily for the situation where an official
module is developed by the same vendor that produced the provider it is
intended to work with, to allow the vendor to indirectly obtain usage
statistics for each module via the provider. For that reason, this
documentation is presented from the perspective of the provider developer
rather than the module developer.
~> **Advanced Topic!** This page covers technical details
of Terraform. You don't need to understand these details to

View File

@ -9,65 +9,91 @@
<li<%= sidebar_current("docs-config") %>>
<a href="/docs/configuration/index.html">0.12 and Newer</a>
<ul class="nav">
<li<%= sidebar_current("docs-config-resources") %>>
<a href="/docs/configuration/resources.html">Resources</a>
<li>
<a href="#">Configuration Blocks</a>
<ul class="nav nav-auto-expand">
<li<%= sidebar_current("docs-config-resources") %>>
<a href="/docs/configuration/resources.html">Resources</a>
</li>
<li>
<a href="/docs/configuration/providers.html">Provider Configuration</a>
</li>
<li<%= sidebar_current("docs-config-variables") %>>
<a href="/docs/configuration/variables.html">Input Variables</a>
</li>
<li<%= sidebar_current("docs-config-outputs") %>>
<a href="/docs/configuration/outputs.html">Output Values</a>
</li>
<li<%= sidebar_current("docs-config-locals") %>>
<a href="/docs/configuration/locals.html">Local Values</a>
</li>
<li<%= sidebar_current("docs-config-modules") %>>
<a href="/docs/configuration/modules.html">Modules</a>
</li>
<li<%= sidebar_current("docs-config-data-sources") %>>
<a href="/docs/configuration/data-sources.html">Data Sources</a>
</li>
<li>
<a href="/docs/configuration/backend.html">Backend Configuration</a>
</li>
<li<%= sidebar_current("docs-config-terraform") %>>
<a href="/docs/configuration/terraform.html">Terraform Settings</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-config-providers") %>>
<a href="/docs/configuration/providers.html">Providers</a>
<li>
<a href="#">Syntax</a>
<ul class="nav nav-auto-expand">
<li<%= sidebar_current("docs-config-syntax") %>>
<a href="/docs/configuration/syntax.html">Configuration Syntax</a>
</li>
<li<%= sidebar_current("docs-config-expressions") %>>
<a href="/docs/configuration/expressions.html">Expressions</a>
</li>
<li<%= sidebar_current("docs-config-functions") %>>
<a href="/docs/configuration/functions.html">Functions</a>
</li>
<li<%= sidebar_current("docs-config-override") %>>
<a href="/docs/configuration/override.html">Override Files</a>
</li>
<li<%= sidebar_current("docs-config-style") %>>
<a href="/docs/configuration/style.html">Style Conventions</a>
</li>
<li>
<a href="/docs/configuration/version-constraints.html">Version Constraints</a>
</li>
<li<%= sidebar_current("docs-config-types") %>>
<a href="/docs/configuration/types.html">Type Constraints</a>
</li>
<li<%= sidebar_current("docs-config-syntax-json") %>>
<a href="/docs/configuration/syntax-json.html">JSON Configuration Syntax</a>
</li>
</ul>
</li>
<li<%= sidebar_current("docs-config-variables") %>>
<a href="/docs/configuration/variables.html">Input Variables</a>
</li>
<li<%= sidebar_current("docs-config-outputs") %>>
<a href="/docs/configuration/outputs.html">Output Values</a>
</li>
<li<%= sidebar_current("docs-config-locals") %>>
<a href="/docs/configuration/locals.html">Local Values</a>
</li>
<li<%= sidebar_current("docs-config-modules") %>>
<a href="/docs/configuration/modules.html">Modules</a>
</li>
<li<%= sidebar_current("docs-config-data-sources") %>>
<a href="/docs/configuration/data-sources.html">Data Sources</a>
</li>
<li<%= sidebar_current("docs-config-syntax") %>>
<a href="/docs/configuration/syntax.html">Configuration Syntax</a>
</li>
<li<%= sidebar_current("docs-config-expressions") %>>
<a href="/docs/configuration/expressions.html">Expressions</a>
</li>
<li<%= sidebar_current("docs-config-functions") %>>
<a href="/docs/configuration/functions.html">Functions</a>
</li>
<li<%= sidebar_current("docs-config-terraform") %>>
<a href="/docs/configuration/terraform.html">Terraform Settings</a>
</li>
<li<%= sidebar_current("docs-config-override") %>>
<a href="/docs/configuration/override.html">Override Files</a>
</li>
<li<%= sidebar_current("docs-config-style") %>>
<a href="/docs/configuration/style.html">Style Conventions</a>
</li>
<li<%= sidebar_current("docs-config-types") %>>
<a href="/docs/configuration/types.html">Type Constraints</a>
</li>
<li<%= sidebar_current("docs-config-syntax-json") %>>
<a href="/docs/configuration/syntax-json.html">JSON Configuration Syntax</a>
</li>
</ul>
</li>