website: Don't claim that things are "very easy"

We typically try to avoid making subjective, boasty claims in our
documentation in recent times, but there remained both some older
documentation that we've not recently revised and also some newer examples
that are, in retrospect, also perhaps more "boasty" than they need to be.

We prefer not to use this sort of boasty language because not everyone
using Terraform has the same background and experience, and so what is
"easy" or "intuitive" to one person may not be so to another person, and
that should not suggest that the second person is in any way wrong or
inadequate.

In reviewing some of our use of the word "easy" here I tried as much as
possible to surgically revise the existing content without getting drawn
into a big rewrite, but in some cases the content was either pretty
unsalvageable (due to talking about obsolete features that were removed
long ago) or required some broader changes to make the result hopefully
still get the same facts across. In those cases I've both removed some
content entirely or adjusted larger paragraphs.

This was not an exhaustive review and so I'm sure there's still plenty of
room for similar improvements elsewhere. I also resisted the urge to
update some pages that contain outdated information about currently-active
features.
This commit is contained in:
Martin Atkins 2020-10-23 18:05:19 -07:00
parent d203401318
commit ddf9635af6
16 changed files with 42 additions and 273 deletions

View File

@ -1,135 +0,0 @@
---
layout: "docs"
page_title: "Backends: Migrating From 0.8.x and Earlier"
sidebar_current: "docs-backends-migrate"
description: |-
A "backend" in Terraform determines how state is loaded and how an operation such as `apply` is executed. This abstraction enables non-local file state storage, remote execution, etc.
---
# Backend & Legacy Remote State
Prior to Terraform 0.9.0 backends didn't exist and remote state management
was done in a completely different way. This page documents how you can
migrate to the new backend system and any considerations along the way.
Migrating to the new backends system is extremely simple. The only complex
case is if you had automation around configuring remote state. An existing
environment can be configured to use the new backend system after just
a few minutes of reading.
For the remainder of this document, the remote state system prior to
Terraform 0.9.0 will be called "legacy remote state."
-> **Note:** This page is targeted at users who used remote state prior
to version 0.9.0 and need to upgrade their environments. If you didn't
use remote state, you can ignore this document.
## Backwards Compatibility
In version 0.9.0, Terraform knows how to load and continue working with
legacy remote state. A warning is shown guiding you to this page, but
otherwise everything continues to work without changing any configuration.
Backwards compatibility with legacy remote state environments will be
removed in Terraform 0.11.0, or two major releases after 0.10.0. Starting
in 0.10.0, detection will remain but users will be _required_ to update
their configurations to use backends. In Terraform 0.11.0, detection and
loading will be completely removed.
For the short term, you may continue using Terraform with version 0.9.0
as you have been. However, you should begin planning to update your configuration
very soon. As you'll see, this process is very easy.
## Migrating to Backends
You should begin by reading the [complete backend documentation](/docs/backends)
section. This section covers in detail how you use and configure backends.
Next, perform the following steps to migrate. These steps will also guide
you through backing up your existing remote state just in case things don't
go as planned.
1. **With the older Terraform version (version 0.8.x),** run `terraform remote pull`. This
will cache the latest legacy remote state data locally. We'll use this for
a backup in case things go wrong.
1. Backup your `.terraform/terraform.tfstate` file. This contains the
cache we just pulled. Please copy this file to a location outside of your
Terraform module.
1. [Configure your backend](/docs/backends/config.html) in your Terraform
configuration. The backend type is the same backend type as you used with
your legacy remote state. The configuration should be setup to match the
same configuration you used with remote state.
1. [Run the init command](/docs/backends/init.html). This is an interactive
process that will guide you through migrating your existing remote state
to the new backend system. During this step, Terraform may ask if you want
to copy your old remote state into the newly configured backend. If you
configured the identical backend location, you may say no since it should
already be there.
1. Verify your state looks good by running `terraform plan` and seeing if
it detects your infrastructure. Advanced users may run `terraform state pull`
which will output the raw contents of your state file to your console. You
can compare this with the file you saved. There may be slight differences in
the serial number and version data, but the raw data should be almost identical.
After the above steps, you're good to go! Everyone who uses the same
Terraform state should copy the same steps above. The only difference is they
may be able to skip the configuration step if you're sharing the configuration.
At this point, **older Terraform versions will stop working.** Terraform
will prevent itself from working with state written with a higher version
of Terraform. This means that even other users using an older version of
Terraform with the same configured remote state location will no longer
be able to work with the environment. Everyone must upgrade.
## Rolling Back
If the migration fails for any reason: your states look different, your
plan isn't what you expect, you're getting errors, etc. then you may roll back.
After rolling back, please [report an issue](https://github.com/hashicorp/terraform)
so that we may resolve anything that may have gone wrong for you.
To roll back, follow the steps below using Terraform 0.8.x or earlier:
1. Remove the backend configuration from your Terraform configuration file.
2. Remove any "terraform.tfstate" files (including backups). If you believe
these may contain important data, you may back them up. Going with the assumption
that you started this migration guide with working remote state, these files
shouldn't contain anything of value.
3. Copy the `.terraform/terraform.tfstate` file you backed up back into
the same location.
And you're rolled back. If your backend migration worked properly and was
able to update your remote state, **then this will not work**. Terraform
prevents writing state that was written with a higher Terraform version
or a later serial number.
**If you're absolutely certain you want to restore your state backup**,
then you can use `terraform remote push -force`. This is extremely dangerous
and you will lose any changes that were in the remote location.
## Configuration Automation
The `terraform remote config` command has been replaced with
`terraform init`. The new command is better in many ways by allowing file-based
configuration, automatic state migration, and more.
You should be able to very easily migrate `terraform remote config`
scripting to the new `terraform init` command.
The new `terraform init` command takes a `-backend-config` flag which is
either an HCL file or a string in the format of `key=value`. This configuration
is merged with the backend configuration in your Terraform files.
This lets you keep secrets out of your actual configuration.
We call this "partial configuration" and you can learn more in the
docs on [configuring backends](/docs/backends/config.html).
This does introduce an extra step: your automation must generate a
JSON file (presumably JSON is easier to generate from a script than HCL
and HCL is compatible) to pass into `-backend-config`.

View File

@ -57,7 +57,7 @@ Many of the rewrite rules are completely automatic, but in some cases the
tool cannot determine enough information from the configuration alone to make tool cannot determine enough information from the configuration alone to make
a decision, and so it will instead add a comment to the configuration for a decision, and so it will instead add a comment to the configuration for
user review. All such comments contain the string `TF-UPGRADE-TODO` to make user review. All such comments contain the string `TF-UPGRADE-TODO` to make
them easy to find. them easier to find.
After upgrading, the configuration will also be reformatted into the standard After upgrading, the configuration will also be reformatted into the standard
Terraform style and expressions rewritten to use the more-readable v0.12 syntax Terraform style and expressions rewritten to use the more-readable v0.12 syntax

View File

@ -46,9 +46,8 @@ if you don't want to keep them around.
## Command-Line Friendly ## Command-Line Friendly
The output and command-line structure of the state subcommands is The output and command-line structure of the state subcommands is
designed to be easy to use with Unix command-line tools such as grep, awk, designed to be usable with Unix command-line tools such as grep, awk,
etc. Consequently, the output is also friendly to the equivalent PowerShell and similar PowerShell commands.
commands within Windows.
For advanced filtering and modification, we recommend piping Terraform For advanced filtering and modification, we recommend piping Terraform
state subcommands together with other command line tools. state subcommands together with other command line tools.

View File

@ -16,7 +16,7 @@ about Terraform 0.11 and earlier, see
Most Terraform configurations are written in Most Terraform configurations are written in
[the native Terraform language syntax](./syntax.html), which is designed to be [the native Terraform language syntax](./syntax.html), which is designed to be
easy for humans to read and update. relatively easy for humans to read and update.
Terraform also supports an alternative syntax that is JSON-compatible. This Terraform also supports an alternative syntax that is JSON-compatible. This
syntax is useful when generating portions of a configuration programmatically, syntax is useful when generating portions of a configuration programmatically,

View File

@ -20,8 +20,8 @@ syntax of the language in more detail, revealing the building blocks that
those constructs are built from. those constructs are built from.
This page describes the _native syntax_ of the Terraform language, which is This page describes the _native syntax_ of the Terraform language, which is
a rich language designed to be easy for humans to read and write. The a rich language designed to be relatively easy for humans to read and write.
constructs in the Terraform language can also be expressed in The constructs in the Terraform language can also be expressed in
[JSON syntax](./syntax-json.html), which is harder for humans [JSON syntax](./syntax-json.html), which is harder for humans
to read and edit but easier to generate and parse programmatically. to read and edit but easier to generate and parse programmatically.

View File

@ -111,7 +111,7 @@ the value for a variable. If no type constraint is set then a value of any type
is accepted. is accepted.
While type constraints are optional, we recommend specifying them; they While type constraints are optional, we recommend specifying them; they
serve as easy reminders for users of the module, and can serve as helpful reminders for users of the module, and they
allow Terraform to return a helpful error message if the wrong type is used. allow Terraform to return a helpful error message if the wrong type is used.
Type constraints are created from a mixture of type keywords and type Type constraints are created from a mixture of type keywords and type

View File

@ -1,75 +0,0 @@
---
layout: "docs"
page_title: "Internal Plugins"
sidebar_current: "docs-internals-plugins"
description: |-
Terraform includes many popular plugins compiled into the main binary.
---
# Internal Plugins
Terraform providers and provisioners are provided via plugins. Each plugin provides an implementation for a specific service, such as AWS, or provisioner, such as bash. Plugins are executed as a separate process and communicate with the main Terraform binary over an RPC interface.
# Upgrading From Versions Earlier Than 0.7
In versions of Terraform prior to 0.7, each plugin shipped as a separate binary. In versions of Terraform >= 0.7, all of the official plugins are shipped as a single binary. This saves a lot of disk space and makes downloads faster for you!
However, when you upgrade you will need to manually delete old plugins from disk. You can do this via something like this, depending on where you installed `terraform`:
rm /usr/local/bin/terraform-*
If you don't do this you will see an error message like the following:
```text
[WARN] /usr/local/bin/terraform-provisioner-file overrides an internal plugin for file-provisioner.
If you did not expect to see this message you will need to remove the old plugin.
See https://www.terraform.io/docs/internals/plugins.html
Error configuring: 2 error(s) occurred:
* Unrecognized remote plugin message: 2|unix|/var/folders/pj/66q7ztvd17v_vgfg8c99gm1m0000gn/T/tf-plugin604337945
This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.
* Unrecognized remote plugin message: 2|unix|/var/folders/pj/66q7ztvd17v_vgfg8c99gm1m0000gn/T/tf-plugin647987867
This usually means that the plugin is either invalid or simply
needs to be recompiled to support the latest protocol.
```
## Why Does This Happen?
In previous versions of Terraform all of the plugins were included in a zip file. For example, when you upgraded from 0.6.12 to 0.6.15, the newer version of each plugin file would have replaced the older one on disk, and you would have ended up with the latest version of each plugin.
Going forward there is only one file in the distribution so you will need to perform a one-time cleanup when upgrading from Terraform < 0.7 to Terraform 0.7 or higher.
If you're curious about the low-level details, keep reading!
## Go Plugin Architecture
Terraform is written in the Go programming language. One of Go's interesting properties is that it produces statically-compiled binaries. This means that it does not need to find libraries on your computer to run, and in general only needs to be compatible with your operating system (to make system calls) and with your CPU architecture (so the assembly instructions match the CPU you're running on).
Another property of Go is that it does not support dynamic libraries. It _only_ supports static binaries. This is part of Go's overall design and is the reason why it produces statically-compiled binaries in the first place -- once you have a Go binary for your platform it should _Just Work_.
In other languages, plugins are built using dynamic libraries. Since this is not an option for us in Go we use a network RPC interface instead. This means that each plugin is an independent program, and instead of communicating via shared memory, the main process communicates with the plugin process over HTTP. When you start Terraform, it identifies the plugin you want to use, finds it on disk, runs the other binary, and does some handshaking to make sure they can talk to each other (the error you may see after upgrading is a handshake failure in the RPC code).
### Downsides
There is a significant downside to this approach. Statically compiled binaries are much larger than dynamically-linked binaries because they include everything they need to run. And because Terraform shares a lot of code with its plugins, there is a lot of binary data duplicated between each of these programs.
In Terraform 0.6.15 there were 42 programs in total, using around 750MB on disk. And it turns out that about 600MB of this is duplicate data! This uses up a lot of space on your hard drive and a lot of bandwidth on our CDN. Fortunately, there is a way to resolve this problem.
### Our Solution
In Terraform 0.7 we merged all of the programs into the same binary. We do this by using a special command `terraform internal-plugin` which allows us to invoke a plugin just by calling the same Terraform binary with extra arguments. In essence, Terraform now just calls itself in order to activate the special behavior in each plugin.
### Supporting our Community
> Why would you do this? Why not just eliminate the network RPC interface and simplify everything?
Terraform is an open source project with a large community, and while we maintain a wide range of plugins as part of the core distribution, we also want to make it easy for people anywhere to write and use their own plugins.
By using the network RPC interface, you can build and distribute a plugin for Terraform without having to rebuild Terraform itself. This makes it easy for you to build a Terraform plugin for your organization's internal use, for a proprietary API that you don't want to open source, or to prototype something before contributing it back to the main project.
In theory, because the plugin interface is HTTP, you could even develop a plugin using a completely different programming language! (Disclaimer, you would also have to re-implement the plugin API which is not a trivial amount of work.)
So to conclude, with the RPC interface _and_ internal plugins, we get the best of all of these features: Binaries that _Just Work_, savings from shared code, and extensibility through plugins. We hope you enjoy using these features in Terraform.

View File

@ -205,8 +205,8 @@ suitable credentials for that repository.
If you use the SSH protocol then any configured SSH keys will be used If you use the SSH protocol then any configured SSH keys will be used
automatically. This is the most common way to access non-public Git automatically. This is the most common way to access non-public Git
repositories from automated systems because it is easy to configure repositories from automated systems because it allows access to private
and allows access to private repositories without interactive prompts. repositories without interactive prompts.
If using the HTTP/HTTPS protocol, or any other protocol that uses If using the HTTP/HTTPS protocol, or any other protocol that uses
username/password credentials, configure username/password credentials, configure
@ -272,8 +272,8 @@ with suitable credentials for that repository.
If you use the SSH protocol then any configured SSH keys will be used If you use the SSH protocol then any configured SSH keys will be used
automatically. This is the most common way to access non-public Mercurial automatically. This is the most common way to access non-public Mercurial
repositories from automated systems because it is easy to configure repositories from automated systems because it allows access to private
and allows access to private repositories without interactive prompts. repositories without interactive prompts.
If your Terraform configuration will be used within [Terraform Cloud](https://www.hashicorp.com/products/terraform), If your Terraform configuration will be used within [Terraform Cloud](https://www.hashicorp.com/products/terraform),
only SSH key authentication is supported, and only SSH key authentication is supported, and

View File

@ -40,12 +40,8 @@ a basic development environment setup.
## Provider Plugin Codebases ## Provider Plugin Codebases
Provider plugins live outside of the Terraform core codebase in their own Provider plugins live outside of the Terraform core codebase in their own
source code repositories. The official set of provider plugins released by source code repositories, and are typically published in a provider registry
HashiCorp (developed by both HashiCorp staff and community contributors) such as [the public Terraform Registry](https://registry.terraform.io/).
all live in repositories in
[the `terraform-providers` organization](https://github.com/terraform-providers)
on GitHub, but third-party plugins can be maintained in any source code
repository.
When developing a provider plugin, it is recommended to use a common `GOPATH` When developing a provider plugin, it is recommended to use a common `GOPATH`
that includes both the core Terraform repository and the repositories of any that includes both the core Terraform repository and the repositories of any
@ -106,20 +102,13 @@ own core providers.
## helper/schema ## helper/schema
The `helper/schema` library is a framework we've built to make creating The `helper/schema` package in the plugin SDK is a framework designed to allow
providers extremely easy. This is the same library we use to build most building providers at a higher level of abstraction than the raw plugin protocol
of the core providers. that Terraform expects. This is the same library we've used to build most
of the official providers.
To give you an idea of how productive you can become with this framework: For more information on `helper/schema`, see
we implemented the Google Cloud provider in about 6 hours of coding work. [the `helper/schema` package reference documentation](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/helper/schema).
This isn't a simple provider, and we did have knowledge of
the framework beforehand, but it goes to show how expressive the framework
can be.
The GoDoc for `helper/schema` can be
[found here](https://godoc.org/github.com/hashicorp/terraform/helper/schema).
This is API-level documentation but will be extremely important
for you going forward.
## Provider ## Provider

View File

@ -12,13 +12,13 @@ The [Terraform Registry](https://registry.terraform.io) is an interactive resour
![screenshot: terraform registry landing page](./images/registry1.png) ![screenshot: terraform registry landing page](./images/registry1.png)
The Terraform Registry is integrated [directly into Terraform](/docs/configuration/provider-requirements.html) to make it easy to use providers and modules. Anyone can publish and consume providers and modules on the public [Terraform Registry](https://registry.terraform.io). (To publish private modules within your organization, you can use a [private registry](/docs/registry/private.html) or [reference repositories and other sources directly](/docs/modules/sources.html).) The Terraform Registry is integrated [directly into Terraform](/docs/configuration/provider-requirements.html) so you can directly specify providers and modules. Anyone can publish and consume providers and modules on the public [Terraform Registry](https://registry.terraform.io). (To publish private modules within your organization, you can use a [private registry](/docs/registry/private.html) or [reference repositories and other sources directly](/docs/modules/sources.html).)
Use the navigation to the left to learn more about using the Terraform Registry. Use the navigation to the left to learn more about using the Terraform Registry.
## Navigating the Registry ## Navigating the Registry
As the Terraform ecosystem continues to grow, the Registry is designed to make it easy to discover integrations and solutions across dozens of categories. Select a provider or module card to learn more, filter results to a [specific tier](./providers/index.html#provider-tiers-amp-namespaces), or use the search field at the top of the Registry to find what youre looking for. (Note that search supports keyboard navigation.) The registry has a number of different categories for both modules and providers to help with navigating the large number of available options. Select a provider or module card to learn more, filter results to a [specific tier](./providers/index.html#provider-tiers-amp-namespaces), or use the search field at the top of the Registry to find what youre looking for. (Note that search supports keyboard navigation.)
![screenshot: terraform registry browse](./images/registry2.png) ![screenshot: terraform registry browse](./images/registry2.png)

View File

@ -25,10 +25,7 @@ any submodules or examples in the module's source repository.
## Requirements ## Requirements
The list below contains all the requirements for publishing a module. The list below contains all the requirements for publishing a module:
Meeting the requirements for publishing a module is extremely easy. The
list may appear long only to ensure we're detailed, but adhering to the
requirements should happen naturally.
- **GitHub.** The module must be on GitHub and must be a public repo. - **GitHub.** The module must be on GitHub and must be a public repo.
This is only a requirement for the [public registry](https://registry.terraform.io). This is only a requirement for the [public registry](https://registry.terraform.io).

View File

@ -26,9 +26,9 @@ modules as well.
## Using Modules ## Using Modules
The Terraform Registry is integrated directly into Terraform. This makes The Terraform Registry is integrated directly into Terraform, so a Terraform
it easy to reference any module in the registry. The syntax for referencing configuration can refer to any module published in the registry. The syntax for
a registry module is `<NAMESPACE>/<NAME>/<PROVIDER>`. For example: specifying a registry module is `<NAMESPACE>/<NAME>/<PROVIDER>`. For example:
`hashicorp/consul/aws`. `hashicorp/consul/aws`.
~> **Note:** Module registry integration was added in Terraform v0.10.6, and full versioning support in v0.11.0. ~> **Note:** Module registry integration was added in Terraform v0.10.6, and full versioning support in v0.11.0.

View File

@ -8,7 +8,7 @@ description: |-
# Publishing Providers # Publishing Providers
Anyone can publish and share a provider by signing into the Registry using their GitHub account and following a few easy steps. Anyone can publish and share a provider by signing into the Registry using their GitHub account and following a few additional steps.
This page describes how to prepare a [Terraform Provider](/docs/plugins/provider.html) for publishing, and how to publish a prepared provider using the Registry's interface. This page describes how to prepare a [Terraform Provider](/docs/plugins/provider.html) for publishing, and how to publish a prepared provider using the Registry's interface.

View File

@ -19,18 +19,14 @@ which can then be shared between all members of a team. Terraform supports
storing state in [Terraform Cloud](https://www.hashicorp.com/products/terraform/), storing state in [Terraform Cloud](https://www.hashicorp.com/products/terraform/),
[HashiCorp Consul](https://www.consul.io/), Amazon S3, Azure Blob Storage, Google Cloud Storage, Alibaba Cloud OSS, and more. [HashiCorp Consul](https://www.consul.io/), Amazon S3, Azure Blob Storage, Google Cloud Storage, Alibaba Cloud OSS, and more.
Remote state is a feature of [backends](/docs/backends). Configuring and Remote state is a feature of [backends](/docs/backends), which you can activate
using remote backends is easy and you can get started with remote state in your configuration's root module.
quickly. If you then want to migrate back to using local state, backends make
that easy as well.
## Delegation and Teamwork ## Delegation and Teamwork
Remote state gives you more than just easier version control and Remote state allows you to share
safer storage. It also allows you to delegate the [output values](/docs/configuration/outputs.html) with other configurations.
[outputs](/docs/configuration/outputs.html) to other teams. This allows This allows your infrastructure to be decomposed into smaller components.
your infrastructure to be more easily broken down into components that
multiple teams can access.
Put another way, remote state also allows teams to share infrastructure Put another way, remote state also allows teams to share infrastructure
resources in a read-only way without relying on any additional configuration resources in a read-only way without relying on any additional configuration
@ -45,8 +41,8 @@ remote state and have other Terraform states consume that.
For example usage, see For example usage, see
[the `terraform_remote_state` data source](/docs/providers/terraform/d/remote_state.html). [the `terraform_remote_state` data source](/docs/providers/terraform/d/remote_state.html).
While remote state is a convenient, built-in mechanism for sharing data While remote state can be a convenient, built-in mechanism for sharing data
between configurations, it is also possible to use more general stores to between configurations, you may prefer to use more general stores to
pass settings both to other configurations and to other consumers. For example, pass settings both to other configurations and to other consumers. For example,
if your environment has [HashiCorp Consul](https://www.consul.io/) then you if your environment has [HashiCorp Consul](https://www.consul.io/) then you
can have one Terraform configuration that writes to Consul using can have one Terraform configuration that writes to Consul using

View File

@ -13,11 +13,13 @@ that already exists. Terraform is not a configuration management tool,
and it allows existing tooling to focus on their strengths: bootstrapping and it allows existing tooling to focus on their strengths: bootstrapping
and initializing resources. and initializing resources.
Using provisioners, Terraform enables any configuration management tool Terraform focuses on the higher-level abstraction of the datacenter and
to be used to setup a resource once it has been created. Terraform associated services, while allowing you to use configuration management
focuses on the higher-level abstraction of the datacenter and associated tools on individual systems. It also aims to bring the same benefits of
services, without sacrificing the ability to use configuration management codification of your system configuration to infrastructure management.
tools to do what they do best. It also embraces the same codification that
is responsible for the success of those tools, making entire infrastructure If you are using traditional configuration management within your compute
deployments easy and reliable. instances, you can use Terraform to configure bootstrapping software like
cloud-init to activate your configuration management software on first
system boot.

View File

@ -531,10 +531,6 @@
<a href="/docs/internals/remote-service-discovery.html">Remote Service Discovery</a> <a href="/docs/internals/remote-service-discovery.html">Remote Service Discovery</a>
</li> </li>
<li<%= sidebar_current("docs-internals-plugins") %>>
<a href="/docs/internals/internal-plugins.html">Internal Plugins</a>
</li>
<li<%= sidebar_current("docs-internals-provider-meta") %>> <li<%= sidebar_current("docs-internals-provider-meta") %>>
<a href="/docs/internals/provider-meta.html">Provider Metadata</a> <a href="/docs/internals/provider-meta.html">Provider Metadata</a>
</li> </li>