website: (Re)Move markdown documentation (#37417)

* website: (Re)Move markdown documentation

* make: remove website targets

* gitignore: remove website paths

* CODEOWNERS: remove website paths

* gh/ISSUE_TEMPLATE: Direct folks to unified repo for docs

* Readme: Update link to docs

* Update refs to website folder

* Re-add Readme.md with a warning and link to the unified repo
This commit is contained in:
Radek Simko 2025-08-11 10:25:18 +01:00 committed by GitHub
parent cfe0464bf8
commit 6d11e670c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
353 changed files with 8 additions and 70469 deletions

View file

@ -21,3 +21,6 @@ contact_links:
- name: Terraform Usage, Language, or Workflow Questions
url: https://discuss.hashicorp.com/c/terraform-core
about: Please ask and answer language or workflow related questions through the Terraform Core Community Forum.
- name: Documentation Issue
url: https://github.com/hashicorp/web-unified-docs
about: Documentation has its own repository for all HashiCorp products and related issues or questions should be directed there.

View file

@ -1,76 +0,0 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
name: Documentation Issue
description: Report an issue or suggest a change in the documentation.
labels: ["documentation", "new"]
body:
- type: markdown
attributes:
value: |
# Thank you for opening a documentation change request.
Please only use the [hashicorp/terraform](https://github.com/hashicorp/terraform) `Documentation` issue type to report problems with the documentation on [https://developer.hashicorp.com/terraform/docs](). Only technical writers (not engineers) monitor this issue type. Report Terraform bugs or feature requests with the `Bug report` or `Feature Request` issue types instead to get engineering attention.
For general usage questions, please see the [Community Forum](https://discuss.hashicorp.com/c/terraform-core/27).
- type: textarea
id: tf-version
attributes:
label: Terraform Version
description: Run `terraform version` to show the version, and paste the result below. If you're not using the latest version, please check to see if something related to your request has already been implemented in a later version.
render: shell
placeholder: ...output of `terraform version`...
value:
validations:
required: true
- type: textarea
id: tf-affected-pages
attributes:
label: Affected Pages
description: |
Link to the pages relevant to your documentation change request.
placeholder:
value:
validations:
required: false
- type: textarea
id: tf-problem
attributes:
label: What is the docs issue?
description: What problems or suggestions do you have about the documentation?
placeholder:
value:
validations:
required: true
- type: textarea
id: tf-proposal
attributes:
label: Proposal
description: What documentation changes would fix this issue and where would you expect to find them? Are one or more page headings unclear? Do one or more pages need additional context, examples, or warnings? Do we need a new page or section dedicated to a specific topic? Your ideas help us understand what you and other users need from our documentation and how we can improve the content.
placeholder:
value:
validations:
required: false
- type: textarea
id: tf-references
attributes:
label: References
description: |
Are there any other open or closed GitHub issues related to the problem or solution you described? If so, list them below. For example:
```
- #6017
```
placeholder:
value:
validations:
required: false
- type: markdown
attributes:
value: |
**Note:** If the submit button is disabled and you have filled out all required fields, please check that you did not forget a **Title** for the issue.

5
.gitignore vendored
View file

@ -4,10 +4,6 @@
bin/
modules-dev/
/pkg/
website/.vagrant
website/.bundle
website/build
website/node_modules
.vagrant/
*.backup
*.bak
@ -22,7 +18,6 @@ go.work*
/terraform
website/vendor
vendor/
# Coverage

View file

@ -32,25 +32,3 @@
builtin/provisioners/file @hashicorp/terraform-core
builtin/provisioners/local-exec @hashicorp/terraform-core
builtin/provisioners/remote-exec @hashicorp/terraform-core
# engineering and web presence get notified of, and can approve changes to web tooling, but not content at developer.hashicorp.com/terraform/docs
/website/ @hashicorp/web-presence @hashicorp/terraform-core
/website/data/
/website/public/
/website/content/
# education and engineering get notified of, and can approve changes to web content at developer.hashicorp.com/terraform/docs
/website/data/ @hashicorp/terraform-education @hashicorp/terraform-core
/website/docs/ @hashicorp/terraform-education @hashicorp/terraform-core
/website/img/ @hashicorp/terraform-education @hashicorp/terraform-core
/website/README.md @hashicorp/terraform-education @hashicorp/terraform-core
/website/public/ @hashicorp/terraform-education @hashicorp/terraform-core
/website/content/ @hashicorp/terraform-education @hashicorp/terraform-core
# Backend maintainers also get co-ownership of their backend docs pages
/website/docs/language/backend/azurerm.mdx @hashicorp/terraform-education @hashicorp/terraform-core @hashicorp/terraform-azure
/website/docs/language/backend/gcs.mdx @hashicorp/terraform-education @hashicorp/terraform-core @hashicorp/tf-eco-hybrid-cloud
/website/docs/language/backend/kubernetes.mdx @hashicorp/terraform-education @hashicorp/terraform-core @hashicorp/tf-eco-hybrid-cloud
/website/docs/language/backend/s3.mdx @hashicorp/terraform-education @hashicorp/terraform-core @hashicorp/terraform-aws

View file

@ -39,21 +39,9 @@ copyrightfix:
syncdeps:
"$(CURDIR)/scripts/syncdeps.sh"
# Run this if working on the website locally to run in watch mode.
website:
$(MAKE) -C website website
# Use this if you have run `website/build-local` to use the locally built image.
website/local:
$(MAKE) -C website website/local
# Run this to generate a new local Docker image.
website/build-local:
$(MAKE) -C website website/build-local
# disallow any parallelism (-j) for Make. This is necessary since some
# commands during the build process create temporary files that collide
# under parallel conditions.
.NOTPARALLEL:
.PHONY: fmtcheck importscheck vetcheck generate protobuf staticcheck syncdeps website website/local website/build-local
.PHONY: fmtcheck importscheck vetcheck generate protobuf staticcheck syncdeps

View file

@ -41,7 +41,7 @@ This repository contains only Terraform core, which includes the command line in
- To learn more about how we handle bug reports, refer to the [bug triage guide](./BUGPROCESS.md).
- To learn how to contribute to the Terraform documentation in this repository, refer to the [Terraform Documentation README](/website/README.md).
- To learn how to contribute to the Terraform documentation, refer to the [Web Unified Docs repository](https://github.com/hashicorp/web-unified-docs).
## License

View file

@ -115,7 +115,7 @@ func initCommands(
// The command list is included in the terraform -help
// output, which is in turn included in the docs at
// website/docs/cli/commands/index.html.markdown; if you
// .../docs/cli/commands/index.mdx (in web-unified-docs); if you
// add, remove or reclassify commands then consider updating
// that to match.

View file

@ -44,7 +44,7 @@ func helpFunc(commands map[string]cli.CommandFactory) string {
sort.Strings(otherCommands)
// The output produced by this is included in the docs at
// website/source/docs/cli/commands/index.html.markdown; if you
// .../docs/cli/commands/index.mdx (in web-unified-docs); if you
// change this then consider updating that to match.
helpText := fmt.Sprintf(`
Usage: terraform [global options] <subcommand> [args]

View file

@ -1,60 +0,0 @@
######################################################
# NOTE: This file is managed by the Digital Team's #
# Terraform configuration @ hashicorp/mktg-terraform #
######################################################
.DEFAULT_GOAL := website
# Set the preview mode for the website shell to "developer" or "io"
PREVIEW_MODE ?= developer
REPO ?= terraform
# Enable setting alternate docker tool, e.g. 'make DOCKER_CMD=podman'
DOCKER_CMD ?= docker
CURRENT_GIT_BRANCH=$$(git rev-parse --abbrev-ref HEAD)
LOCAL_CONTENT_DIR=../docs
PWD=$$(pwd)
DOCKER_IMAGE="hashicorp/dev-portal"
DOCKER_IMAGE_LOCAL="dev-portal-local"
DOCKER_RUN_FLAGS=-it \
--publish "3000:3000" \
--rm \
--tty \
--volume "$(PWD)/docs:/app/docs" \
--volume "$(PWD)/img:/app/public" \
--volume "$(PWD)/data:/app/data" \
--volume "$(PWD)/redirects.js:/app/redirects.js" \
--volume "next-dir:/app/website-preview/.next" \
--volume "$(PWD)/.env:/app/.env" \
--volume "$(PWD)/.env.development:/app/website-preview/.env.development" \
--volume "$(PWD)/.env.local:/app/website-preview/.env.local" \
-e "REPO=$(REPO)" \
-e "PREVIEW_FROM_REPO=$(REPO)" \
-e "IS_CONTENT_PREVIEW=true" \
-e "LOCAL_CONTENT_DIR=$(LOCAL_CONTENT_DIR)" \
-e "CURRENT_GIT_BRANCH=$(CURRENT_GIT_BRANCH)" \
-e "PREVIEW_MODE=$(PREVIEW_MODE)"
# Default: run this if working on the website locally to run in watch mode.
.PHONY: website
website:
@echo "==> Downloading latest Docker image..."
@$(DOCKER_CMD) pull $(DOCKER_IMAGE)
@echo "==> Starting website..."
@$(DOCKER_CMD) run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE)
# Use this if you have run `website/build-local` to use the locally built image.
.PHONY: website/local
website/local:
@echo "==> Starting website from local image..."
@$(DOCKER_CMD) run $(DOCKER_RUN_FLAGS) $(DOCKER_IMAGE_LOCAL)
# Run this to generate a new local Docker image.
.PHONY: website/build-local
website/build-local:
@echo "==> Building local Docker image"
@$(DOCKER_CMD) build https://github.com/hashicorp/dev-portal.git\#main \
-t $(DOCKER_IMAGE_LOCAL)

View file

@ -2,90 +2,5 @@
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
This directory contains the portions of [the Terraform website](https://www.terraform.io/) that pertain to the core functionality, excluding providers and the overall configuration.
The website uses the files in this directory in conjunction with
[the `terraform-website` repository](https://github.com/hashicorp/terraform-website). The `terraform-website` repository brings all of the documentation together and contains the scripts for testing and building the entire site.
## Suggesting Changes
You can [submit an issue](https://github.com/hashicorp/terraform/issues/new/choose) with documentation requests or submit a pull request with suggested changes.
Click **Edit this page** at the bottom of any Terraform website page to go directly to the associated markdown file in GitHub.
## Validating Content
Content changes are automatically validated against a set of rules as part of the pull request process. If you want to run these checks locally to validate your content before committing your changes, you can run the following command:
```
npm run content-check
```
If the validation fails, actionable error messages will be displayed to help you address detected issues.
## Modifying Sidebar Navigation
You must update the sidebar navigation when you add or delete documentation .mdx files. If you do not update the navigation, the website deploy preview fails.
To update the sidebar navigation, you must edit the appropriate `nav-data.json` file. This repository contains the sidebar navigation files for the following documentation sets:
- Terraform Language: [`language-nav-data.json`](https://github.com/hashicorp/terraform/blob/main/website/data/language-nav-data.json)
- Terraform CLI: [`cli-nav-data.json`](https://github.com/hashicorp/terraform/blob/main/website/data/cli-nav-data.json)
- Introduction to Terraform: [`intro-nav-data.json`](https://github.com/hashicorp/terraform/blob/update-readme/website/data/intro-nav-data.json)
For more details about how to update the sidebar navigation, refer to [Editing Navigation Sidebars](https://github.com/hashicorp/terraform-website#editing-navigation-sidebars) in the `terraform-website` repository.
## Adding Redirects
You must add a redirect when you move, rename, or delete documentation pages. Refer to https://github.com/hashicorp/terraform-docs-common#redirects for details.
## Previewing Changes
You should preview all of your changes locally before creating a pull request. The build includes content from this repository and the [`terraform-website`](https://github.com/hashicorp/terraform-website/) repository, allowing you to preview the entire Terraform documentation site.
**Set Up Local Environment**
1. [Install Docker](https://docs.docker.com/get-docker/).
2. [Install Go](https://golang.org/doc/install) or create a `~/go` directory manually.
3. Open terminal and set `GOPATH` as an environment variable:
Bash: `export $GOPATH=~/go`(bash)
Zsh: `echo -n 'export GOPATH=~/go' >> ~/.zshrc`
4. Restart your terminal or command line session.
**Launch Site Locally**
1. Navigate into your local `terraform` top-level directory and run `make website`.
1. Open `http://localhost:3000` in your web browser. While the preview is running, you can edit pages and Next.js automatically rebuilds them.
1. Press `ctrl-C` in your terminal to stop the server and end the preview.
## Deploying Changes
Merging a PR to `main` queues up documentation changes for the next minor product release. Your changes are not immediately available on the website.
The website generates versioned documentation by pointing to the HEAD of the release branch for that version. For example, the `v1.2.x` documentation on the website points to the HEAD of the `v1.2` release branch in the `terraform` repository. To update existing documentation versions, you must also backport your changes to that release branch. Backported changes become live on the site within one hour.
### Backporting
**Important:** Editing old versions (not latest) should be rare. We backport to old versions when there is an egregious error. Egregious errors include inaccuracies that could cause security vulnerabilities or extreme inconvenience for users.
Backporting involves cherry-picking commits to one or more release branches within a docs repository. You can backport (cherry-pick) commits to a version branch by adding the associated backport label to your pull request. For example, if you need to add a security warning to the v1.1 documentation, you must add the `1.1-backport` label. When you merge a pull request with one or more backport labels, GitHub Actions opens a backport PR to cherry-pick your changes to the associated release branches. You must manually merge the backport PR to finish backporting the changes.
To make your changes available on the latest docs version:
1. Add the backport label for the latest version.
<img width="317" alt="Screen Shot 2022-08-09 at 11 06 17 AM" src="https://user-images.githubusercontent.com/83350965/183686586-f94e58f3-fd62-48cf-88bd-fa886fe4724f.png">
1. Merge the pull request. GitHub Actions autogenerates a backport pull request, linked to the original.
<img width="726" alt="Screen Shot 2022-08-09 at 11 08 52 AM" src="https://user-images.githubusercontent.com/83350965/183687165-350b0e9b-a888-409e-91e2-81d82eac0a4e.png">
1. Merge the auto-generated backport pull request.
You can review and merge your own backport pull request without waiting for another review if the changes in the backport pull request are effectively equivalent to the original. You can make minor adjustments to resolve merge conflicts, but you should not merge a backport PR that contains major content or functionality changes from the original, approved pull request. If you are not sure whether it is okay to merge a backport pull request, post a comment on the original pull request to discuss with the team.

View file

@ -1,422 +0,0 @@
[
{ "heading": "Terraform CLI" },
{ "title": "Overview", "path": "" },
{ "title": "Basic CLI Features", "href": "/cli/commands" },
{
"title": "Initializing Working Directories",
"routes": [
{ "title": "Overview", "path": "init" },
{ "title": "<code>init</code>", "href": "/cli/commands/init" },
{ "title": "<code>get</code>", "href": "/cli/commands/get" }
]
},
{
"title": "Provisioning Infrastructure",
"routes": [
{ "title": "Overview", "path": "run" },
{ "title": "<code>plan</code>", "href": "/cli/commands/plan" },
{ "title": "<code>apply</code>", "href": "/cli/commands/apply" },
{ "title": "<code>destroy</code>", "href": "/cli/commands/destroy" }
]
},
{
"title": "Authenticating",
"routes": [
{ "title": "Overview", "path": "auth" },
{ "title": "<code>login</code>", "href": "/cli/commands/login" },
{ "title": "<code>logout</code>", "href": "/cli/commands/logout" }
]
},
{
"title": "Writing and Modifying Code",
"routes": [
{ "title": "Overview", "path": "code" },
{ "title": "<code>console</code>", "href": "/cli/commands/console" },
{ "title": "<code>fmt</code>", "href": "/cli/commands/fmt" },
{ "title": "<code>validate</code>", "href": "/cli/commands/validate" }
]
},
{
"title": "Inspecting Infrastructure",
"routes": [
{ "title": "Overview", "path": "inspect" },
{ "title": "<code>graph</code>", "href": "/cli/commands/graph" },
{ "title": "<code>output</code>", "href": "/cli/commands/output" },
{ "title": "<code>show</code>", "href": "/cli/commands/show" },
{
"title": "<code>state list</code>",
"href": "/cli/commands/state/list"
},
{
"title": "<code>state show</code>",
"href": "/cli/commands/state/show"
}
]
},
{
"title": "Import Infrastructure",
"routes": [
{ "title": "Overview", "path": "import" },
{ "title": "Import existing resources", "path": "import/usage" },
{
"title": "Reference",
"href": "/cli/commands/import"
}
]
},
{
"title": "Manually Update State",
"routes": [
{ "title": "Overview", "path": "state" },
{
"title": "Resource Addressing",
"path": "state/resource-addressing"
},
{ "title": "<code>state</code>", "href": "/cli/commands/state" },
{
"title": "Inspecting State",
"routes": [
{ "title": "Overview", "path": "state/inspect" },
{
"title": "<code>state list</code>",
"href": "/cli/commands/state/list"
},
{
"title": "<code>state show</code>",
"href": "/cli/commands/state/show"
},
{
"title": "<code>refresh</code>",
"href": "/cli/commands/refresh"
}
]
},
{
"title": "Forcing Re-creation (Tainting)",
"routes": [
{ "title": "Overview", "path": "state/taint" },
{
"title": "<code>taint</code>",
"href": "/cli/commands/taint"
},
{
"title": "<code>untaint</code>",
"href": "/cli/commands/untaint"
}
]
},
{
"title": "Moving Resources",
"routes": [
{ "title": "Overview", "path": "state/move" },
{
"title": "<code>state mv</code>",
"href": "/cli/commands/state/mv"
},
{
"title": "<code>state rm</code>",
"href": "/cli/commands/state/rm"
},
{
"title": "<code>state replace-provider</code>",
"href": "/cli/commands/state/replace-provider"
}
]
},
{
"title": "Disaster Recovery",
"routes": [
{
"title": "Overview",
"path": "state/recover"
},
{
"title": "<code>state pull</code>",
"href": "/cli/commands/state/pull"
},
{
"title": "<code>state push</code>",
"href": "/cli/commands/state/push"
},
{
"title": "<code>force-unlock</code>",
"href": "/cli/commands/force-unlock"
}
]
}
]
},
{
"title": "Managing Workspaces",
"routes": [
{ "title": "Overview", "path": "workspaces" },
{
"title": "<code>workspace</code>",
"routes": [
{ "title": "Overview", "href": "/cli/commands/workspace" },
{
"title": "<code>workspace list</code>",
"href": "/cli/commands/workspace/list"
},
{
"title": "<code>workspace select</code>",
"href": "/cli/commands/workspace/select"
},
{
"title": "<code>workspace new</code>",
"href": "/cli/commands/workspace/new"
},
{
"title": "<code>workspace delete</code>",
"href": "/cli/commands/workspace/delete"
},
{
"title": "<code>workspace show</code>",
"href": "/cli/commands/workspace/show"
}
]
}
]
},
{
"title": "Managing Plugins",
"routes": [
{ "title": "Overview", "path": "plugins" },
{ "title": "Plugin Signing", "path": "plugins/signing" },
{
"title": "<code>providers</code>",
"href": "/cli/commands/providers"
},
{
"title": "<code>version</code>",
"href": "/cli/commands/version"
},
{
"title": "<code>providers lock</code>",
"href": "/cli/commands/providers/lock"
},
{
"title": "<code>providers mirror</code>",
"href": "/cli/commands/providers/mirror"
},
{
"title": "<code>providers schema</code>",
"href": "/cli/commands/providers/schema"
}
]
},
{
"title": "CLI Configuration",
"routes": [
{ "title": "Overview", "path": "config" },
{ "title": "CLI Configuration", "path": "config/config-file" },
{
"title": "Environment Variables",
"path": "config/environment-variables"
}
]
},
{
"title": "Using HCP Terraform",
"routes": [
{ "title": "Overview", "path": "cloud" },
{ "title": "Connect to HCP Terraform", "path": "cloud/settings" },
{
"title": "Command Line Arguments",
"path": "cloud/command-line-arguments"
}
]
},
{
"title": "Testing Terraform",
"routes": [
{ "title": "Overview", "path": "test" },
{ "title": "<code>test<code>", "href": "/cli/commands/test"}
]
},
{
"title": "Automating Terraform",
"routes": [
{
"title": "Running Terraform in Automation",
"href": "https://learn.hashicorp.com/tutorials/terraform/automate-terraform?in=terraform/automation&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS"
},
{
"title": "GitHub Actions",
"href": "https://learn.hashicorp.com/tutorials/terraform/github-actions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS"
}
]
},
{
"title": "Alphabetical List of Commands",
"routes": [
{ "title": "Overview", "href": "/cli/commands" },
{ "title": "<code>apply</code>", "href": "/cli/commands/apply" },
{ "title": "<code>console</code>", "href": "/cli/commands/console" },
{ "title": "<code>destroy</code>", "href": "/cli/commands/destroy" },
{ "title": "<code>fmt</code>", "href": "/cli/commands/fmt" },
{
"title": "<code>force-unlock</code>",
"href": "/cli/commands/force-unlock"
},
{ "title": "<code>get</code>", "href": "/cli/commands/get" },
{ "title": "<code>graph</code>", "href": "/cli/commands/graph" },
{ "title": "<code>import</code>", "href": "/cli/commands/import" },
{ "title": "<code>init</code>", "href": "/cli/commands/init" },
{ "title": "<code>login</code>", "href": "/cli/commands/login" },
{ "title": "<code>logout</code>", "href": "/cli/commands/logout" },
{ "title": "<code>modules</code>", "href": "/cli/commands/modules" },
{ "title": "<code>output</code>", "href": "/cli/commands/output" },
{ "title": "<code>plan</code>", "href": "/cli/commands/plan" },
{ "title": "<code>providers</code>", "href": "/cli/commands/providers" },
{
"title": "<code>providers lock</code>",
"href": "/cli/commands/providers/lock"
},
{
"title": "<code>providers mirror</code>",
"href": "/cli/commands/providers/mirror"
},
{
"title": "<code>providers schema</code>",
"href": "/cli/commands/providers/schema"
},
{ "title": "<code>refresh</code>", "href": "/cli/commands/refresh" },
{ "title": "<code>show</code>", "href": "/cli/commands/show" },
{ "title": "<code>state</code>", "href": "/cli/commands/state" },
{
"title": "<code>state list</code>",
"href": "/cli/commands/state/list"
},
{ "title": "<code>state mv</code>", "href": "/cli/commands/state/mv" },
{
"title": "<code>state pull</code>",
"href": "/cli/commands/state/pull"
},
{
"title": "<code>state push</code>",
"href": "/cli/commands/state/push"
},
{
"title": "<code>state replace-provider</code>",
"href": "/cli/commands/state/replace-provider"
},
{ "title": "<code>state rm</code>", "href": "/cli/commands/state/rm" },
{
"title": "<code>state show</code>",
"href": "/cli/commands/state/show"
},
{ "title": "<code>taint</code>", "href": "/cli/commands/taint" },
{ "title": "<code>test</code>", "href": "/cli/commands/test" },
{ "title": "<code>untaint</code>", "href": "/cli/commands/untaint" },
{ "title": "<code>validate</code>", "href": "/cli/commands/validate" },
{ "title": "<code>version</code>", "href": "/cli/commands/version" },
{ "title": "<code>workspace</code>", "href": "/cli/commands/workspace" },
{
"title": "<code>workspace list</code>",
"href": "/cli/commands/workspace/list"
},
{
"title": "<code>workspace select</code>",
"href": "/cli/commands/workspace/select"
},
{
"title": "<code>workspace new</code>",
"href": "/cli/commands/workspace/new"
},
{
"title": "<code>workspace delete</code>",
"href": "/cli/commands/workspace/delete"
},
{
"title": "<code>workspace show</code>",
"href": "/cli/commands/workspace/show"
},
{
"title": "0.12upgrade",
"href": "/cli/commands/0.12upgrade"
},
{
"title": "0.13upgrade",
"href": "/cli/commands/0.13upgrade"
}
]
},
{
"title": "Alphabetical list of commands",
"hidden": true,
"routes": [
{ "title": "Overview", "path": "commands" },
{ "title": "apply", "path": "commands/apply" },
{ "title": "console", "path": "commands/console" },
{ "title": "destroy", "path": "commands/destroy" },
{ "title": "fmt", "path": "commands/fmt" },
{ "title": "force-unlock", "path": "commands/force-unlock" },
{ "title": "get", "path": "commands/get" },
{ "title": "graph", "path": "commands/graph" },
{ "title": "import", "path": "commands/import" },
{ "title": "init", "path": "commands/init" },
{ "title": "login", "path": "commands/login" },
{ "title": "logout", "path": "commands/logout" },
{ "title": "modules", "path": "commands/modules" },
{ "title": "output", "path": "commands/output" },
{ "title": "plan", "path": "commands/plan" },
{
"title": "providers",
"routes": [
{ "title": "providers", "path": "commands/providers" },
{ "title": "providers lock", "path": "commands/providers/lock" },
{ "title": "providers mirror", "path": "commands/providers/mirror" },
{ "title": "providers schema", "path": "commands/providers/schema" }
]
},
{ "title": "refresh", "path": "commands/refresh" },
{ "title": "show", "path": "commands/show" },
{
"title": "state",
"routes": [
{ "title": "state", "path": "commands/state" },
{ "title": "state list", "path": "commands/state/list" },
{ "title": "state mv", "path": "commands/state/mv" },
{ "title": "state pull", "path": "commands/state/pull" },
{ "title": "state push", "path": "commands/state/push" },
{
"title": "state replace-provider",
"path": "commands/state/replace-provider"
},
{ "title": "state rm", "path": "commands/state/rm" },
{ "title": "state show", "path": "commands/state/show" }
]
},
{ "title": "taint", "path": "commands/taint" },
{ "title": "test", "path": "commands/test" },
{ "title": "untaint", "path": "commands/untaint" },
{ "title": "validate", "path": "commands/validate" },
{ "title": "version", "path": "commands/version" },
{
"title": "workspace",
"routes": [
{
"title": "workspace",
"path": "commands/workspace"
},
{ "title": "workspace list", "path": "commands/workspace/list" },
{ "title": "workspace select", "path": "commands/workspace/select" },
{ "title": "workspace new", "path": "commands/workspace/new" },
{ "title": "workspace delete", "path": "commands/workspace/delete" },
{ "title": "workspace show", "path": "commands/workspace/show" }
]
},
{
"title": "0.12upgrade",
"path": "commands/0.12upgrade"
},
{
"title": "0.13upgrade",
"path": "commands/0.13upgrade"
}
]
},
{ "divider": true },
{ "title": "Terraform Internals", "href": "/internals" }
]

View file

@ -1,64 +0,0 @@
[
{ "heading": "Terraform Internals" },
{
"title": "Overview",
"path": ""
},
{
"title": "Credentials Helpers",
"path": "credentials-helpers"
},
{
"title": "Debugging Terraform",
"path": "debugging"
},
{
"title": "Module Registry Protocol",
"path": "module-registry-protocol"
},
{
"title": "Provider Network Mirror Protocol",
"path": "provider-network-mirror-protocol"
},
{
"title": "Provider Registry Protocol",
"path": "provider-registry-protocol"
},
{
"title": "Dependency Graph",
"path": "graph"
},
{
"title": "Login Protocol",
"path": "login-protocol"
},
{
"title": "JSON Output Format",
"path": "json-format"
},
{
"title": "Remote Service Discovery",
"path": "remote-service-discovery"
},
{
"title": "Provider Metadata",
"path": "provider-meta"
},
{
"title": "Functions Metadata",
"path": "functions-meta"
},
{
"title": "Machine Readable UI",
"path": "machine-readable-ui"
},
{
"title": "Archiving",
"path": "archiving",
"hidden": true
},
{ "divider": true },
{ "title": "Terraform CLI", "href": "/cli" },
{ "divider": true },
{ "title": "Configuration Language", "href": "/language" }
]

View file

@ -1,34 +0,0 @@
[
{ "heading": "Introduction to Terraform" },
{ "title": "What is Terraform?", "path": "" },
{ "title": "Use Cases", "path": "use-cases" },
{
"title": "Get Started",
"href": "https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS"
},
{ "title": "Terraform Editions", "path": "terraform-editions" },
{ "title": "The Core Terraform Workflow", "path": "core-workflow" },
{
"title": "Phases of Terraform Adoption",
"routes": [
{"title": "Overview", "path": "phases"},
{"title": "Adopt", "path": "phases/adopt"},
{"title": "Collaborate", "path": "phases/collaborate"},
{"title": "Scale", "path": "phases/scale"},
{"title": "Govern", "path": "phases/govern"}
]
},
{
"title": "Terraform vs. Alternatives",
"routes": [
{ "title": "Overview", "path": "vs" },
{ "title": "Chef, Puppet, etc.", "path": "vs/chef-puppet" },
{
"title": "CloudFormation, Heat, etc.",
"path": "vs/cloudformation"
},
{ "title": "Boto, Fog, etc.", "path": "vs/boto" },
{ "title": "Custom Solutions", "path": "vs/custom" }
]
}
]

File diff suppressed because it is too large Load diff

View file

@ -1,39 +0,0 @@
---
page_title: Get an API token for HCP Terraform or Terraform Enterprise
description: >-
Use the `terraform login` and `terraform logout` commands get
an API token for your HCP Terraform or Terraform Enterprise account.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Get an API token for HCP Terraform and Terraform Enterprise
This topic describes how to use the `terraform login` and `terraform logout` to authenticate with HCP Terraform and Terraform Enterprise.
> **Hands-on:** Try the [Authenticate the CLI with HCP Terraform](/terraform/tutorials/cloud/cloud-login?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Overview
[HCP Terraform](https://cloud.hashicorp.com/products/terraform) and
[Terraform Enterprise](/terraform/enterprise) are platforms that perform
Terraform runs to provision infrastructure, offering a collaboration-focused
environment that makes it easier for teams to use Terraform together.
You can integrate the Terraform CLI with HCP Terraform and Terraform Enterprise in the following ways:
- Use the Terraform CLI as a front-end for [CLI-driven runs](/terraform/cloud-docs/run/cli) in HCP Terraform
- Use HCP Terraform or Terraform Enterprise as a state backend and a private module registry.
These integrations require you to authenticate the Terraform CLI
with your HCP Terraform account.
## Authentication
Run the `terraform login` command to generate an API token for your HCP Terraform user account. Refer to the [`terraform login` command](/terraform/cli/commands/login) reference documentation for details.
Run the `terraform logout` command to end your HCP Terraform or Terraform Enterprise session. Refer to the [`terraform logout` command](/terraform/cli/commands/logout) reference documentation for details.

View file

@ -1,30 +0,0 @@
---
page_title: -ignore-remote-version reference
description: Use the -ignore-remote-version flag to override CLI-driven commands for HCP Terraform runs.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `-ignore-remote-version` reference
When your configuration includes a `cloud` block, commands that
make local modifications to Terraform state and then push them back up to the remote workspace
accept the following option to modify that behavior:
- `-ignore-remote-version` - Override checking that the local and remote
Terraform versions agree, making an operation proceed even when there is
a mismatch.
State-modification operations usually require using a local version of the
Terraform CLI that is compatible with the Terraform version selected
in the remote workspace settings. This prevents the
local operation from creating a new state snapshot that the workspace's
remote execution environment cannot decode.
We recommend against using this option unless absolutely necessary. Overriding this check can result
in an HCP Terraform workspace that is no longer able to complete remote operations with the currently
selected version of Terraform.

View file

@ -1,31 +0,0 @@
---
page_title: Use HCP Terraform or Terraform Enterprise with the Terraform CLI
description: >-
Learn how to use HCP Terraform and Terraform Enterprise on the command line with the Terraform CLI.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Use HCP Terraform with the Terraform CLI
The Terraform CLI integration with HCP Terraform lets you use HCP Terraform and Terraform Enterprise on the command line. In the documentation HCP Terraform instructions also apply to Terraform Enterprise, except where explicitly stated.
Using HCP Terraform through the command line is called the [CLI-driven run workflow](/terraform/cloud-docs/run/cli). When you use the CLI workflow, operations like `terraform plan` or `terraform apply` are remotely executed in HCP Terraform's run environment by default, with log output streaming to the local terminal. This lets you use HCP Terraform features within the familiar Terraform CLI workflow, including variables encrypted at rest in an HCP Terraform workspace, cost estimates, and policy checking.
> **Hands On:** Try the [Migrate State to HCP Terraform](/terraform/tutorials/cloud/cloud-migrate) tutorial.
Workspaces can also be configured for local execution, in which case HCP Terraform only stores state. In this mode, HCP Terraform behaves just like a standard state backend.
-> **Note:** The CLI integration is available in Terraform 1.1.0 and later, and Terraform Enterprise 202201-1 and later. Previous versions can use the [`remote` backend](/terraform/language/backend/remote). Refer to [Migrating from the remote
backend](/terraform/cli/cloud/settings#migrate-state-data) for details about switching to the CLI integration.
## Documentation Summary
- [Connect to HCP Terraform](/terraform/cli/cloud/settings) documents the `cloud` block that you must add to your configuration to enable HCP Terraform support.
- [Command Line Arguments](/terraform/cli/cloud/command-line-arguments) lists the Terraform command flags that are specific to using Terraform with HCP Terraform.
Refer to the [CLI-driven Run Workflow](/terraform/cloud-docs/run/cli) for more details about how to use HCP Terraform from the command line.

View file

@ -1,164 +0,0 @@
---
page_title: Connect to HCP Terraform
description: >-
Learn how to configure the Terraform CLI to connect to HCP Terraform.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Connect to HCP Terraform
This topic describes how to connect the Terraform CLI to HCP Terraform. Integrating the CLI with HCP Terraform enables the CLI to act as a client for CLI-drive workflows. Refer to [CLI-driven Run Workflow](/terraform/cloud-docs/run/cli) for additional information.
> **Hands On:** Complete the [Migrate State to HCP Terraform](/terraform/tutorials/cloud/cloud-migrate) tutorial to learn more about integrating the CLI with HCP Terraform.
## Overview
Connecting the Terraform CLI to HCP Terraform links the working directory that contains your Terraform configurations to one or more HCP Terraform workspaces. This allows team members with access to the workspace to provision and manage infrastructure using HCP Terraform. Additionally, HCP Terraform manages state data so that you do not have to maintain remote state objects. Refer to the following topics for additional information:
- [State overview](/terraform/language/state) in the Terraform configuration language reference.
- [Terraform State in HCP Terraform](/terraform/cloud-docs/workspaces/state) in the HCP Terraform documentation.
Complete the following steps to connect to HCP Terraform:
1. Provide credentials to HCP Terraform.
1. Define connection settings in your Terraform configuration.
1. Initialize the working directory.
1. Migrate state data. This step is optional.
## Requirements
You must have a user profile in HCP Terraform with permissions to create a workspace. Refer to [Workspace Permissions](/terraform/cloud-docs/users-teams-organizations/permissions) in the HCP Terraform documentation for additional information.
## Provide credentials
You must provide credentials to access HCP Terraform. We recommend using the
[`terraform login`](/terraform/cli/commands/login) command to log into Terraform. You can also provide a user token in the Terraform configuration. Refer to the [`token`](/terraform/language/terraform#terraform-cloud-token) attribute in the Terraform configuration reference for additional information.
## Define connection settings
Add a `cloud` block to your Terraform configuration and configure the connection settings to link the working directory to an HCP Terraform workspace. The `cloud` block is a member of the `terraform` block. Refer to the [`terraform` block reference](/terraform/language/terraform) for additional information.
Specify the following settings in the `cloud` block:
- `organization`: Specifies the name of an HCP Terraform organization to connect to.
- `workspaces.tags`: Specifies either a map of tag strings or a list of key-only string tags (legacy style). Terraform links the working directory to existing workspaces in the organization that have matching tags. If there are no existing workspaces with matching tags, the Terraform CLI prompts you to create a new workspace that applies the tags you specify in this field when you initialize the configuration.
- `workspaces.name`: You can specify the name of an existing workspace to associate with the Terraform configuration instead of using tags. If you configure the `name`, you cannot use the `tags` configuration.
- `workspaces.project`: You can specify the name of an existing project. Terraform associates the configuration with workspaces in the project that match the `name` or `tags`.
Refer to the [`cloud` block reference](/terraform/language/terraform#terraform-cloud) for details about configuring the `cloud` block.
In the following example, the configuration links the working directory to all workspaces tagged with `networking` and `source:cli` in the `networking-development` project:
```hcl
terraform {
cloud {
organization = "my-org"
hostname = "app.terraform.io" # Optional; defaults to app.terraform.io
workspaces {
project = "networking-development"
tags = {
layer = "networking"
source = "cli"
}
}
}
}
```
## Initialize the working directory
After adding or changing a `cloud` block, run the [`terraform init` command](/terraform/cli/commands/init) to complete the set up.
By default, Terraform uploads a copy of Terraform configurations stored in the working directory when you run the `terraform plan` or `terraform apply` command, but you can add a `.terraformignore` file to the directory and specify files that you do not want to upload to HCP Terraform. Refer to [Exclude files](#exclude-files) for additional information.
If the working directory does not have an existing Terraform state file, you can immediately start using Terraform with HCP Terraform. Refer to [CLI-driven run workflow](/terraform/cloud-docs/run/cli) for additional information.
If the directory has an existing state file associated with a `backend` configuration, Terraform prompts you to migrate state from any existing workspaces. Refer to [Migrate state data](#migrate-state-data) for next steps.
## Migrate state data
Complete the data migration process when prompted according to one of the following scenarios:
State is stored in a [local or state backend](#local-and-state-backend-migration): If the working directory already has state data in one or more workspaces, Terraform prompts you to migrate the state to new HCP Terraform workspaces.
State is stored in a [remote backend](#remote-backend-migration): If the working directory is already connected to HCP Terraform with the remote backend, Terraform can continue using the same HCP Terraform workspaces. Change the `backend "remote"` configuration to a `cloud` block in this scenario.
### Migrate local state
Run the `terraform init` command and follow the CLI prompts to migrate state data stored in a local or state backend.
HCP Terraform requires all workspaces to have a name. As a result, Terraform may also prompt you to rename your workspaces during the migration.
Terraform CLI-only workspaces represent multiple environments associated with the same configuration, such as `production`, `staging`, and `development`, but HCP Terraform workspaces can represent completely independent configurations and must have unique names within the HCP Terraform organization.
As a result, Terraform prompts you to rename workspaces according to a pattern relative to their existing names. The pattern is intended to indicate that the workspaces share configuration. A common strategy is `<COMPONENT>-<ENVIRONMENT>-<REGION>`, for example `networking-prod-us-east` and `networking-staging-us-east`. Refer to [Workspace Naming](/terraform/cloud-docs/workspaces/naming) in the HCP Terraform documentation for additional information.
### Migrate remote backend
In the `terraform` block or `terraform.tf` file, replace `backend "remote"` with `cloud`. Terraform will continue to use the same ste of HCP Terraform workspaces.
The following example migrates the state data for a single workspace named `my-app-prod` to an HCP Terraform organization named `my-org`.
```hcl
terraform {
- backend "remote" {
+ cloud {
organization = "my-org"
workspaces {
name = "my-app-prod"
}
}
}
}
```
If the `terraform` block or `terraform.tf` file uses the `prefix` argument to connect to multiple workspaces, you can specify a list of key-value string tags in the `tags` argument instead of using the `name` argument. During `terraform plan` or `terraform apply` operations, Terraform associates the configuration with workspaces that match the specified tags.
The following example replaces the `my-app-` prefix with the `app=mine` tag:
```hcl
terraform {
- backend "remote" {
+ cloud {
organization = "my-org"
workspaces {
- prefix = "my-app-"
+ tags = {
+ app = "mine"
+ }
}
}
}
```
Note that because the `cloud` block does not support the `prefix` argument, after you migrate your workspaces to HCP Terraform, you must refer to them by their full name when you use the Terraform CLI. For example, instead of running the `terraform workspace select prod` command, you would run `terraform workspace select my-app-prod` instead.
## Exclude files
When executing a remote `plan` or `apply` in a [CLI-driven run](/terraform/cloud-docs/run/cli),
a copy of your configuration directory is uploaded to HCP Terraform. You can define
paths to exclude from upload by adding a `.terraformignore` file at the root of your
configuration directory. If this file is not present, Terraform still excludes the following directories by default:
- `.git/` directories
- `.terraform/` directories (exclusive of `.terraform/modules`)
The rules for defining `.terraformignore` are based on
[.gitignore files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring):
- Terraform ignores comments starting with `#`
- Terraform ignores blank lines.
- End a pattern with a forward slash `/` to specify a directory.
- Negate a pattern by starting it with an exclamation point `!`. When ignoring large directories, negation patterns can impact performance. Place negation rules as early as possible within `.terraformignore` or avoid using them if possible.
Terraform parses the `.terraformignore` at the root of the configuration directory.

View file

@ -1,53 +0,0 @@
---
page_title: Format and validate Terraform configuration using the Terraform CLI
description: Learn about the Terraform commands that validate, format, and upgrade code written in HCL.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Write and modify Terrafrom configuration from the CLI
This topic provides an overview of the Terraform CLI commands you can use to develop, format, and validate your Terraform configuration.
## Introduction
The [Terraform language](/terraform/language) is Terraform's primary
user interface, and all of Terraform's workflows rely on configurations written
in the Terraform language.
## Workflows
Terraform CLI includes several commands to make Terraform code more convenient
to work with. You can integrate the following commands into your editing
workflow to test expressions and format and validate your configuration syntax:
- The [`terraform console`](/terraform/cli/commands/console) command starts an
interactive shell for evaluating Terraform
[expressions](/terraform/language/expressions), to quickly verify that a
particular resource argument results in the value you expect.
- The [`terraform fmt`](/terraform/cli/commands/fmt) command automatically rewrites Terraform
configuration files to a canonical format and style, so you don't have to
waste time making minor adjustments for readability and consistency. The `terraform fmt` command works
well as a pre-commit hook in your version control system.
- The [`terraform validate`](/terraform/cli/commands/validate) commands validates the
syntax and arguments of the Terraform configuration files in a directory,
including argument and attribute names and types for resources and modules.
The `plan` and `apply` commands automatically validate a configuration before
performing any other work. Running `validate` isn't a crucial part of the core
workflow but can be very useful as a pre-commit hook or as part of a
continuous integration pipeline.
- The [`0.13upgrade`](/terraform/cli/commands/0.13upgrade) and
[`0.12upgrade`](/terraform/cli/commands/0.12upgrade) commands modify the configuration files in a Terraform module automatically to help deal with major
syntax changes that occurred in the 0.13 and 0.12 releases of Terraform. Both
commands are only available in the Terraform version they are
associated with. Make sure to upgrade older code to be compatible
with 0.12 before attempting to make it compatible with 0.13. For more detailed
information about updating code for new Terraform versions, refer to the [upgrade
guides](/terraform/language/upgrade-guides).

View file

@ -1,123 +0,0 @@
---
page_title: terraform 0.12upgrade command reference
description: >-
The `terraform 0.12upgrade` command automatically rewrites existing configurations for
Terraform 0.12 compatibility.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform 0.12upgrade` command
The `terraform 0.12upgrade` command applies several automatic upgrade rules to
help prepare a module that was written for Terraform v0.11 to be used
with Terraform v0.12.
-> **This command is available only in Terraform v0.12 releases.** For more information, see [the Terraform v0.12 upgrade guide](/terraform/language/v1.1.x/upgrade-guides/0-12).
## Usage
Usage: `terraform 0.12upgrade [options] [dir]`
By default, `0.12upgrade` changes configuration files in the current working
directory. However, you can provide an explicit path to another directory if
desired, which may be useful for automating migrations of several modules in
the same repository.
When run with no other options, the command will first explain what it is
going to do and prompt for confirmation:
```
$ terraform 0.12upgrade
This command will rewrite the configuration files in the given directory so
that they use the new syntax features from Terraform v0.12, and will identify
any constructs that may need to be adjusted for correct operation with
Terraform v0.12.
We recommend using this command in a clean version control work tree, so that
you can easily see the proposed changes as a diff against the latest commit.
If you have uncommitted changes already present, we recommend aborting this
command and dealing with them before running this command again.
Would you like to upgrade the module in the current directory?
Only 'yes' will be accepted to confirm.
Enter a value: yes
```
The `0.12upgrade` subcommand requires access to providers used in the
configuration in order to analyze their resource types, so it's important to
run `terraform init` first to install these. In some rare cases, a configuration
that worked in v0.11 may have syntax errors in v0.12, in which case
`terraform init` will run in a special mode where it installs only enough to
run the upgrade command, after which you can run `terraform init` again to
complete initialization.
Many of the rewrite rules are completely automatic, but in some cases the
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
user review. All such comments contain the string `TF-UPGRADE-TODO` to make
them easier to find.
After upgrading, the configuration will also be reformatted into the standard
Terraform style and expressions rewritten to use the more-readable v0.12 syntax
features.
We recommend running this command with a clean version control work tree so
that you can use VCS tools to review the proposed changes, including any
`TF-UPGRADE-TODO` comments, and make any revisions required before committing
the change.
Once upgraded the configuration will no longer be compatible with Terraform
v0.11 and earlier. When upgrading a shared module that is called from multiple
configurations, you may need to
[fix existing configurations to a previous version](/terraform/language/modules/syntax#version)
to allow for a gradual upgrade. If the module is published via
[a Terraform registry](/terraform/registry), assign a new _major_ version number
to the upgraded module source to represent the fact that this is a breaking
change for v0.11 callers. If a module is installed directly from a version
control system such as Git,
[use specific revisions](/terraform/language/modules/sources#selecting-a-revision)
to control which version is used by which caller.
The command-line options are all optional. The available options are:
* `-yes` - Skip the initial introduction messages and interactive confirmation.
Use this when running the command in batch from a script.
* `-force` - Override the heuristic that attempts to detect if a configuration
is already written for v0.12 or later. Some of the transformations made by
this command are not idempotent, so re-running against the same module may
change the meanings of some expressions in the module.
## Batch Usage
After you've experimented with the `0.12upgrade` command in some confined
situations, if you have a repository containing multiple modules you may
wish to batch-upgrade them all and review them together. Recursive upgrades
are not supported by the tool itself, but if you are on a Unix-style system
you can achieve this using the `find` command as follows:
```
find . -name '*.tf' -printf "%h\n" | uniq | xargs -n1 terraform 0.12upgrade -yes
```
On Mac OS X, the `find` included with the system does not support the `-printf` argument. You can install GNU find using Homebrew in order to use that argument:
```
brew install findutils
```
Once installed, run the above command line using `gfind` instead of `find`.
Note that the above includes the `-yes` option to override the interactive
prompt, so be sure you have a clean work tree before running it.
Because upgrading requires access to the configuration's provider plugins,
all of the directories must be initialized with `terraform init` prior to
running the above.

View file

@ -1,95 +0,0 @@
---
page_title: terraform 0.13upgrade command reference
description: >-
The `terraform 0.13upgrade` command updates existing configurations to use the new
provider source features from Terraform 0.13.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform 0.13upgrade` command
The `terraform 0.13upgrade` command updates existing configuration to add an
explicit `source` attribute for each provider used in a given module. The
provider source settings are stored in a `required_providers` block.
-> **This command is available only in Terraform v0.13 releases.** For more information, see [the Terraform v0.13 upgrade guide](/terraform/language/v1.1.x/upgrade-guides/0-13).
## Usage
Usage: `terraform 0.13upgrade [options] [dir]`
The primary purpose of the `0.13upgrade` command is to determine which
providers are in use for a module, detect the source address for those
providers where possible, and record this information in a
[`required_providers` block][required-providers].
[required-providers]: /terraform/language/providers/requirements
~> Note: the command ignores `.tf.json` files and override files in the module.
If the module already has a `required_providers` block, the command updates it
in-place. Otherwise, a new block is added to the `versions.tf` file.
By default, `0.13upgrade` changes configuration files in the current working
directory. However, you can provide an explicit path to another directory if
desired, which may be useful for automating migrations of several modules in
the same repository.
When run with no other options, the command will first explain what it is
going to do and prompt for confirmation:
```
$ terraform 0.13upgrade
This command will update the configuration files in the given directory to use
the new provider source features from Terraform v0.13. It will also highlight
any providers for which the source cannot be detected, and advise how to
proceed.
We recommend using this command in a clean version control work tree, so that
you can easily see the proposed changes as a diff against the latest commit.
If you have uncommited changes already present, we recommend aborting this
command and dealing with them before running this command again.
Would you like to upgrade the module in the current directory?
Only 'yes' will be accepted to confirm.
Enter a value: yes
```
We recommend running this command with a clean version control work tree so
that you can use VCS tools to review the proposed changes, including any
`TF-UPGRADE-TODO` comments, and make any revisions required before committing
the change.
There is one command-line option:
* `-yes` - Skip the initial introduction messages and interactive confirmation.
Use this when running the command in batch from a script.
## Batch Usage
After you've experimented with the `0.13upgrade` command in some confined
situations, if you have a repository containing multiple modules you may
wish to batch-upgrade them all and review them together. Recursive upgrades
are not supported by the tool itself, but if you are on a Unix-style system
you can achieve this using the `find` command as follows:
```
$ find . -name '*.tf' | xargs -n1 dirname | uniq | xargs -n1 terraform 0.13upgrade -yes
```
On a Windows system with PowerShell, you can use this command:
```
Get-Childitem -Recurse -Include *.tf | Split-Path | `
Select-Object -Unique | ForEach-Object { terraform 0.13upgrade -yes $_.FullName }
```
Note that the above commands include the `-yes` option to override the
interactive prompt, so be sure you have a clean work tree before running it.

View file

@ -1,125 +0,0 @@
---
page_title: terraform apply command reference
description: The `terraform apply` command executes the actions proposed in a Terraform plan
to create, update, or destroy infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform apply` command
The `terraform apply` command executes the actions proposed in a Terraform
plan.
> **Hands On:** Try the [Apply Terraform Configuration](/terraform/tutorials/cli/apply?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial to learn how Terraform applies a configuration, how Terraform recovers from errors during apply, and common ways to use this command.
## Usage
Usage: `terraform apply [options] [plan file]`
### Automatic Plan Mode
When you run `terraform apply` without passing a saved plan file, Terraform automatically creates a new execution plan as if you had run [`terraform plan`](/terraform/cli/commands/plan), prompts you to approve that plan, and takes the indicated actions. You can use all of the [planning modes](/terraform/cli/commands/plan#planning-modes) and
[planning options](/terraform/cli/commands/plan#planning-options) to customize how Terraform will create the plan.
You can pass the `-auto-approve` option to instruct Terraform to apply the plan without asking for confirmation.
!> **Warning:** If you use `-auto-approve`, we recommend making sure that no one can change your infrastructure outside of your Terraform workflow. This minimizes the risk of unpredictable changes and configuration drift.
### Saved Plan Mode
When you pass a [saved plan file](/terraform/cli/commands/plan#out-filename) to `terraform apply`, Terraform takes the actions in the saved plan without prompting you for confirmation. You may want to use this two-step workflow when [running Terraform in automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
Use [`terraform show`](/terraform/cli/commands/show) to inspect a saved plan file before applying it.
When using a saved plan, you cannot specify any additional planning modes or options. These options only affect Terraform's decisions about which
actions to take, and the plan file contains the final results of those
decisions.
### Plan Options
Without a saved plan file, `terraform apply` supports all planning modes and planning options available for `terraform plan`.
- **[Planning Modes](/terraform/cli/commands/plan#planning-modes):** These include `-destroy`, which creates a plan to destroy all remote objects, and `-refresh-only`, which creates a plan to update Terraform state and root module output values.
- **[Planning Options](/terraform/cli/commands/plan#planning-options):** These include specifying which resource instances Terraform should replace (`-replace`), setting Terraform input variables (`-var` and `-var-file`), etc.
### Apply Options
The following options change how the apply command executes and reports on the apply operation.
- `-auto-approve` - Skips interactive approval of the plan before applying. Terraform ignores this
option when you pass a previously-saved plan file. This is because
Terraform interprets the act of passing the plan file as the approval.
- `-compact-warnings` - Shows any warning messages in a compact form which
includes only the summary messages, unless the warnings are accompanied by
at least one error and thus the warning text might be useful context for
the errors.
- `-input=false` - Disables all of Terraform's interactive prompts. Note that
this also prevents Terraform from prompting for interactive approval of a
plan, so Terraform will conservatively assume that you do not wish to
apply the plan, causing the operation to fail. If you wish to run Terraform
in a non-interactive context, see
[Running Terraform in Automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) for some
different approaches.
- `-json` - Enables the [machine readable JSON UI][machine-readable-ui] output.
This implies `-input=false`, so the configuration must have no unassigned
variable values to continue. To enable this flag, you must also either enable
the `-auto-approve` flag or specify a previously-saved plan.
[machine-readable-ui]: /terraform/internals/machine-readable-ui
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
- `-no-color` - Disables terminal formatting sequences in the output. Use this
if you are running Terraform in a context where its output will be
rendered by a system that cannot interpret terminal formatting.
- `-parallelism=n` - Limit the number of concurrent operations as Terraform
[walks the graph](/terraform/internals/graph#walking-the-graph). Defaults to
10\.
- `-replace=resource` - Terraform will plan to replace this resource instance
instead of doing an update or no-op action.
- All [planning modes](/terraform/cli/commands/plan#planning-modes) and
[planning options](/terraform/cli/commands/plan#planning-options) for
`terraform plan` - Customize how Terraform will create the plan. Only available when you run `terraform apply` without a saved plan file.
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform apply` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).
## Passing a Different Configuration Directory
Terraform v0.13 and earlier also accepted a directory path in place of the
plan file argument to `terraform apply`, in which case Terraform would use
that directory as the root module instead of the current working directory.
That usage was deprecated in Terraform v0.14 and removed in Terraform v0.15.
If your workflow relies on overriding the root module directory, use
[the `-chdir` global option](/terraform/cli/commands#switching-working-directory-with-chdir)
instead, which works across all commands and makes Terraform consistently look
in the given directory for all files it would normally read or write in the
current working directory.
If your previous use of this legacy pattern was also relying on Terraform
writing the `.terraform` subdirectory into the current working directory even
though the root module directory was overridden, use
[the `TF_DATA_DIR` environment variable](/terraform/cli/config/environment-variables#tf_data_dir)
to direct Terraform to write the `.terraform` directory to a location other
than the current working directory.

View file

@ -1,151 +0,0 @@
---
page_title: terraform console command reference
description: >-
The `terraform console` command opens an interactive console for evaluating
expressions.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform console` command
The `terraform console` command opens an interactive console for
evaluating [expressions](/terraform/language/expressions).
## Usage
Usage: `terraform console [options]`
This command provides an interactive command-line console for evaluating and
experimenting with [expressions](/terraform/language/expressions).
You can use it to test interpolations before using them in configurations
and to interact with any values currently saved in
[state](/terraform/language/state). If the current state is empty or has not yet been created, you can use the console to experiment with the expression syntax and
[built-in functions](/terraform/language/functions). The console holds a [lock on the state](/terraform/language/state/locking), and you will not be able to use the console while performing other actions that modify state.
To close the console, enter the `exit` command or press Control-C
or Control-D.
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform console` accepts the legacy command line option
[`-state`](/terraform/language/backend/local#command-line-arguments).
## Scripting
The `terraform console` command can be used in non-interactive scripts
by piping newline-separated commands to it. Only the output from the
final command is printed unless an error occurs earlier.
For example:
```shell
$ echo 'split(",", "foo,bar,baz")' | terraform console
tolist([
"foo",
"bar",
"baz",
])
```
## Remote State
If [remote state](/terraform/language/state/remote) is used by the current backend,
Terraform will read the state for the current workspace from the backend
before evaluating any expressions.
## Evaluation against a Plan
By default, `terraform console` evaluates expressions against the current
Terraform state, and so the results are typically very limited for resource
instances that haven't yet been created by applying a plan.
You can use the `-plan` option to instead generate an execution plan first,
as if running `terraform plan`, and then evaluate against the _planned_ state
to describe the values Terraform expects will be correct after the plan is
applied. This typically causes a longer delay before the console prompt
appears, but in return there will be a more complete set of values available in
the expression scope.
For well-behaved configurations the planning phase should not make any
modifications to real remote objects, but it _is_ possible to write a
configuration that can take significant actions while planning. For example, a
configuration which uses the `hashicorp/external` provider's
[`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external)
is likely to run the configured external command during the plan phase, which
means it would be run by `terraform console -plan` too.
We don't recommend that you write configurations that make changes during the
plan phase. If you do write such a configuration despite that recommendation,
take care when using the console in plan mode against that configuration.
## Examples
The `terraform console` command will read the Terraform configuration in the
current working directory and the Terraform state file from the configured
backend so that interpolations can be tested against both the values in the
configuration and the state file.
With the following `main.tf`:
```hcl
variable "apps" {
type = map(any)
default = {
"foo" = {
"region" = "us-east-1",
},
"bar" = {
"region" = "eu-west-1",
},
"baz" = {
"region" = "ap-south-1",
},
}
}
resource "random_pet" "example" {
for_each = var.apps
}
```
Executing `terraform console` will drop you into an interactive shell where you
can test interpolations to:
Print a value from a map:
```
> var.apps.foo
{
"region" = "us-east-1"
}
```
Filter a map based on a specific value:
```
> { for key, value in var.apps : key => value if value.region == "us-east-1" }
{
"foo" = {
"region" = "us-east-1"
}
}
```
Check if certain values may not be known until apply:
```
> random_pet.example
(known after apply)
```
Test various functions:
```
> cidrnetmask("172.16.0.0/12")
"255.240.0.0"
```

View file

@ -1,59 +0,0 @@
---
page_title: terraform destroy command reference
description: >-
The `terraform destroy` command deprovisions all objects managed by a Terraform
configuration.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform destroy` command
The `terraform destroy` command deprovisions all objects managed by a Terraform configuration.
While you will typically not want to destroy long-lived objects in a production
environment, Terraform is sometimes used to manage ephemeral infrastructure
for development purposes, in which case you can use `terraform destroy` to
conveniently clean up all of those temporary objects once you are finished
with your work.
## Usage
Usage: `terraform destroy [options]`
This command is just a convenience alias for the following command:
```
terraform apply -destroy
```
For that reason, this command accepts most of the options that
[`terraform apply`](/terraform/cli/commands/apply) accepts, although it does
not accept a plan file argument and forces the selection of the "destroy"
planning mode.
You can also create a speculative destroy plan, to see what the effect of
destroying would be, by running the following command:
```
terraform plan -destroy
```
This will run [`terraform plan`](/terraform/cli/commands/plan) in _destroy_ mode, showing
you the proposed destroy changes without executing them.
-> **Note:** The `-destroy` option to `terraform apply` exists only in
Terraform v0.15.2 and later. For earlier versions, you _must_ use
`terraform destroy` to get the effect of `terraform apply -destroy`.
### Target a specific resource
You can use the `-target` option to destroy a particular resource and its dependencies. For example, if your Terraform configuration contained a `aws_instance` resource with the label `example`, you could destroy that resource with the following command.
```
terraform destroy -target aws_instance.example
```

View file

@ -1,68 +0,0 @@
---
page_title: terraform fmt command reference
description: >-
The `terraform fmt` command formats Terraform configuration contents so that it matches the canonical format
and style.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform fmt` command
The `terraform fmt` command formats Terraform configuration file contents so that it matches the canonical format and style. This command applies a subset of
the [Terraform language style conventions](/terraform/language/style#code-formatting),
along with other minor adjustments for readability.
## Introduction
Terraform commands that generate Terraform configuration produce
configuration files that conform to the style imposed by `terraform fmt`. Follow this style in your files to ensure consistency.
The canonical format may change in minor ways between Terraform versions, so
after upgrading Terraform we recommend to proactively run `terraform fmt`
on your modules along with any other changes you are making to adopt the new
version.
We do not consider new formatting rules in `terraform fmt` to be a breaking
change in new versions of Terraform, but we minimize changes for
configurations that already follow the style examples shown in the
Terraform documentation. New formatting rules programmed into the `terraform fmt`
command are usually expansions to include existing rules from the documentation.
We recommend following the documented style even for decisions that `terraform fmt`
does not yet apply automatically.
Formatting decisions are always subjective and so you might disagree with the
decisions that `terraform fmt` makes. This command is intentionally opinionated
and has no customization options because its primary goal is to encourage
consistency of style between different Terraform codebases, even though the
chosen style can never be everyone's favorite.
We recommend that you follow the style conventions applied by `terraform fmt`
when writing Terraform modules, but if you find the results particularly
objectionable then you may choose not to use this command, and possibly choose
to use a third-party formatting tool instead. If you choose to use a
third-party tool then you should also run it on files that are generated
automatically by Terraform, to get consistency between your hand-written files
and the generated files.
## Usage
Usage: `terraform fmt [options] [target...]`
By default, the `terraform fmt` command scans your current directory for configuration files. You can also provide a `target` argument to tell `terraform fmt` to scan:
* A directory
* A specific file
* Standard input by supplying a single dash (`-`).
The `terraform fmt` command accepts the following arguments.
| Flag | Description | Required |
| :---- | :---- | :---- |
| `-list=false` | Prevents the command from listing the files containing formatting inconsistencies. | Optional |
| `-diff` | Displays the diffs of formatting changes. | Optional |
| `-write=false` | Prevents the command from overwriting files. This behavior is implied by the `-check` flag or if the input is from `STDIN`. | Optional |
| `-check` | Checks if the input is formatted. The exit status is `0` if the command's input is properly formatted. Otherwise, the exit status is non-zero, and the command outputs a list of improperly formatted file names. | Optional |
| `-recursive` | Processes files in subdirectories in addition to the current directory. By default, the command only processes the specified, or current, directory. | Optional |

View file

@ -1,35 +0,0 @@
---
page_title: terraform force-unlock command reference
description: >-
The `terraform force-unlock` command unlocks the state for a configuration. It
does not modify your infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform force-unlock` command
This topic provides reference information about the `terraform force-unlock` command. This command manually unlocks the state for the defined configuration.
This command removes the lock on the state for the current configuration. The behavior of this lock is dependent
on the backend being used. Local state files cannot be unlocked by another
process. The `terraform force-unlock` command does not modify your infrastructure.
## Usage
Usage: `terraform force-unlock [options] LOCK_ID`
Manually unlock the state for the defined configuration.
This will not modify your infrastructure. This command removes the lock on the
state for the current configuration. The behavior of this lock is dependent
on the backend being used. Local state files cannot be unlocked by another
process.
Options:
- `-force` - Don't ask for input for unlock confirmation.

View file

@ -1,30 +0,0 @@
---
page_title: terraform get command reference
description: The `terraform get` command downloads and updates modules.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform get` command
Run the `terraform get` command to download and update
[modules](/terraform/language/modules/develop) declared in the root module.
## Usage
Usage: `terraform get [options]`
The modules are downloaded into a `.terraform` subdirectory of the current
working directory. Don't commit this directory to your version control
repository.
The `get` command supports the following option:
* `-update` - If specified, modules that are already downloaded will be
checked for updates and the updates will be downloaded if present.
* `-no-color` - Disable text coloring in the output.

View file

@ -1,60 +0,0 @@
---
page_title: terraform graph command reference
description: >-
The `terraform graph` command generates a visual representation of a
configuration or execution plan that you can use to generate charts.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform graph` command
The `terraform graph` command generates a visual representation of a configuration or execution plan that you can use to generate charts. This command uses the DOT language generate graphs. Refer to the [GraphViz documentation](https://graphviz.org/doc/info/lang.html) for additional information.
## Usage
Usage: `terraform graph [options]`
By default the result is a simplified graph which describes only the dependency
ordering of the resources (`resource` and `data` blocks) in the configuration.
The `-type=...` option optionally selects from a number of other graph types
which have more detail, at the expense of also exposing some of the
implementation details of the Terraform language runtime.
Options:
* `-plan=tfplan` - Produce a graph for applying the given plan. Implies `-type=apply`.
* `-draw-cycles` - Highlight any cycles in the graph with colored edges.
This helps when diagnosing cycle errors. This option is supported only when
selecting one of the real graph operaton types using the `-type=...`
option.
* `-type=...` - Selects a specific operation type to show the graph of, instead
of the default resources-only simplified graph.
Can be: `plan`, `plan-refresh-only`, `plan-destroy`, or `apply`.
## Generating Images
The graph output uses
[the DOT language](https://en.wikipedia.org/wiki/DOT_(graph_description_language)),
which is a machine-readable graph description language which originated in
[Graphviz](https://graphviz.org/). You can use the Graphviz `dot` command
to present the resulting graph description as an image. There are also various
third-party online graph rendering services which accept this format.
If you have the Graphviz `dot` command already installed, you can render
a PNG image by piping into that command:
```shellsession
$ terraform graph -type=plan | dot -Tpng >graph.png
```
The following is an example result:
![A visualization of the plan graph of a hypothetical Terraform configuration, produced by dot](/img/docs/graph-example.png)

View file

@ -1,169 +0,0 @@
---
page_title: terraform import command reference
description: The `terraform import` command imports existing resources into Terraform state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform import` command reference
The `terraform import` command imports existing resources into Terraform. Refer to [Import](/terraform/cli/import) for additional information.
> **Hands-on:** Try the [Import Terraform Configuration](/terraform/tutorials/state/state-import?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Usage
Usage: `terraform import [options] ADDRESS ID`
Import will find the existing resource from ID and import it into your Terraform
state at the given ADDRESS.
ADDRESS must be a valid [resource address](/terraform/cli/state/resource-addressing).
Because any resource address is valid, the import command can import resources
into modules as well as directly into the root of your state.
ID is dependent on the resource type being imported. For example, for AWS EC2
instances it is the instance ID (`i-abcd1234`) but for AWS Route53 zones
it is the zone ID (`Z12ABC4UGMOZ2N`). Please reference the provider documentation for details
on the ID format. If you're unsure, feel free to just try an ID. If the ID
is invalid, you'll just receive an error message.
~> Warning: Terraform expects that each remote object it is managing will be
bound to only one resource address, which is normally guaranteed by Terraform
itself having created all objects. If you import existing objects into Terraform,
be careful to import each remote object to only one Terraform resource address.
If you import the same object multiple times, Terraform may exhibit unwanted
behavior. For more information on this assumption, see
[the State section](/terraform/language/state).
Instead of manually importing resources, you can add the `import` block to your Terraform configurations so that Terraform imports resources when you run the `terraform apply` command. Using Terraform configurations lets you automate resource imports as part of your CI/CD pipelines. Refer to the [`import` block reference documentation](/terraform/language/import) for additional information.
The command-line flags are all optional. The following flags are available:
- `-config=path` - Path to directory of Terraform configuration files that
configure the provider for import. This defaults to your working directory.
If this directory contains no Terraform configuration files, the provider
must be configured via manual input or environmental variables.
- `-input=true` - Whether to ask for input for provider configuration.
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=0s` - Duration to retry a state lock.
- `-no-color` - If specified, output won't contain any color.
- `-parallelism=n` - Limit the number of concurrent operations as Terraform
[walks the graph](/terraform/internals/graph#walking-the-graph). Defaults
to 10.
- `-provider=provider` - **Deprecated** Override the provider configuration to
use when importing the object. By default, Terraform uses the provider specified
in the configuration for the target resource, and that is the best behavior in most cases.
- `-var 'foo=bar'` - Set a variable in the Terraform configuration. This flag
can be set multiple times. Variable values are interpreted as
[literal expressions](/terraform/language/expressions/types) in the
Terraform language, so list and map values can be specified via this flag.
- `-var-file=foo` - Set variables in the Terraform configuration from
a [variable file](/terraform/language/values/variables#variable-definitions-tfvars-files). If
`terraform.tfvars` or any `.auto.tfvars` files are present in the current
directory, they are automatically loaded. Terraform loads `terraform.tfvars`
first and the `.auto.tfvars` files after in alphabetical order. Any files
specified by `-var-file` override any values set automatically from files in
the working directory. This flag can be used multiple times. This is only
useful with the `-config` flag.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform import`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform import` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).
## Provider Configuration
Terraform will attempt to load configuration files that configure the
provider being used for import. If no configuration files are present or
no configuration for that specific provider is present, Terraform will
prompt you for access credentials. You may also specify environmental variables
to configure the provider.
The only limitation Terraform has when reading the configuration files
is that the import provider configurations must not depend on non-variable
inputs. For example, a provider configuration cannot depend on a data
source.
As a working example, if you're importing AWS resources and you have a
configuration file with the contents below, then Terraform will configure
the AWS provider with this file.
```hcl
variable "access_key" {}
variable "secret_key" {}
provider "aws" {
access_key = var.access_key
secret_key = var.secret_key
}
```
## Example: Import into Resource
This example will import an AWS instance into the `aws_instance` resource named `foo`:
```shell
$ terraform import aws_instance.foo i-abcd1234
```
## Example: Import into Module
The example below will import an AWS instance into the `aws_instance` resource named `bar` into a module named `foo`:
```shell
$ terraform import module.foo.aws_instance.bar i-abcd1234
```
## Example: Import into Resource configured with count
The example below will import an AWS instance into the first instance of the `aws_instance` resource named `baz` configured with
[`count`](/terraform/language/meta-arguments/count):
```shell
$ terraform import 'aws_instance.baz[0]' i-abcd1234
```
## Example: Import into Resource configured with for_each
The example below will import an AWS instance into the `"example"` instance of the `aws_instance` resource named `baz` configured with
[`for_each`](/terraform/language/meta-arguments/for_each):
Linux, Mac OS, and UNIX:
```shell
$ terraform import 'aws_instance.baz["example"]' i-abcd1234
```
PowerShell:
```shell
$ terraform import 'aws_instance.baz[\"example\"]' i-abcd1234
```
Windows `cmd.exe`:
```shell
$ terraform import aws_instance.baz[\"example\"] i-abcd1234
```

View file

@ -1,174 +0,0 @@
---
page_title: Terraform CLI overview
description: The Terrafrom CLI includes commands for provisioning infrastructure as code and managing the infrastructure lifecycle. Learn about Terraform CLI features.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform CLI Overview
This topic provides an overview of the Terraform command line interface.
> **Hands-on:** Try the [Terraform: Get Started](/terraform/tutorials/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials.
## Introduction
The command line interface to Terraform is the `terraform` command, which
accepts a variety of subcommands such as `terraform init` or `terraform plan`.
We refer to the `terraform` command line tool as "Terraform CLI" elsewhere
in the documentation. This terminology is often used to distinguish it from
other components you might use in the Terraform product family, such as
[HCP Terraform](/terraform/cloud-docs) or
the various [Terraform providers](/terraform/language/providers), which
are developed and released separately from Terraform CLI.
To view a list of the commands available in your current Terraform version,
run `terraform` with no additional arguments:
```text
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
All other commands:
console Try Terraform expressions at an interactive command prompt
fmt Reformat your configuration in the standard style
force-unlock Release a stuck lock on the current workspace
get Install or upgrade remote Terraform modules
graph Generate a Graphviz graph of the steps in an operation
import Associate existing infrastructure with a Terraform resource
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
metadata Metadata related commands
modules Show all declared modules in a working directory
output Show output values from your root module
providers Show the providers required for this configuration
refresh Update the state to match remote systems
show Show the current state or a saved plan
state Advanced state management
taint Mark a resource instance as not fully functional
untaint Remove the 'tainted' state from a resource instance
version Show the current Terraform version
workspace Workspace management
Global options (use these before the subcommand, if any):
-chdir=DIR Switch to a different working directory before executing the
given subcommand.
-help Show this help output or the help for a specified subcommand.
-version An alias for the "version" subcommand.
```
(The output from your current Terraform version may be different than the
above example.)
To get specific help for any specific command, use the `-help` option with the
relevant subcommand. For example, to see help about the "validate" subcommand
you can run `terraform validate -help`.
The inline help built into Terraform CLI describes the most important
characteristics of each command. For more detailed information, refer to each
command's page for details.
## Switching working directory with `-chdir`
The usual way to run Terraform is to first switch to the directory containing
the `.tf` files for your root module (for example, using the `cd` command), so
that Terraform will find those files automatically without any extra arguments.
In some cases though — particularly when wrapping Terraform in automation
scripts — it can be convenient to run Terraform from a different directory than
the root module directory. To allow that, Terraform supports a global option
`-chdir=...` which you can include before the name of the subcommand you intend
to run:
```
terraform -chdir=environments/production apply
```
The `chdir` option instructs Terraform to change its working directory to the
given directory before running the given subcommand. This means that any files
that Terraform would normally read or write in the current working directory
will be read or written in the given directory instead.
There are two exceptions where Terraform will use the original working directory
even when you specify `-chdir=...`:
* Settings in the [CLI Configuration](/terraform/cli/config/config-file) are not for a specific
subcommand and Terraform processes them before acting on the `-chdir`
option.
* In case you need to use files from the original working directory as part
of your configuration, a reference to `path.cwd` in the configuration will
produce the original working directory instead of the overridden working
directory. Use `path.root` to get the root module directory.
## Shell Tab-completion
If you use either `bash` or `zsh` as your command shell, Terraform can provide
tab-completion support for all command names and some command arguments.
To add the necessary commands to your shell profile, run the following command:
```bash
terraform -install-autocomplete
```
After installation, it is necessary to restart your shell or to re-read its
profile script before completion will be activated.
To uninstall the completion hook, assuming that it has not been modified
manually in the shell profile, run the following command:
```bash
terraform -uninstall-autocomplete
```
## Upgrade and Security Bulletin Checks
The Terraform CLI commands interact with the HashiCorp service
[Checkpoint](https://checkpoint.hashicorp.com/) to check for the availability
of new versions and critical security bulletins about the current version.
One place where the effect of this can be seen is in `terraform version`, where
it is used by default to indicate in the output when a newer version is
available.
Only anonymous information, which cannot be used to identify the user or host,
is sent to Checkpoint. An anonymous ID is sent which helps de-duplicate warning
messages. Both the anonymous id and the use of checkpoint itself are completely
optional and can be disabled.
Checkpoint itself can be entirely disabled for all HashiCorp products by
setting the environment variable `CHECKPOINT_DISABLE` to any non-empty value.
Alternatively, settings in
[the CLI configuration file](/terraform/cli/config/config-file) can be used to
disable checkpoint features. The following checkpoint-related settings are
supported in this file:
* `disable_checkpoint` - set to `true` to disable checkpoint calls
entirely. This is similar to the `CHECKPOINT_DISABLE` environment variable
described above.
* `disable_checkpoint_signature` - set to `true` to disable the use of an
anonymous signature in checkpoint requests. This allows Terraform to check
for security bulletins but does not send the anonymous signature in these
requests.
[The Checkpoint client code](https://github.com/hashicorp/go-checkpoint) used
by Terraform is available for review by any interested party.

View file

@ -1,211 +0,0 @@
---
page_title: terraform init command reference
description: >-
The `terraform init` command initializes a working directory containing
configuration files and installs plugins for required providers.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform init` command
The `terraform init` command initializes a working directory
containing Terraform configuration files. This is the first command you should
run after writing a new Terraform configuration or cloning an existing configuration
from version control. It is safe to run this command multiple times.
> **Hands-on:** Try the [Terraform: Get Started](/terraform/tutorials/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. For more in-depth details on the `init` command, check out the [Initialize Terraform Configuration tutorial](/terraform/tutorials/cli/init?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
## Usage
Usage: `terraform init [options]`
This command performs several different initialization steps in order to
prepare the current working directory for use with Terraform. More details on
these are in the sections below, but in most cases it is not necessary to worry
about these individual steps.
This command is always safe to run multiple times, to bring the working
directory up to date with changes in the configuration. Though subsequent runs
may give errors, this command will never delete your existing configuration or
state.
## General Options
The following options apply to all of (or several of) the initialization steps:
* `-input=true` Ask for input if necessary. If false, will error if
input was required.
* `-lock=false` Disable locking of state files during state-related operations.
* `-lock-timeout=<duration>` Override the time Terraform will wait to acquire
a state lock. The default is `0s` (zero seconds), which causes immediate
failure if the lock is already held by another process.
* `-no-color` Disable color codes in the command output.
* `-upgrade` Opt to upgrade modules and plugins as part of their respective
installation steps. See the sections below for more details.
## Copy a Source Module
By default, `terraform init` assumes that the working directory already
contains a configuration and will attempt to initialize that configuration.
Optionally, init can be run against an empty directory with the
`-from-module=MODULE-SOURCE` option, in which case the given module will be
copied into the target directory before any other initialization steps are
run.
This special mode of operation supports two use-cases:
* Given a version control source, it can serve as a shorthand for checking out
a configuration from version control and then initializing the working directory
for it.
* If the source refers to an _example_ configuration, it can be copied into
a local directory to be used as a basis for a new configuration.
For routine use it is recommended to check out configuration from version
control separately, using the version control system's own commands. This way
it is possible to pass extra flags to the version control system when necessary,
and to perform other preparation steps (such as configuration generation, or
activating credentials) before running `terraform init`.
## Backend Initialization
During init, the root configuration directory is consulted for
[backend configuration](/terraform/language/backend) and the chosen backend
is initialized using the given configuration settings.
Re-running init with an already-initialized backend will update the working
directory to use the new backend settings. Either `-reconfigure` or
`-migrate-state` must be supplied to update the backend configuration.
The `-migrate-state` option will attempt to copy existing state to the new
backend, and depending on what changed, may result in interactive prompts to
confirm migration of workspace states. The `-force-copy` option suppresses
these prompts and answers "yes" to the migration questions.
Enabling `-force-copy` also automatically enables the `-migrate-state` option.
The `-reconfigure` option disregards any existing configuration, preventing
migration of any existing state.
To skip backend configuration, use `-backend=false`. Note that some other init
steps require an initialized backend, so it is recommended to use this flag only
when the working directory was already previously initialized for a particular
backend.
The `-backend-config=...` option can be used for
[partial backend configuration](/terraform/language/backend#partial-configuration),
in situations where the backend settings are dynamic or sensitive and so cannot
be statically specified in the configuration file.
## Child Module Installation
During init, the configuration is searched for `module` blocks, and the source
code for referenced [modules](/terraform/language/modules/develop) is retrieved from the locations
given in their `source` arguments.
Re-running init with modules already installed will install the sources for
any modules that were added to configuration since the last init, but will not
change any already-installed modules. Use `-upgrade` to override this behavior,
updating all modules to the latest available source code.
To skip child module installation, use `-get=false`. Note that some other init
steps can complete only when the module tree is complete, so it's recommended
to use this flag only when the working directory was already previously
initialized with its child modules.
## Plugin Installation
Most Terraform providers are published separately from Terraform as plugins.
During init, Terraform searches the configuration for both direct and indirect
references to providers and attempts to install the plugins for those providers.
For providers that are published in either
[the public Terraform Registry](https://registry.terraform.io/) or in a
third-party provider registry, `terraform init` will automatically find,
download, and install the necessary provider plugins. If you cannot or do not
wish to install providers from their origin registries, you can customize how
Terraform installs providers using
[the provider installation settings in the CLI configuration](/terraform/cli/config/config-file#provider-installation).
For more information about specifying which providers are required for each
of your modules, see [Provider Requirements](/terraform/language/providers/requirements).
After successful installation, Terraform writes information about the selected
providers to [the dependency lock file](/terraform/language/files/dependency-lock).
You should commit this file to your version control system to ensure that
when you run `terraform init` again in future Terraform will select exactly
the same provider versions. Use the `-upgrade` option if you want Terraform
to ignore the dependency lock file and consider installing newer versions.
You can modify `terraform init`'s plugin behavior with the following options:
* `-upgrade` Upgrade all previously-selected plugins to the newest version
that complies with the configuration's version constraints. This will
cause Terraform to ignore any selections recorded in the dependency lock
file, and to take the newest available version matching the configured
version constraints.
* `-get-plugins=false` — Skip plugin installation.
-> Note: Since Terraform 0.13, this option has been superseded by the
[`provider_installation`](/terraform/cli/config/config-file#provider-installation) and
[`plugin_cache_dir`](/terraform/cli/config/config-file#plugin_cache_dir) settings.
It should not be used in Terraform versions 0.13+, and this option
was removed in Terraform 0.15.
* `-plugin-dir=PATH` — Force plugin installation to read plugins _only_ from
the specified directory, as if it had been configured as a `filesystem_mirror`
in the CLI configuration. If you intend to routinely use a particular
filesystem mirror then we recommend
[configuring Terraform's installation methods globally](/terraform/cli/config/config-file#provider-installation).
You can use `-plugin-dir` as a one-time override for exceptional situations,
such as if you are testing a local build of a provider plugin you are
currently developing.
* `-lockfile=MODE` Set a dependency lockfile mode.
The valid values for the lockfile mode are as follows:
* `readonly`: suppress the lockfile changes, but verify checksums against the
information already recorded. It conflicts with the `-upgrade` flag. If you
update the lockfile with third-party dependency management tools, it would be
useful to control when it changes explicitly.
## Running `terraform init` in automation
For teams that use Terraform as a key part of a change management and
deployment pipeline, it can be desirable to orchestrate Terraform runs in some
sort of automation in order to ensure consistency between runs, and provide
other interesting features such as integration with version control hooks.
There are some special concerns when running `init` in such an environment,
including optionally making plugins available locally to avoid repeated
re-installation. For more information, see
the [Running Terraform in Automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Passing a Different Configuration Directory
Terraform v0.13 and earlier also accepted a directory path in place of the
plan file argument to `terraform apply`, in which case Terraform would use
that directory as the root module instead of the current working directory.
That usage is still supported in Terraform v0.14, but is now deprecated and removed in
Terraform v0.15. If your workflow relies on overriding
the root module directory, use
[the `-chdir` global option](/terraform/cli/commands#switching-working-directory-with-chdir)
instead, which works across all commands and makes Terraform consistently look
in the given directory for all files it would normally read or write in the
current working directory.
If your previous use of this legacy pattern was also relying on Terraform
writing the `.terraform` subdirectory into the current working directory even
though the root module directory was overridden, use
[the `TF_DATA_DIR` environment variable](/terraform/cli/config/environment-variables#tf_data_dir)
to direct Terraform to write the `.terraform` directory to a location other
than the current working directory.

View file

@ -1,49 +0,0 @@
---
page_title: terraform login command reference
description: >-
The `terraform login` command obtains an API token for HCP Terraform, Terraform Enterprise, or other host that
offers Terraform services.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform login` command
The `terraform login` command obtains an API token for HCP Terraform, Terraform Enterprise, or other host that
offers Terraform services.
You can only use this command in interactive scenarios because the command launches a web browser on the same host where Terraform
is running. If you are running Terraform in an unattended automation scenario,
you can
[configure credentials manually in the CLI configuration](/terraform/cli/config/config-file#credentials).
## Usage
Usage: `terraform login [hostname]`
If you don't provide an explicit hostname, Terraform will assume you want to
log in to HCP Terraform at `app.terraform.io`.
## Credentials Storage
By default, Terraform will obtain an API token and save it in plain text in a
local CLI configuration file called `credentials.tfrc.json`. When you run
`terraform login`, it will explain specifically where it intends to save
the API token and give you a chance to cancel if the current configuration is
not as desired.
If you do not wish to store your API token in the default location, you can
optionally configure a
[credentials helper program](/terraform/cli/config/config-file#credentials-helpers) that knows
how to store and later retrieve credentials in some other system, such as
your organization's existing secrets management system.
## Login Server Support
The `terraform login` command works with any server supporting the
[login protocol](/terraform/internals/login-protocol), including HCP Terraform
and Terraform Enterprise.

View file

@ -1,39 +0,0 @@
---
page_title: terraform logout command reference
description: >-
The `terraform logout` command removes credentials stored after using the terraform
login command.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform logout` command
This topic provides reference information about the `terraform logout` command.
## Introduction
Use the `terraform logout` command to remove credentials stored after running the
`terraform login` command. These credentials are API tokens for HCP Terraform,
Terraform Enterprise, or any other host that offers Terraform services.
## Usage
Usage: `terraform logout [hostname]`
If you don't provide an explicit hostname, Terraform will assume you want to
log out of HCP Terraform at `app.terraform.io`.
-> **Note:** the API token is only removed from local storage, not destroyed on
the remote server, so it will remain valid until manually revoked.
## Credentials Storage
By default, Terraform will remove the token stored in plain text in a local CLI
configuration file called `credentials.tfrc.json`. If you have configured a
[credentials helper program](/terraform/cli/config/config-file#credentials-helpers), Terraform
will use the helper's `forget` command to remove it.

View file

@ -1,94 +0,0 @@
---
page_title: terraform modules command reference
description: >-
The `terraform modules` command prints source and version data about all declared
modules in Terraform configuration.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Command: modules
The `terraform modules` command provides a holistic view of all Terraform modules
declared in Terraform configuration for the current working directory.
This command can be useful for auditing or setting policies on module consumption.
The output of `terraform modules` includes a list of each declared module's
key, source, and version.
-> **Note**: The `terraform modules` command requires **Terraform v1.10.0 or later**.
## Usage
Usage: `terraform modules [options]`
The following optional flags are available:
- `-json` - Displays the module declarations in a machine-readable, JSON format.
The output of `terraform modules -json` includes a `format_version` key, which is set to the value of `"1.0"` in Terraform 1.10.0. The semantics of this version are:
- For minor versions, such as `"1.1"`, changes or additions will be backward-compatible.
Ignore object properties that are unrecognized to remain forward-compatible
with future minor versions.
- For major versions, such as `"2.0"`, changes will not be backward-compatible. Reject any input which reports an unsupported major version.
We will introduce new major versions only within the bounds of
[the Terraform 1.0 Compatibility Promises](/terraform/language/v1-compatibility-promises).
## Output Format
The `terraform modules` command returns a nested structure, representing module composition and hierarchy within your configuration.
The following example demonstrates what the `terraform modules` command returns without any additional flags:
```shell-session
Modules declared by configuration:
.
├── "my_private_registry_module"[app.terraform.io/hashicorp/label/null] 1.0.0 (>=1.0.0, < 2.0.1)
├── "my_public_registry_module"[terraform-aws-modules/iam/aws] 5.47.1 (>5.0.1)
└── "my_local_module_a"[./path/to/local/module_a]
└── "my_local_module_b"[./path/to/local/module_a/module_b]
└── "my_local_module_c"[./path/to/local/module/module_a/module_b/module_c]
```
The following example is a representation of the JSON output format that `terraform modules -json` returns.
```javascript
{
"format_version": "1.0",
"modules": [
{
"key": "my_private_registry_module",
"source": "app.terraform.io/hashicorp/label/null",
"version": "1.0.0"
},
{
"key": "my_public_registry_module",
"source": "terraform-aws-modules/iam/aws",
"version": "5.47.1"
},
{
"key": "my_local_module_a",
"source": "./path/to/local/module_a",
"version": ""
},
{
"key": "my_local_module_b",
"source": "./path/to/local/module_a/module_b",
"version": ""
},
{
"key": "my_local_module_c",
"source": "./path/to/local/module/module_a/module_b/module_c",
"version": ""
},
]
}
```

View file

@ -1,131 +0,0 @@
---
page_title: terraform output command reference
description: >-
The `terraform output` command extracts the value of an output variable from the state file.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform output` command
The `terraform output` command extracts the value of an output variable from the state file.
## Usage
Usage: `terraform output [options] [NAME]`
With no additional arguments, `output` will display all the outputs for
the root module. If an output `NAME` is specified, only the value of that
output is printed.
The command-line flags are all optional. The following flags are available:
* `-json` - If specified, the outputs are formatted as a JSON object, with
a key per output. If `NAME` is specified, only the output specified will be
returned. This can be piped into tools such as `jq` for further processing.
* `-raw` - If specified, Terraform will convert the specified output value to a
string and print that string directly to the output, without any special
formatting. This can be convenient when working with shell scripts, but
it only supports string, number, and boolean values. Use `-json` instead
for processing complex data types.
* `-no-color` - If specified, output won't contain any color.
* `-state=path` - Path to the state file. Defaults to "terraform.tfstate".
Ignored when [remote state](/terraform/language/state/remote) is used.
-> **Note:** When using the `-json` or `-raw` command-line flags, Terraform displays `sensitive` values in plain text. For more information,
refer to [Sensitive data in state](/terraform/language/state/sensitive-data).
## Examples
These examples assume the following Terraform output snippet.
```hcl
output "instance_ips" {
value = aws_instance.web.*.public_ip
}
output "lb_address" {
value = aws_alb.web.public_dns
}
output "password" {
sensitive = true
value = var.secret_password
}
```
To list all outputs:
```shellsession
$ terraform output
instance_ips = [
"54.43.114.12",
"52.122.13.4",
"52.4.116.53"
]
lb_address = "my-app-alb-1657023003.us-east-1.elb.amazonaws.com"
password = <sensitive>
```
Note that Terraform does not redact `sensitive` values when you specify the output by name:
```shellsession
$ terraform output password
password = notasecurepassword
```
However, Terraform completely omits any `ephemeral` values, even if you specify an output by name. Ephemeral values are never stored in state or included in Terraform plans. For more information, refer to [Sensitive data in state](/terraform/language/state/sensitive-data).
To query for the DNS address of the load balancer:
```shellsession
$ terraform output lb_address
"my-app-alb-1657023003.us-east-1.elb.amazonaws.com"
```
To query for all instance IP addresses:
```shellsession
$ terraform output instance_ips
instance_ips = [
"54.43.114.12",
"52.122.13.4",
"52.4.116.53"
]
```
## Use in automation
The `terraform output` command by default displays in a human-readable format,
which can change over time to improve clarity.
For scripting and automation, use `-json` to produce the stable JSON format.
You can parse the output using a JSON command-line parser such as
[jq](https://stedolan.github.io/jq/):
```shellsession
$ terraform output -json instance_ips | jq -r '.[0]'
54.43.114.12
```
For the common case of directly using a string value in a shell script, you
can use `-raw` instead, which will print the string directly with no extra
escaping or whitespace.
```shellsession
$ terraform output -raw lb_address
my-app-alb-1657023003.us-east-1.elb.amazonaws.com
```
The `-raw` option works only with values that Terraform can automatically
convert to strings. Use `-json` instead, possibly combined with `jq`, to
work with complex-typed values such as objects.
Terraform strings are sequences of Unicode characters rather than raw bytes,
so the `-raw` output will be UTF-8 encoded when it contains non-ASCII
characters. If you need a different character encoding, use a separate command
such as `iconv` to transcode Terraform's raw output.

View file

@ -1,373 +0,0 @@
---
page_title: terraform plan command reference
description: >-
The `terraform plan` command creates an execution plan with a preview of the
changes that Terraform will make to your infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform plan` command
The `terraform plan` command creates an execution plan, which lets you preview
the changes that Terraform plans to make to your infrastructure.
## Introduction
By default, Terraform performs the following operations when it creates a plan:
* Reads the current state of any already-existing remote objects to make sure
that the Terraform state is up-to-date.
* Compares the current configuration to the prior state and noting any
differences.
* Proposes a set of change actions that should, if applied, make the remote
objects match the configuration.
> **Hands-on:** Try the [Terraform: Get Started](/terraform/tutorials/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. For more in-depth details on the `plan` command, check out the [Create a Terraform Plan tutorial](/terraform/tutorials/cli/plan?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
The `plan` command alone does not actually carry out the proposed changes You can use this command to check whether the proposed changes match what
you expected before you apply the changes or share your changes with your
team for broader review.
If Terraform detects that no changes are needed to resource instances or to
root module output values, `terraform plan` will report that no actions need
to be taken.
If you are using Terraform directly in an interactive terminal and you expect
to apply the changes Terraform proposes, you can alternatively run
[`terraform apply`](/terraform/cli/commands/apply) directly. By default, the "apply" command
automatically generates a new plan and prompts you to approve it.
You can use the optional `-out=FILE` option to save the generated plan to a
file on disk, which you can later execute by passing the file to
[`terraform apply`](/terraform/cli/commands/apply) as an extra argument. This two-step workflow
is primarily intended for when
[running Terraform in automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
If you run `terraform plan` without the `-out=FILE` option then it will create
a _speculative plan_, which is a description of the effect of the plan but
without any intent to actually apply it.
In teams that use a version control and code review workflow for making changes
to real infrastructure, developers can use speculative plans to verify the
effect of their changes before submitting them for code review. However, it's
important to consider that other changes made to the target system in the
meantime might cause the final effect of a configuration change to be different
than what an earlier speculative plan indicated, so you should always re-check
the final non-speculative plan before applying to make sure that it still
matches your intent.
## Usage
Usage: `terraform plan [options]`
The `plan` subcommand looks in the current working directory for the root module
configuration.
Because the plan command is one of the main commands of Terraform, it has
a variety of different options, described in the following sections. However,
most of the time you should not need to set any of these options, because
a Terraform configuration should typically be designed to work with no special
additional options for routine work.
The remaining sections on this page describe the various options:
* **[Planning Modes](#planning-modes)**: There are some special alternative
planning modes that you can use for some special situations where your goal
is not just to change the remote system to match your configuration.
* **[Planning Options](#planning-options)**: Alongside the special planning
modes, there are also some options you can set in order to customize the
planning process for unusual needs.
* **[Resource Targeting](#resource-targeting)** is one particular
special planning option that has some important caveats associated
with it.
* **[Other Options](#other-options)**: These change the behavior of the planning
command itself, rather than customizing the content of the generated plan.
## Planning Modes
The previous section describes Terraform's default planning behavior, which
changes the remote system to match the changes you make to
your configuration. Terraform has two alternative planning modes, each of which creates a plan with a different intended outcome. These options are available for both `terraform plan` and [`terraform apply`](/terraform/cli/commands/apply).
* **Destroy mode:** creates a plan whose goal is to destroy all remote objects
that currently exist, leaving an empty Terraform state. It is the same as running [`terraform destroy`](/terraform/cli/commands/destroy). Destroy mode can be useful for situations like transient development environments, where the managed objects cease to be useful once the development task is complete.
Activate destroy mode using the `-destroy` command line option.
* **Refresh-only mode:** creates a plan whose goal is only to update the
Terraform state and any root module output values to match changes made to
remote objects outside of Terraform. This can be useful if you've
intentionally changed one or more remote objects outside of the usual
workflow (e.g. while responding to an incident) and you now need to reconcile
Terraform's records with those changes.
Activate refresh-only mode using the `-refresh-only` command line option.
In situations where we need to discuss the default planning mode that Terraform
uses when none of the alternative modes are selected, we refer to it as
"Normal mode". Because these alternative modes are for specialized situations
only, some other Terraform documentation only discusses the normal planning
mode.
The planning modes are all mutually-exclusive, so activating any non-default
planning mode disables the "normal" planning mode, and you can't use more than
one alternative mode at the same time.
-> **Note:** In Terraform v0.15 and earlier, the `-destroy` option is
supported only by the `terraform plan` command, and not by the
`terraform apply` command. To create and apply a plan in destroy mode in
earlier versions you must run [`terraform destroy`](/terraform/cli/commands/destroy).
-> **Note:** The `-refresh-only` option is available only in Terraform v0.15.4
and later.
> **Hands-on:** Try the [Use Refresh-Only Mode to Sync Terraform State](/terraform/tutorials/state/refresh) tutorial.
## Planning Options
In addition to alternate [planning modes](#planning-modes), there are several options that can modify planning behavior. These options are available for both `terraform plan` and [`terraform apply`](/terraform/cli/commands/apply).
- `-refresh=false` - Disables the default behavior of synchronizing the
Terraform state with remote objects before checking for configuration changes. This can make the planning operation faster by reducing the number of remote API requests. However, setting `refresh=false` causes Terraform to ignore external changes, which could result in an incomplete or incorrect plan. You cannot use `refresh=false` in refresh-only planning mode because it would effectively disable the entirety of the planning operation.
- `-replace=ADDRESS` - Instructs Terraform to plan to replace the
resource instance with the given address. This is helpful when one or more remote objects have become degraded, and you can use replacement objects with the same configuration to align with immutable infrastructure patterns. Terraform will use a "replace" action if the specified resource would normally cause an "update" action or no action at all. Include this option multiple times to replace several objects at once. You cannot use `-replace` with the `-destroy` option, and it is only available from Terraform v0.15.2 onwards. For earlier versions, use [`terraform taint`](/terraform/cli/commands/taint) to achieve a similar result.
- `-target=ADDRESS` - Instructs Terraform to focus its planning efforts only
on resource instances that match the given address and on any objects that
those instances depend on.
-> **Note:** Use `-target=ADDRESS` in exceptional circumstances only, such as recovering from mistakes or working around Terraform limitations. Refer to [Resource Targeting](#resource-targeting) for more details.
- `-var 'NAME=VALUE'` - Sets a value for a single
[input variable](/terraform/language/values/variables) declared in the
root module of the configuration. Use this option multiple times to set
more than one variable. Refer to
[Input Variables on the Command Line](#input-variables-on-the-command-line) for more information.
- `-var-file=FILENAME` - Sets values for potentially many
[input variables](/terraform/language/values/variables) declared in the
root module of the configuration, using definitions from a
["tfvars" file](/terraform/language/values/variables#variable-definitions-tfvars-files).
Use this option multiple times to include values from more than one file.
There are several other ways to set values for input variables in the root
module, aside from the `-var` and `-var-file` options. Refer to
[Assigning Values to Root Module Variables](/terraform/language/values/variables#assigning-values-to-root-module-variables) for more information.
### Input Variables on the Command Line
You can use the `-var` command line option to specify values for
[input variables](/terraform/language/values/variables) declared in your
root module.
However, to do so will require writing a command line that is parsable both
by your chosen command line shell _and_ Terraform, which can be complicated
for expressions involving lots of quotes and escape sequences. In most cases,
we recommend using the `-var-file` option instead, and writing your actual values
in a separate file so that Terraform can parse them directly, rather than
interpreting the result of your shell's parsing.
~> **Warning:** Terraform will error if you include a space before or after the equals sign (e.g., `-var "length = 2"`).
To use `-var` on a Unix-style shell on a system like Linux or macOS we
recommend writing the option argument in single quotes `'` to ensure the
shell will interpret the value literally:
```
terraform plan -var 'name=value'
```
If your intended value also includes a single quote then you'll still need to
escape that for correct interpretation by your shell, which also requires
temporarily ending the quoted sequence so that the backslash escape character
will be significant:
```
terraform plan -var 'name=va'\''lue'
```
When using Terraform on Windows, we recommend using the Windows Command Prompt
(`cmd.exe`). When you pass a variable value to Terraform from the Windows
Command Prompt, use double quotes `"` around the argument:
```
terraform plan -var "name=value"
```
If your intended value includes literal double quotes then you'll need to
escape those with a backslash:
```
terraform plan -var "name=va\"lue"
```
PowerShell on Windows cannot correctly pass literal quotes to external programs,
so we do not recommend using Terraform with PowerShell when you are on Windows.
Use Windows Command Prompt instead.
The appropriate syntax for writing the variable value is different depending
on the variable's [type constraint](/terraform/language/expressions/type-constraints).
The primitive types `string`, `number`, and `bool` all expect a direct string
value with no special punctuation except that required by your shell, as
shown in the above examples. For all other type constraints, including list,
map, and set types and the special `any` keyword, you must write a valid
Terraform language expression representing the value, and write any necessary
quoting or escape characters to ensure it will pass through your shell
literally to Terraform. For example, for a `list(string)` type constraint:
```
# Unix-style shell
terraform plan -var 'name=["a", "b", "c"]'
# Windows Command Prompt (do not use PowerShell on Windows)
terraform plan -var "name=[\"a\", \"b\", \"c\"]"
```
Similar constraints apply when setting input variables using environment
variables. For more information on the various methods for setting root module
input variables, see
[Assigning Values to Root Module Variables](/terraform/language/values/variables#assigning-values-to-root-module-variables).
### Resource Targeting
> **Hands-on:** Try the [Target resources](/terraform/tutorials/state/resource-targeting?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
You can use the `-target` option to focus Terraform's attention on only a
subset of resources.
You can use [resource address syntax](/terraform/cli/state/resource-addressing)
to specify the constraint. Terraform interprets the resource address as follows:
* If the given address identifies one specific resource instance, Terraform
will select that instance alone. For resources with either `count` or
`for_each` set, a resource instance address must include the instance index
part, like `aws_instance.example[0]`.
* If the given address identifies a resource as a whole, Terraform will select
all of the instances of that resource. For resources with either `count`
or `for_each` set, this means selecting _all_ instance indexes currently
associated with that resource. For single-instance resources (without
either `count` or `for_each`), the resource address and the resource instance
address are identical, so this possibility does not apply.
* If the given address identifies an entire module instance, Terraform will
select all instances of all resources that belong to that module instance
and all of its child module instances.
Once Terraform has selected one or more resource instances that you've directly
targeted, it will also then extend the selection to include all other objects
that those selections depend on either directly or indirectly.
This targeting capability is provided for exceptional circumstances, such
as recovering from mistakes or working around Terraform limitations. It
is _not recommended_ to use `-target` for routine operations, since this can
lead to undetected configuration drift and confusion about how the true state
of resources relates to configuration.
Instead of using `-target` as a means to operate on isolated portions of very
large configurations, prefer instead to break large configurations into
several smaller configurations that can each be independently applied.
[Data sources](/terraform/language/data-sources) can be used to access
information about resources created in other configurations, allowing
a complex system architecture to be broken down into more manageable parts
that can be updated independently.
## Other Options
The `terraform plan` command also has some other options that are related to
the input and output of the planning command, rather than customizing what
sort of plan Terraform will create. These commands are not necessarily also
available on `terraform apply`, unless otherwise stated in the documentation
for that command.
The available options are:
* `-compact-warnings` - Shows any warning messages in a compact form which
includes only the summary messages, unless the warnings are accompanied by
at least one error and thus the warning text might be useful context for
the errors.
* `-detailed-exitcode` - Returns a detailed exit code when the command exits.
When provided, this argument changes the exit codes and their meanings to
provide more granular information about what the resulting plan contains:
* 0 = Succeeded with empty diff (no changes)
* 1 = Error
* 2 = Succeeded with non-empty diff (changes present)
- `-generate-config-out=PATH` - (Experimental) If `import` blocks are present in configuration, instructs Terraform to generate HCL for any imported resources not already present. The configuration is written to a new file at PATH, which must not already exist, or Terraform will error. If the plan fails for another reason, Terraform may still attempt to write configuration.
* `-input=false` - Disables Terraform's default behavior of prompting for
input for root module input variables that have not otherwise been assigned
a value. This option is particularly useful when running Terraform in
non-interactive automation systems.
* `-json` - Enables the [machine readable JSON UI][machine-readable-ui] output.
This implies `-input=false`, so the configuration must have no unassigned
variable values to continue.
[machine-readable-ui]: /terraform/internals/machine-readable-ui
* `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
* `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
* `-no-color` - Disables terminal formatting sequences in the output. Use this
if you are running Terraform in a context where its output will be
rendered by a system that cannot interpret terminal formatting.
* `-out=FILENAME` - Writes the generated plan to the given filename in an
opaque file format that you can later pass to `terraform apply` to execute
the planned changes, and to some other Terraform commands that can work with
saved plan files.
Terraform will allow any filename for the plan file, but a typical
convention is to name it `tfplan`. **Do not** name the file with a suffix
that Terraform recognizes as another file format; if you use a `.tf` suffix
then Terraform will try to interpret the file as a configuration source
file, which will then cause syntax errors for subsequent commands.
The generated file is not in any standard format intended for consumption
by other software, but the file _does_ contain your full configuration,
all of the values associated with planned changes, and all of the plan
options including the input variables. If your plan includes any sort of
sensitive data, even if obscured in Terraform's terminal output, it will
be saved in cleartext in the plan file. You should therefore treat any
saved plan files as potentially-sensitive artifacts.
* `-parallelism=n` - Limit the number of concurrent operations as Terraform
[walks the graph](/terraform/internals/graph#walking-the-graph). Defaults
to 10.
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform plan` accepts the legacy command line option
[`-state`](/terraform/language/backend/local#command-line-arguments).
### Passing a Different Configuration Directory
Terraform v0.13 and earlier accepted an additional positional argument giving
a directory path, in which case Terraform would use that directory as the root
module instead of the current working directory.
That usage was deprecated in Terraform v0.14 and removed in Terraform v0.15.
If your workflow relies on overriding the root module directory, use
[the `-chdir` global option](/terraform/cli/commands#switching-working-directory-with-chdir)
instead, which works across all commands and makes Terraform consistently look
in the given directory for all files it would normally read or write in the
current working directory.
If your previous use of this legacy pattern was also relying on Terraform
writing the `.terraform` subdirectory into the current working directory even
though the root module directory was overridden, use
[the `TF_DATA_DIR` environment variable](/terraform/cli/config/environment-variables#tf_data_dir)
to direct Terraform to write the `.terraform` directory to a location other
than the current working directory.

View file

@ -1,25 +0,0 @@
---
page_title: 'Command: providers'
description: >-
The `terraform providers` command prints information about the providers
required in the current configuration.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Command: providers
The `terraform providers` command shows information about the
[provider requirements](/terraform/language/providers/requirements) of the
configuration in the current working directory, as an aid to understanding
where each requirement was detected from.
This command also has several subcommands with different purposes.
## Usage
Usage: `terraform providers`

View file

@ -1,182 +0,0 @@
---
page_title: terraform providers lock command reference
description: |-
The `terraform providers lock` command adds new provider selection information
to the dependency lock file without initializing the referenced providers.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform providers lock` command
The `terraform providers lock` adds new provider selection information to the dependency lock file without initializing the referenced providers.
## Introduction
When you run the command, Terraform consults upstream registries and writes provider dependency information into the
the dependency lock file. Refer to [Dependency Lock File](/terraform/language/files/dependency-lock) in the Terraform configuration language reference documentation for additional information about the lock file.
The common way to update the dependency lock file is as a side-effect of normal
provider installation during
[`terraform init`](/terraform/cli/commands/init), but there are several situations where that
automatic approach may not be sufficient:
* If you are running Terraform in an environment that uses
[alternative provider installation methods](/terraform/cli/config/config-file#provider-installation),
such as filesystem or network mirrors, normal provider installation will not
access the origin registry for a provider and therefore Terraform will not
be able to populate all of the possible package checksums for the selected
provider versions.
If you use `terraform lock` to write the official release checksums for a
provider into the dependency lock file then future `terraform init` runs
will verify the packages available in your selected mirror against the
official checksums previously recorded, giving additional certainty that
the mirror is serving the provider packages it is claiming to.
* If your team runs Terraform across a number of different platforms (e.g.
on both Windows and Linux) and the upstream registry for a provider is unable
to provide signed checksums using the latest hashing scheme, subsequent runs
of Terraform on other platforms may
[add additional checksums to the lock file](/terraform/language/files/dependency-lock#new-provider-package-checksums).
You can avoid that by pre-populating hashes for all of the platforms you
intend to use, using the `terraform providers lock` command.
## Usage
Usage: `terraform providers lock [options] [providers...]`
With no additional command line arguments, `terraform providers lock` will
analyze the configuration in the current working directory to find all of
the providers it depends on, and it will fetch the necessary data about those
providers from their origin registries and then update
[the dependency lock file](/terraform/language/files/dependency-lock) to
include a selected version for each provider and all of the package checksums
that are covered by the provider developer's cryptographic signature.
~> **Warning:** The `terraform providers lock` command prints information
about what it has fetched and whether each package was signed using a
cryptographic signature, but it cannot automatically verify that the
providers are trustworthy and that they comply with your local system
policies or relevant regulations. Review the signing key information
in the output to confirm that you trust all of the signers before committing
the updated lock file to your version control system.
If you list one or more provider source addresses on the command line then
`terraform providers lock` will restrict its work only to those providers,
leaving the lock entries for other providers (if any) unchanged.
You can customize the default behavior using the following additional option:
* `-fs-mirror=PATH` - Direct Terraform to look for provider packages in the
given local filesystem mirror directory, instead of in upstream registries.
The given directory must use the usual filesystem mirror directory layout.
* `-net-mirror=URL` - Direct Terraform to look for provider packages in the
given network mirror service, instead of in upstream registries. The
given URL must implement
[the Terraform provider network mirror protocol](/terraform/internals/provider-network-mirror-protocol).
* `-platform=OS_ARCH` - Specify a platform you intend to use to work with this
Terraform configuration. Terraform will ensure that the providers are all
available for the given platform and will save enough package checksums in
the lock file to support _at least_ the specified platforms.
Use this option multiple times to include checksums for multiple target
systems.
Target platform names consist of an operating system and a CPU
architecture. For example, `linux_amd64` selects the Linux operating system
running on an AMD64 or x86_64 CPU.
There is more detail on this option in the following section.
* `-enable-plugin-cache` - Enable the usage of the [globally configured plugin cache](/terraform/cli/config/config-file#provider-plugin-cache).
This will speed up the locking process. This is not enabled by default since
the plugin cache is not an authoritative source. As the
`terraform provider lock` command is used to ensure no untrusted provider
versions can be used installing the plugins from the cache is considered risky.
## Specifying Target Platforms
In your environment you may, for example, have both developers who work with
your Terraform configuration on their Windows or macOS workstations _and_
automated systems that apply the configuration while running on Linux.
In that situation, you could choose to verify that all of your providers support
all of those platforms, and to pre-populate the lock file with the necessary
checksums, by running `terraform providers lock` and specifying those three
platforms:
```
terraform providers lock \
-platform=windows_amd64 \ # 64-bit Windows
-platform=darwin_amd64 \ # 64-bit macOS
-platform=linux_amd64 # 64-bit Linux
```
(The above example uses Unix-style shell wrapping syntax for readability. If
you are running the command on Windows then you will need to put all of the
arguments on a single line, and remove the backslashes and comments.)
## Lock Entries for In-house Providers
An _in-house provider_ is one that isn't published on a real Terraform provider
registry because it's developed and used only within a particular organization and
distributed via either a filesystem mirror or network mirror.
By default, `terraform providers lock` assumes all providers are available
at a Terraform provider registry and tries to contact the origin registries
in order to get access to the most detailed information about the provider
packages.
To create a lock entry for a particular provider that is available only in a
local mirror, you can use either the `-fs-mirror` or `-net-mirror` command
line options to override the default behavior of consulting the provider's
origin registry:
```
terraform providers lock \
-fs-mirror=/usr/local/terraform/providers
-platform=windows_amd64 \
-platform=darwin_amd64 \
-platform=linux_amd64 \
tf.example.com/ourcompany/ourplatform
```
(The above example uses Unix-style shell wrapping syntax for readability. If
you are running the command on Windows then you will need to put all of the
arguments on a single line, and remove the backslashes.)
Because the command above includes the provider source address
`tf.example.com/ourcompany/ourplatform`, `terraform providers lock` will only
attempt to access that particular provider and will leave the lock entries
for any other providers unchanged. If you have a variety of different providers
available from different sources, you can run `terraform providers lock`
multiple times and specify a different subset of your providers each time.
The `-fs-mirror` and `-net-mirror` options have the same meaning as
`filesystem_mirror` and `network_mirror` blocks in
[the provider installation methods configuration](/terraform/cli/config/config-file#provider-installation),
but specify only a single method in order to be explicit about where you
intend to derive the package checksum information from.
Note that only an origin registry can provide official checksums covered by
the original developer's cryptographic signature. Lock entries created from
filesystem or network mirrors will therefore cover only the exact platforms
you requested, and the recorded checksums will be those reported by the
mirror, rather than the origin registry's official checksums. If you want
to ensure that the recorded checksums are the ones signed by the original
provider publisher, run this command _without_ either the `-fs-mirror` or
`-net-mirror` options to fetch all information from origin registries.
If you wish, you can publish your in-house providers via an in-house provider
registry, which will then allow locking and installation of those providers
without any special options or additional CLI configuration. For more
information, see
[the provider registry protocol](/terraform/internals/provider-registry-protocol).

View file

@ -1,73 +0,0 @@
---
page_title: terraform providers mirror command reference
description: |-
The `terraform providers mirror` command downloads the providers required
for the current configuration and copies them into a directory in the local
filesystem.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform providers mirror` command
The `terraform providers mirror` command downloads the providers required
for the current configuration and copies them into a directory in the local
filesystem.
In normal use, `terraform init` will automatically download needed providers
from provider registries as part of initializing the current working directory.
Sometimes Terraform is running in an environment where that isn't possible,
such as on an isolated network without access to the Terraform Registry. In
that case,
[explicit installation method configuration](/terraform/cli/config/config-file#explicit-installation-method-configuration)
allows you to configure Terraform, when running on a particular system, to
consult only a local filesystem directory where you've created a local mirror
of the necessary plugins, and to skip accessing the upstream registry at all.
The `terraform providers mirror` command can automatically populate a directory
that will be used as a local filesystem mirror in the provider installation
configuration.
-> `terraform providers mirror` is available only in Terraform v0.13 or later.
## Usage
Usage: `terraform providers mirror [options] <target-dir>`
A single target directory is required. Terraform will create under that
directory the path structure that is expected for filesystem-based provider
plugin mirrors, populating it with `.zip` files containing the plugins
themselves.
Terraform will also generate various `.json` index files which contain suitable
responses to implement
[the network mirror protocol](/terraform/internals/provider-network-mirror-protocol),
if you upload the resulting directory to a static website host. Terraform
ignores those index files when using the directory as a filesystem mirror,
because the directory entries themselves are authoritative in that case.
This command supports the following additional option:
* `-platform=OS_ARCH` - Choose which target platform to build a mirror for.
By default Terraform will obtain plugin packages suitable for the platform
where you run this command. Use this flag multiple times to include packages
for multiple target systems.
Target platform names consist of an operating system and a CPU
architecture. For example, `linux_amd64` selects the Linux operating system
running on an AMD64 or x86_64 CPU.
* `-lock-file=false` - Ignore the provider lock file when fetching providers.
By default the mirror command will use the version info in the lock file if the
configuration directory has been previously initialized.
You can run `terraform providers mirror` again on an existing mirror directory
to update it with new packages. For example, you can add packages for a new
target platform by re-running the command with the desired new `-platform=...`
option, and it will place the packages for that new platform without removing
packages you previously downloaded, merging the resulting set of packages
together to update the JSON index files.

View file

@ -1,219 +0,0 @@
---
page_title: terraform providers schema command
description: >-
The `terraform providers schema` command prints detailed schemas for the providers declared in the configuration.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform providers schema` command
The `terraform providers schema` command print detailed schemas for the providers used in the current configuration.
## Usage
```
$ terraform providers schema [options]
```
The following flags are available:
- `-json` - Displays the schemas in a machine-readable JSON format. The `-json` flag is required.
The output includes a `format_version` key, which has a default value of `"1.0"`. The semantics of this version are:
- Versions between `1.0` and `2.0` are backward-compatible. You should ignore any object properties with unrecognized names to
remain forward-compatible with future minor versions.
- Major versions are not backward-compatible to older versions. You should reject any input that reports an unsupported major
version.
- Refer to [Terraform 1.0 Compatibility Promises](/terraform/language/v1-compatibility-promises) for additional information about version support.
## Format Summary
The following sections describe the JSON output format by example, using a pseudo-JSON notation.
Important elements are described with comments, which are prefixed with //.
To avoid excessive repetition, we've split the complete format into several discrete sub-objects, described under separate headers. References wrapped in angle brackets (like `<block-representation>`) are placeholders which, in the real output, would be replaced by an instance of the specified sub-object.
The JSON output format consists of the following objects and sub-objects:
- [Providers Schema Representation](#providers-schema-representation) - the top-level object returned by `terraform providers schema -json`
- [Schema Representation](#schema-representation) - a sub-object of providers, resources, and data sources that describes their schema, along with function signatures
- [Block Representation](#block-representation) - a sub-object of schemas that describes attributes and nested blocks
- [Function Representation](#function-representation) - a sub-object of functions that describes parameters, the return, and additional documentation
- [Parameter Representation](#parameter-representation) - a sub-object of function signatures that describes their type and additional documentation
## Providers Schema Representation
```javascript
{
"format_version": "1.0",
// "provider_schemas" describes the provider schemas for all
// providers throughout the configuration tree.
"provider_schemas": {
// keys in this map are the provider type, such as "random"
"example_provider_name": {
// "provider" is the schema for the provider configuration
"provider": <schema-representation>,
// "resource_schemas" map the resource type name to the resource's schema
"resource_schemas": {
"example_resource_name": <schema-representation>
},
// "data_source_schemas" map the data source type name to the
// data source's schema
"data_source_schemas": {
"example_datasource_name": <schema-representation>,
},
// "ephemeral_resource_schemas" map the resource type name to the
// resource's schema
"ephemeral_resource_schemas": {
"example_resource_name": <schema-representation>,
},
// "functions" map the provider function name to the function definition
"functions": {
"example_function": <function-representation>
}
},
"example_provider_two": { … }
}
}
```
## Schema Representation
A schema representation pairs a provider or resource schema (in a "block") with that schema's version.
```javascript
{
// "version" is the schema version, not the provider version
"version": int64,
"block": <block-representation>
}
```
## Block Representation
A block representation contains "attributes" and "block_types" (which represent nested blocks).
```javascript
{
// "attributes" describes any attributes that appear directly inside the
// block. Keys in this map are the attribute names.
"attributes": {
"example_attribute_name": {
// "type" is a representation of a type specification
// that the attribute's value must conform to.
"type": "string",
// "description" is an English-language description of
// the purpose and usage of the attribute.
"description": "string",
// "required", if set to true, specifies that an
// omitted or null value is not permitted.
"required": bool,
// "optional", if set to true, specifies that an
// omitted or null value is permitted.
"optional": bool,
// "computed", if set to true, indicates that the
// value comes from the provider rather than the
// configuration.
"computed": bool,
// "sensitive", if set to true, indicates that the
// attribute may contain sensitive information.
"sensitive": bool
},
},
// "block_types" describes any nested blocks that appear directly
// inside the block.
// Keys in this map are the names of the block_type.
"block_types": {
"example_block_name": {
// "nesting_mode" describes the nesting mode for the
// child block, and can be one of the following:
// single
// list
// set
// map
"nesting_mode": "list",
"block": <block-representation>,
// "min_items" and "max_items" set lower and upper
// limits on the number of child blocks allowed for
// the list and set modes. These are
// omitted for other modes.
"min_items": 1,
"max_items": 3
}
}
}
```
## Function Representation
A function representation describes the definition of a function.
```javascript
{
// "summary" is a shortened English-language description of
// the purpose of the function in Markdown.
"summary": "string",
// "description" is a longer English-language description of
// the purpose and usage of the function in Markdown.
"description": "string",
// "deprecation_message" when present signals that the function is deprecated
// and the message contains practitioner-facing actions for the deprecation.
"deprecation_message": "string",
// "return_type" is a representation of a type specification
// that the function returns.
"return_type": "string",
// "parameters" is an optional list of the positional parameters
// that the function accepts.
"parameters": [
<parameter-representation>,
// ...
],
// "variadic_parameter" is an optional representation of the
// additional arguments that the function accepts after those
// matching with the fixed parameters.
"variadic_parameter": <parameter-representation>
}
```
## Parameter Representation
A parameter representation describes a parameter to a function.
```javascript
{
// "name" is the internal name of the parameter
"name": "string",
// "description" is an optional English-language description of
// the purpose and usage of the parameter in Markdown.
"description": "string",
// "is_nullable" is true if null is acceptable value for the argument
"is_nullable": bool,
// "type" is a representation of a type specification
// that the parameter's value must conform to.
"type": "string"
}
```

View file

@ -1,60 +0,0 @@
---
page_title: terraform refresh command reference
description: |-
The `terraform refresh` command reads the current settings from all managed
remote objects and updates the Terraform state to match.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform refresh` command
The `terraform refresh` command reads the current settings from all managed
remote objects and updates the Terraform state to match. This command is deprecated. Instead, add the `-refresh-only` flag to [`terraform apply`](/terraform/cli/commands/apply) and [`terraform plan`](/terraform/cli/commands/plan) commands.
This does not modify your real remote objects, but it modifies the
[Terraform state](/terraform/language/state).
> **Hands-on:** Try the [Use Refresh-Only Mode to Sync Terraform State](/terraform/tutorials/state/refresh) tutorial.
## Usage
Usage: `terraform refresh [options]`
This command is effectively an alias for the following command:
```
terraform apply -refresh-only -auto-approve
```
Consequently, it supports all of the same options as
[`terraform apply`](/terraform/cli/commands/apply) except that it does not accept a saved
plan file, it doesn't allow selecting a planning mode other than "refresh only",
and `-auto-approve` is always enabled.
Automatically applying the effect of a refresh is risky. If you have
misconfigured credentials for one or more providers, Terraform may
be misled into thinking that all of the managed objects have been deleted,
causing it to remove all of the tracked objects without any confirmation prompt.
Instead, we recommend using the following command in order to get the same
effect but with the opportunity to review the changes that Terraform has
detected before committing them to the state:
```
terraform apply -refresh-only
```
This alternative command will present an interactive prompt for you to confirm
the detected changes.
The `-refresh-only` option for `terraform plan` and `terraform apply` was
introduced in Terraform v0.15.4. For prior versions you must use
`terraform refresh` directly if you need this behavior, while taking into
account the warnings above. Wherever possible, avoid using `terraform refresh`
explicitly and instead rely on Terraform's behavior of automatically refreshing
existing objects as part of creating a normal plan.

View file

@ -1,56 +0,0 @@
---
page_title: terraform show command reference
description: The `terraform show` command provides human-readable output from a state or plan file.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform show` command
The `terraform show` command provides human-readable output
from a state or plan file. Use the command to inspect a plan to ensure
that the planned operations are expected, or to inspect the current state
as Terraform sees it.
-> **Note:** When using the `-json` command-line flag, any sensitive values in
Terraform state will be displayed in plain text. For more information, see
[Sensitive Data in State](/terraform/language/state/sensitive-data).
## JSON Output
Add the `-json` command-line flag to generate machine-readable output.
For Terraform state files, including when no path is provided,
`terraform show -json` shows a JSON representation of the state.
For Terraform plan files, `terraform show -json` shows a JSON representation
of the plan, configuration, and current state.
If you updated providers that contain new schema versions since the state
was written, upgrade the state before so that Terraform can display it with
`show -json`. If you are viewing a plan, it must be created without
`-refresh=false`. If you are viewing a state file, run `terraform refresh`
first.
The output format is covered in detail in [JSON Output Format](/terraform/internals/json-format).
## Usage
Usage: `terraform show [options] [file]`
You may use `show` with a path to either a Terraform state file or plan
file. If you don't specify a file path, Terraform will show the latest state
snapshot.
This command accepts the following options:
* `-no-color` - Disables output with coloring
* `-json` - Displays machine-readable output from a state or plan file
-> JSON output via the `-json` option requires **Terraform v0.12 or later**.

View file

@ -1,60 +0,0 @@
---
page_title: terraform state commands reference
description: The `terraform state` group of commands enable advanced Terraform state management.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state` commands
The `terraform state` commands enable advanced state management.
## Introduction
You can use the `terraform state` commands to modify the [Terraform state](/terraform/language/state) instead modifying the state directly.
## Usage
Usage: `terraform state <subcommand> [options] [args]`
Refer to the following subcommands for additional information:
- [`terraform state list`](/terraform/cli/commands/state/list)
- [`terraform state mv`](/terraform/cli/commands/state/mv)
- [`terraform state pull`](/terraform/cli/commands/state/pull)
- [`terraform state replace-provider`](/terraform/cli/commands/state/replace-provider)
- [`terraform state rm`](/terraform/cli/commands/state/rm)
- [`terraform state show`](/terraform/cli/commands/state/show)
## Remote State
The Terraform state subcommands all work with remote state just as if it
was local state. Reads and writes may take longer than normal as each read
and each write do a full network roundtrip. Otherwise, backups are still
written to disk and the CLI usage is the same as if it were local state.
## Backups
All `terraform state` subcommands that modify the state write backup
files. The path of these backup file can be controlled with `-backup`.
Subcommands that are read-only (such as [list](/terraform/cli/commands/state/list))
do not write any backup files since they aren't modifying the state.
Note that backups for state modification _can not be disabled_. Due to
the sensitivity of the state file, Terraform forces every state modification
command to write a backup file. You'll have to remove these files manually
if you don't want to keep them around.
## Command-Line Friendly
The output and command-line structure of the state subcommands is
designed to be usable with Unix command-line tools such as grep, awk,
and similar PowerShell commands.
For advanced filtering and modification, we recommend piping Terraform
state subcommands together with other command line tools.

View file

@ -1,94 +0,0 @@
---
page_title: terraform state list command reference
description: >-
The terraform state list command lists resources within a Terraform
state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state list` command
The `terraform state list` command lists resources within a
[Terraform state](/terraform/language/state).
## Usage
Usage: `terraform state list [options] [address...]`
The command will list all resources in the state file matching the given
addresses (if any). If no addresses are given, all resources are listed.
The resources listed are sorted according to module depth order followed
alphabetically. This means that resources that are in your immediate
configuration are listed first, and resources that are more deeply nested
within modules are listed last.
For complex infrastructures, the state can contain thousands of resources.
To filter these, provide one or more patterns to the command. Patterns are
in [resource addressing format](/terraform/cli/state/resource-addressing).
The command-line flags are all optional. The following flags are available:
* `-state=path` - Path to the state file. Defaults to "terraform.tfstate".
Ignored when [remote state](/terraform/language/state/remote) is used.
* `-id=id` - ID of resources to show. Ignored when unset.
## Example: All Resources
This example will list all resources, including modules:
```
$ terraform state list
aws_instance.foo
aws_instance.bar[0]
aws_instance.bar[1]
module.elb.aws_elb.main
```
## Example: Filtering by Resource
This example will only list resources for the given name:
```
$ terraform state list aws_instance.bar
aws_instance.bar[0]
aws_instance.bar[1]
```
## Example: Filtering with an index
This example will show you how to filter when your filter includes an index:
```
$ terraform state list 'foo[0].bar'
foo[0].bar.lorem
foo[0].bar.ipsum
```
Use single quotes to prevent your command line from interpreting the square brackets as shell syntax.
## Example: Filtering by Module
This example will list resources in the given module and any submodules:
```
$ terraform state list module.elb
module.elb.aws_elb.main
module.elb.module.secgroups.aws_security_group.sg
```
## Example: Filtering by ID
This example will only list the resource whose ID is specified on the
command line. This is useful to find where in your configuration a
specific resource is located.
```
$ terraform state list -id=sg-1234abcd
module.elb.aws_security_group.sg
```

View file

@ -1,193 +0,0 @@
---
page_title: terraform state mv command reference
description: >-
The `terraform state mv` command changes bindings in Terraform state so that existing remote objects bind to new resource instances.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state mv` command
The `terraform state mv` command changes bindings in Terraform state so that existing remote objects bind to new resource instances.
## Introduction
Terraform automatically updates the state when you apply a plan, but you can use `terraform state mv`
to retain an existing remote object but track it as a different resource
instance address in Terraform.
## Usage
Usage: `terraform state mv [options] SOURCE DESTINATION`
Terraform will look in the current state for a resource instance, resource,
or module that matches the given address, and if successful it will move the
remote objects currently associated with the source to be tracked instead
by the destination.
Both the source and destination addresses must use
[resource address syntax](/terraform/cli/state/resource-addressing), and
they must both refer to the same kind of object: you can only move a resource
instance to another resource instance, a whole module instance to another
whole module instance, etc. Furthermore, if you are moving a resource or
a resource instance then you can only move it to a new address with the
same resource type.
The most common uses for `terraform state mv` are when you have renamed a
resource block in your configuration or you've moved a resource block into
a child module, in both cases with the intention of retaining the existing
object but tracking it under a new name. By default Terraform will understand
moving or renaming a resource configuration as a request to delete the old
object and create a new object at the new address, and so `terraform state mv`
allows you to override that interpretation by pre-emptively attaching the
existing object to the new address in Terraform.
~> _Warning:_ If you are using Terraform in a collaborative environment, you
must ensure that when you are using `terraform state mv` for a code refactoring
purpose you communicate carefully with your coworkers to ensure that nobody
makes any other changes between your configuration change and your
`terraform state mv` command, because otherwise they might inadvertently create
a plan that will destroy the old object and create a new object at the new
address.
This command also accepts the following options:
- `-dry-run` - Report all of the resource instances that match the given
address without actually "forgetting" any of them.
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform state mv`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
The legacy options [`-backup` and `-backup-out`](/terraform/language/backend/local#command-line-arguments)
operate on a local state file only. Configurations using
[the `remote` backend](/terraform/language/backend/remote)
must specify a local state file with the [`-state`](/terraform/language/backend/local#command-line-arguments)
option in order to use the [`-backup` and `-backup-out`](/terraform/language/backend/local#command-line-arguments)
options.
For configurations using
[the `local` state mv](/terraform/language/backend/local) only,
`terraform state mv` also accepts the legacy options
[`-state`, `-state-out`, `-backup`, and `-backup-out`](/terraform/language/backend/local#command-line-arguments).
## Example: Rename a Resource
Renaming a resource means making a configuration change like the following:
```diff
-resource "packet_device" "worker" {
+resource "packet_device" "helper" {
# ...
}
```
To tell Terraform that it should treat the new "helper" resource as a rename
of the old "worker" resource, you can pair the above configuration change
with the following command:
```shell
terraform state mv packet_device.worker packet_device.helper
```
## Example: Move a Resource Into a Module
If you originally wrote a resource in your root module but now wish to refactor
it into a child module, you can move the `resource` block into the child
module configuration, removing the original in the root module, and then
run the following command to tell Terraform to treat it as a move:
```shell
terraform state mv packet_device.worker module.worker.packet_device.worker
```
In the above example the new resource has the same name but a different module
address. You could also change the resource name at the same time, if the new
module organization suggests a different naming scheme:
```shell
terraform state mv packet_device.worker module.worker.packet_device.main
```
## Example: Move a Module Into a Module
You can also refactor an entire module into a child module. In the
configuration, move the `module` block representing the module into a different
module and then pair that change with a command like the following:
```shell
terraform state mv module.app module.parent.module.app
```
## Example: Move a Particular Instance of a Resource using `count`
A resource defined with [the `count` meta-argument](/terraform/language/meta-arguments/count)
has multiple instances that are each identified by an integer. You can
select a particular instance by including an explicit index in your given
address:
```shell
$ terraform state mv 'packet_device.worker[0]' 'packet_device.helper[0]'
```
A resource that doesn't use `count` or `for_each` has only a single resource
instance whose address is the same as the resource itself, and so you can
move from an address not containing an index to an address containing an index,
or the opposite, as long as the address type you use matches whether and how
each resource is configured:
```shell
$ terraform state mv 'packet_device.main' 'packet_device.all[0]'
```
Brackets (`[`, `]`) have a special meaning in some shells, so you may need to
quote or escape the address in order to pass it literally to Terraform.
The above examples show the typical quoting syntax for Unix-style shells.
## Example: Move a Resource configured with for_each
A resource defined with [the `for_each` meta-argument](/terraform/language/meta-arguments/for_each)
has multiple instances that are each identified by an string. You can
select a particular instance by including an explicit key in your given
address.
However, the syntax for strings includes quotes and the quote symbol often
has special meaning in command shells, so you'll need to use the appropriate
quoting and/or escaping syntax for the shell you are using. For example:
Unix-style shells, such as on Linux or macOS:
```shell
terraform state mv 'packet_device.worker["example123"]' 'packet_device.helper["example456"]'
```
Windows Command Prompt (`cmd.exe`):
```shell
terraform state mv packet_device.worker[\"example123\"] packet_device.helper[\"example456\"]
```
PowerShell:
```shell
terraform state mv 'packet_device.worker[\"example123\"]' 'packet_device.helper[\"example456\"]'
```
Aside from the use of strings instead of integers for instance keys, the
treatment of `for_each` resources is similar to `count` resources and so
the same combinations of addresses with and without index components is
valid as described in the previous section.

View file

@ -1,33 +0,0 @@
---
page_title: terraform state pull command reference
description: >-
The `terraform state pull` command downloads and outputs state information from a remote state or local state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state pull` command
The `terraform state pull` downloads and outputs state information from a [remote state](/terraform/language/state/remote) or local state.
## Usage
Usage: `terraform state pull`
This command downloads the state from its current location, upgrades the
local copy to the latest state file version that is compatible with
locally-installed Terraform, and outputs the raw format to stdout.
This is useful for reading values out of state (potentially pairing this
command with something like [jq](https://stedolan.github.io/jq/)). It is
also useful if you need to make manual modifications to state.
You cannot use this command to inspect the Terraform version of
the remote state, as it will always be converted to the current Terraform
version before output.
-> **Note:** Terraform state files must be in UTF-8 format without a byte order mark (BOM). For PowerShell on Windows, use `Set-Content` to automatically encode files in UTF-8 format. For example, run `terraform state pull | Set-Content terraform.tfstate`.

View file

@ -1,49 +0,0 @@
---
page_title: terraform state push command reference
description: The `terraform state push` command uploads a state file to the Terraform state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state push` command
The `terraform state push` command uploads a local state file to [remote state](/terraform/language/state/remote) or a local state. We only recommend using this command when you must manually modify the remote state.
## Usage
Usage: `terraform state push [options] PATH`
This command pushes the state specified by PATH to the currently
configured [backend](/terraform/language/backend).
If PATH is "-" then the state data to push is read from stdin. This data
is loaded completely into memory and verified prior to being written to
the destination state.
-> **Note:** Terraform state files must be in UTF-8 format without a byte order mark (BOM). For PowerShell on Windows, use `Set-Content` to automatically encode files in UTF-8 format. For example, run `terraform state push | Set-Content terraform.tfstate`.
Terraform will perform a number of safety checks to prevent you from
making changes that appear to be unsafe:
- **Differing lineage**: If the "lineage" value in the state differs,
Terraform will not allow you to push the state. A differing lineage
suggests that the states are completely different and you may lose
data.
- **Higher remote serial**: If the "serial" value in the destination state
is higher than the state being pushed, Terraform will prevent the push.
A higher serial suggests that data is in the destination state that isn't
accounted for in the local state being pushed.
Both of these safety checks can be disabled with the `-force` flag.
**This is not recommended.** If you disable the safety checks and are
pushing state, the destination state will be overwritten.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform state push`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).

View file

@ -1,57 +0,0 @@
---
page_title: terraform state replace-provider command reference
description: >-
The `terraform state replace-provider` command replaces the provider for
resources in the Terraform state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state replace-provider` command
The `terraform state replace-provider` command replaces the provider
for resources in a [Terraform state](/terraform/language/state).
## Usage
Usage: `terraform state replace-provider [options] FROM_PROVIDER_FQN TO_PROVIDER_FQN`
This command will update all resources using the "from" provider, setting the
provider to the specified "to" provider. This allows changing the source of a
provider which currently has resources in state.
This command will output a backup copy of the state prior to saving any
changes. The backup cannot be disabled. Due to the destructive nature
of this command, backups are required.
This command also accepts the following options:
- `-auto-approve` - Skip interactive approval.
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=0s` - Duration to retry a state lock.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform state replace-provider`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
For configurations using
[the `local` state](/terraform/language/backend/local) only,
`terraform state replace-provider` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).
## Example
The example below replaces the `hashicorp/aws` provider with a fork by `acme`, hosted at a private registry at `registry.acme.corp`:
```shell
$ terraform state replace-provider hashicorp/aws registry.acme.corp/acme/aws
```

View file

@ -1,134 +0,0 @@
---
page_title: terraform state rm command reference
description: >-
The `terraform state rm` command removes bindings between resource instances defined in the Terraform configuration and corresponding remote objects.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state rm` command
The `terraform state rm` command removes the binding to an existing remote object without first destroying it. The remote object continues
to exist but is no longer managed by Terraform.
Instead of using the `terraform state rm` command, you can use `removed` blocks to remove resources. You can remove more than one resource at a time, and you can review removals as part of your normal plan and apply workflow. [Learn more about using `removed` blocks with resources](/terraform/language/resources/syntax#removing-resources) and [using `removed` blocks with modules](/terraform/language/modules/syntax#removing-modules).
## Usage
Usage: `terraform state rm [options] ADDRESS...`
Terraform will search the state for any instances matching the given
[resource address](/terraform/cli/state/resource-addressing), and remove
the record of each one so that Terraform will no longer be tracking the
corresponding remote objects.
This means that although the objects will still continue to exist in the
remote system, a subsequent
[`terraform plan`](/terraform/cli/commands/plan)
will include an action to create a new object for each of the "forgotten"
instances. Depending on the constraints imposed by the remote system, creating
those objects might fail if their names or other identifiers conflict with
the old objects still present.
This command also accepts the following options:
- `-dry-run` - Report all of the resource instances that match the given
address without actually "forgetting" any of them.
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform state rm`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
For configurations using
[the `local` state rm](/terraform/language/backend/local) only,
`terraform state rm` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).
## Example: Remove all Instances of a Resource
The following example will cause Terraform to "forget" all of the instances
of the `packet_device` resource named "worker".
```shell
$ terraform state rm 'packet_device.worker'
```
A resource that doesn't use `count` or `for_each` has only one instance, so
this is also the appropriate syntax to select that single instance.
## Example: Remove all Instances of a Resource in a Module
To select a resource that you've defined in a child module you must specify
the path of that module as part of the resource address:
```shell
$ terraform state rm 'module.foo.packet_device.worker'
```
## Example: Remove all Instances of all Resources in a Module
The following example will cause Terraform to "forget" all of the instances
associated with all resources defined in all instances of the module named
`foo`:
```shell
$ terraform state rm 'module.foo'
```
## Example: Remove a Particular Instance of a Resource using `count`
A resource defined with [the `count` meta-argument](/terraform/language/meta-arguments/count)
has multiple instances that are each identified by an integer. You can
select a particular instance by including an explicit index in your given
address:
```shell
$ terraform state rm 'packet_device.worker[0]'
```
Brackets (`[`, `]`) have a special meaning in some shells, so you may need to
quote or escape the address in order to pass it literally to Terraform.
The above shows the typical quoting syntax for Unix-style shells.
## Example: Remove a Particular Instance of a Resource using `for_each`
A resource defined with [the `for_each` meta-argument](/terraform/language/meta-arguments/for_each)
has multiple instances that are each identified by an string. You can
select a particular instance by including an explicit key in your given
address.
However, the syntax for strings includes quotes and the quote symbol often
has special meaning in command shells, so you'll need to use the appropriate
quoting and/or escaping syntax for the shell you are using. For example:
Unix-style shells, such as on Linux or macOS:
```shell
$ terraform state rm 'packet_device.worker["example"]'
```
Windows Command Prompt (`cmd.exe`):
```shell
$ terraform state rm packet_device.worker[\"example\"]
```
PowerShell:
```shell
$ terraform state rm 'packet_device.worker[\"example\"]'
```

View file

@ -1,95 +0,0 @@
---
page_title: terraform state show command reference
description: >-
The `terraform state show` command shows the attributes of a single
resource in the Terraform state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform state show` command
The `terraform state show` command shows the attributes of a
single resource in the
[Terraform state](/terraform/language/state).
## Usage
Usage: `terraform state show [options] ADDRESS`
The command will show the attributes of a single resource in the
state file that matches the given address.
This command requires an address that points to a single resource in the
state. Addresses are
in [resource addressing format](/terraform/cli/state/resource-addressing).
The command-line flags are all optional. The following flags are available:
* `-state=path` - Path to the state file. Defaults to "terraform.tfstate".
Ignored when [remote state](/terraform/language/state/remote) is used.
The output of `terraform state show` is intended for human consumption, not
programmatic consumption. To extract state data for use in other software, use
[`terraform show -json`](/terraform/cli/commands/show#json-output) and decode the result
using the documented structure.
## Example: Show a Resource
The example below shows a `packet_device` resource named `worker`:
```
$ terraform state show 'packet_device.worker'
# packet_device.worker:
resource "packet_device" "worker" {
billing_cycle = "hourly"
created = "2015-12-17T00:06:56Z"
facility = "ewr1"
hostname = "prod-xyz01"
id = "6015bg2b-b8c4-4925-aad2-f0671d5d3b13"
locked = false
}
```
## Example: Show a Module Resource
The example below shows a `packet_device` resource named `worker` inside a module named `foo`:
```shell
$ terraform state show 'module.foo.packet_device.worker'
```
## Example: Show a Resource configured with count
The example below shows the first instance of a `packet_device` resource named `worker` configured with
[`count`](/terraform/language/meta-arguments/count):
```shell
$ terraform state show 'packet_device.worker[0]'
```
## Example: Show a Resource configured with for_each
The following example shows the `"example"` instance of a `packet_device` resource named `worker` configured with the [`for_each`](/terraform/language/meta-arguments/for_each) meta-argument. You must place the resource name in single quotes when it contains special characters like double quotes.
Linux, Mac OS, and UNIX:
```shell
$ terraform state show 'packet_device.worker["example"]'
```
PowerShell:
```shell
$ terraform state show 'packet_device.worker[\"example\"]'
```
Windows `cmd.exe`:
```shell
$ terraform state show packet_device.worker[\"example\"]
```

View file

@ -1,67 +0,0 @@
---
page_title: terraform taint command reference
description: |-
The `terraform taint` command marks specified objects in the Terraform state as tainted.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform taint` command
The `terraform taint` command marks specified objects in the Terraform state as tainted. Use the `terraform taint` command when objects become degraded or damaged. Terraform prompts you to replace the tainted objects in the next plan you create.
This command is deprecated. Instead, add the `-replace` option to your [`terraform apply` command](/terraform/cli/commands/apply).
## Recommended Alternative
For Terraform v0.15.2 and later, we recommend using the [`-replace` option](/terraform/cli/commands/plan#replace-address) with `terraform apply` to force Terraform to replace an object even though there are no configuration changes that would require it.
```
$ terraform apply -replace="aws_instance.example[0]"
```
We recommend the `-replace` option because the change will be reflected in the Terraform plan, letting you understand how it will affect your infrastructure before you take any externally-visible action. When you use `terraform taint`, other users could create a new plan against your tainted object before you can review the effects.
## Usage
```
$ terraform taint [options] <address>
```
The `address` argument is the address of the resource to mark as tainted.
The address is in
[the resource address syntax](/terraform/cli/state/resource-addressing),
as shown in the output from other commands, such as:
- `aws_instance.foo`
- `aws_instance.bar[1]`
- `aws_instance.baz[\"key\"]` (quotes in resource addresses must be escaped on the command line, so that they will not be interpreted by your shell)
- `module.foo.module.bar.aws_instance.qux`
This command accepts the following options:
- `-allow-missing` - If specified, the command will succeed (exit code 0)
even if the resource is missing. The command might still return an error
for other situations, such as if there is a problem reading or writing
the state.
- `-lock=false` - Disables Terraform's default behavior of attempting to take
a read/write lock on the state for the duration of the operation.
- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote) only, `terraform taint`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform taint` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).

View file

@ -1,235 +0,0 @@
---
page_title: terraform test command reference
description: >-
The `terraform test` command loads and executes Terraform testing files.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform test` command
The `terraform test` command loads and exectures Terraform testing files.
## Introduction
The `terraform test` command and the test file syntax help module authors validate and test their shared modules. You can also use the `terraform test` command to validate root modules.
## Usage
Usage: `terraform test [options]`
This command searches the current directory and the specified testing directory for Terraform testing files and executes the specified tests. By default, the directory containing test files is named `tests`. Refer to [Tests](/terraform/language/tests) for more details on test files.
Terraform then executes a series of Terraform plan or apply commands according to the test files' specifications, and also validates the relevant plan and state files according to the test files' specifications.
!> **Warning:** The Terraform test command can create real infrastructure than can cost you money. Refer to the [Terraform Test Cleanup](#terraform-test-cleanup) section for best practices on ensuring created infrastructure is destroyed.
## General Options
The following options apply to the Terraform `terraform test` command:
* `-cloud-run=<module source>` - This test run executes remotely on HCP Terraform within the specified Terraform [private registry](/terraform/language/modules/sources#terraform-registry) module.
* `-filter=testfile` - Limits the `terraform test` operation to the specified test files.
* `-json` - Displays machine-readable JSON output for your testing results.
* `-junit-xml=<output file path>` - Saves a test report in JUnit XML format to the specified file. This is currently incompatible with remote test execution using the the `-cloud-run` option. The file path must be relative or absolute.
* `-test-directory=<relative directory>` - Overrides the directory that Terraform looks into for test files. Note that Terraform always loads testing files within the main configuration directory. The default testing directory is `tests`.
* `-verbose` - Prints out the plan or state for each `run` block within a test file, based on the `command` attribute of each `run` block.
* `-parallelism=<n>` - Specifies the number of plan/apply operations to execute in parallel within a single test run. The default is 10.
## State Management
Each Terraform test file will maintain all Terraform state it requires within memory as it executes, starting empty. This state is entirely separate from any existing state for the configuration under test, so you can safely execute Terraform test commands without affecting any live infrastructure.
### Terraform Test Cleanup
The Terraform `terraform test` command creates _real_ infrastructure. Once Terraform fully executes each test file, Terraform attempts to destroy any remaining infrastructure. If it cannot do this, Terraform reports a list of resources it created but could not destroy.
You should monitor the output of the test command closely to ensure Terraform removes the infrastructure it created or perform manual cleanup if not. We recommend creating dedicated testing accounts within the target providers that you can routinely and safely purge to ensure any accidental and costly resources aren't left behind.
Terraform also provides diagnostics explaining why it could not automatically clean up. You should review these diagnostics to ensure that future clean-up operations are successful.
## HCP Terraform execution
You can execute tests remotely on HCP Terraform using the `-cloud-run` option.
The `-cloud-run` option accepts a [private registry module source](/terraform/language/modules/sources#terraform-registry). This option associates the test run with your specified private module within the HCP Terraform user interface.
You must provide a module from a _private_ registry, not the public Terraform registry.
You must execute [`terraform login`](/terraform/cli/commands/login) before using this option, and ensure that your `hostname` argument matches the private registry hostname of your target module.
## Example: Test Directory Structure and Commands
The following directory structure represents an example directory tree for a Terraform module with tests and a setup module.
```
project/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
|-- tests/
| |-- validations.tftest.hcl
| |-- outputs.tftest.hcl
|-- testing/
|-- setup/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
```
At the root directory of the project, there are some typical Terraform configuration files: `main.tf`, `outputs.tf`, `terraform.tf`, and `variables.tf`. The test files, `validations.tftest.hcl` and `outputs.tftest.hcl`, are within the default tests directory: `tests`.
In addition, a [setup module](/terraform/language/tests#modules) for the tests exists within the `testing` directory.
In order to execute the tests you should run `terraform test` from the root configuration directory as if running `terraform plan` or `terraform apply`. Despite the actual test files being in the nested `tests` directory, Terraform executes from the main configuration directory.
Specific test files can be executed using the `-filter` option.
Linux, Mac OS, and UNIX:
```shell
terraform test -filter=tests/validations.tftest.hcl
```
PowerShell:
```shell
terraform test -filter='tests\validations.tftest.hcl'
```
Windows `cmd.exe`:
```shell
terraform test -filter=tests\validations.tftest.hcl
```
### Alternate Test Directories
In the above example the tests are in the default testing directory of `tests`. Test files can also be included directly within the main configuration directory:
```
project/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
|-- validations.tftest.hcl
|-- outputs.tftest.hcl
|-- testing/
|-- setup/
|-- main.tf
|-- outputs.tf
|-- terraform.tf
|-- variables.tf
```
The location of the testing files does not affect the operation of `terraform test`. All references to, and absolute file paths within, the testing files should be relative to the main configuration directory.
You can also use the `-test-directory` argument to change the location of the testing files. For example, `terraform test -test-directory=testing` would instruct Terraform to load tests from the directory `testing` instead of `tests`.
The testing directory must be beneath the main configuration directory, but it can be nested many times.
> Note: Test files within the root configuration directory are always loaded, regardless of the `-test-directory` value.
We do not recommend changing the default test directory. The option for customization is included for configuration authors who may have included a `tests` submodule in their configuration before the `terraform test` command was released. In general, the default test directory of `tests` should always be used.
## Example: Test Output Format Options
Below is a contrived example of Terraform testing that makes assertions about the values of local variables `true` and `false`.
There are two test files: one contains a passing test, and one contains a failing test.
```hcl
# main.tf
locals {
true = "true"
false = "true" # incorrect, should be "false"!
}
```
The assertion that `local.true == "true"` in `example_1.tftest.hcl` will pass:
```hcl
# example_1.tftest.hcl
run "true_is_true" {
assert {
condition = local.true == "true"
error_message = "local.true did not match expected value"
}
}
```
The assertion that `local.false == "false"` in `example_2.tftest.hcl` will fail:
```hcl
# example_2.tftest.hcl
run "false_is_false" {
assert {
condition = local.false == "false"
error_message = "local.false did not match expected value"
}
}
```
### Test output in JUnit XML format, saved to file
Below is the output of the `terraform test -junit-xml=./output.xml` command using the example files above.
The test output is:
* Printed to the terminal in the default, human-readable format.
* Also saved in JUnit XML format in the file specified by the flag.
Below is the contents of the resulting `output.xml` file:
```xml
<?xml version="1.0" encoding="UTF-8"?><testsuites>
<testsuite name="example_1.tftest.hcl" tests="1" skipped="0" failures="0" errors="0">
<testcase name="true_is_true" classname="example_1.tftest.hcl" time="0.002295" timestamp="2025-01-13T19:23:16Z"></testcase>
</testsuite>
<testsuite name="example_2.tftest.hcl" tests="1" skipped="0" failures="1" errors="0">
<testcase name="false_is_false" classname="example_2.tftest.hcl" time="0.001468" timestamp="2025-01-13T19:23:16Z">
<failure message="local.false did not match expected value"><![CDATA[
Error: Test assertion failed
on example_2.tftest.hcl line 3, in run "false_is_false":
3: condition = local.false == "false"
├────────────────
│ local.false is "true"
local.false did not match expected value
]]></failure>
</testcase>
</testsuite>
</testsuites>
```
If a run block contains a failing assertion, the `<testcase>` element will contain a `<failure>` element that includes the error message and further details.
A `<testcase>` element could contain a `<skipped>` element that includes details about why a test was skipped. This could either be due to an error causing remaining run blocks to be skipped, or due to the command being interrupted.
#### Mapping Terraform test command concepts to JUnit XML format
The test report generated when using `-junit-xml` maps Terraform test command concepts to JUnit XML format according to the table below:
| Terraform test concept | Element in JUnit XML output |
| ----------------------------------| --------------------------------------------|
| Test directory | `<testsuites>` |
| Test file | `<testsuite>` |
| Run block | `<testcase>` |
| Run block assertion | None; details are included only on failure |
| Test failure | `<failure>` |
| Test was skipped | `<skipped>` |
| Test stopped due to error | `<error>` |
| Any unhandled warnings or errors | `<system-err>` |

View file

@ -1,80 +0,0 @@
---
page_title: terraform untaint command reference
description: |-
The `terraform untaint` command removes the `tainted` status from infrastructure objects tracked in the Terraform state data.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform untaint` command
This topic provides reference information about the `terraform untaint` command.
## Introduction
Terraform has a marker called `tainted` which it uses to track that an object
might be damaged and so a future Terraform plan ought to replace it.
Terraform automatically marks an object as "tainted" if an error occurs during
a multi-step "create" action, because Terraform can't be sure that the object
was left in a fully-functional state.
You can also manually mark an object as "tainted" using the deprecated command
[`terraform taint`](/terraform/cli/commands/taint), although we no longer recommend that
workflow.
If Terraform currently considers a particular object as tainted but you've
determined that it's actually functioning correctly and need _not_ be replaced,
you can use `terraform untaint` to remove the taint marker from that object.
This command _will not_ modify any real remote objects, but will modify the
state in order to remove the tainted status.
If you remove the taint marker from an object but then later discover that it
was degraded after all, you can create and apply a plan to replace it without
first re-tainting the object, by using a command like the following:
```
terraform apply -replace="aws_instance.example[0]"
```
## Usage
Usage: `terraform untaint [options] address`
The `address` argument is a [resource address](/terraform/cli/state/resource-addressing)
identifying a particular resource instance which is currently tainted.
This command also accepts the following options:
- `-allow-missing` - If specified, the command will succeed (exit code 0)
even if the resource is missing. The command might still return an error
for other situations, such as if there is a problem reading or writing
the state.
- `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
- `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
instructs Terraform to retry acquiring a lock for a period of time before
returning an error. The duration syntax is a number followed by a time
unit letter, such as "3s" for three seconds.
- `-no-color` - Disables terminal formatting sequences in the output. Use this
if you are running Terraform in a context where its output will be
rendered by a system that cannot interpret terminal formatting.
For configurations using the [HCP Terraform CLI integration](/terraform/cli/cloud) or the [`remote` backend](/terraform/language/backend/remote)
only, `terraform untaint`
also accepts the option
[`-ignore-remote-version`](/terraform/cli/cloud/command-line-arguments#ignore-remote-version).
For configurations using
[the `local` backend](/terraform/language/backend/local) only,
`terraform untaint` also accepts the legacy options
[`-state`, `-state-out`, and `-backup`](/terraform/language/backend/local#command-line-arguments).

View file

@ -1,219 +0,0 @@
---
page_title: terraform validate command reference
description: >-
The `terraform validate` command validates the syntax of Terraform configuration files in a directory.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform validate` command
The `terraform validate` command validates the configuration files in a
directory. It does not validate remote services, such as remote state or provider APIs.
## Introduction
Validate runs checks that verify whether a configuration is syntactically
valid and internally consistent, regardless of any provided variables or
existing state. It is thus primarily useful for general verification of
reusable modules, including correctness of attribute names and value types.
It is safe to run this command automatically, for example as a post-save
check in a text editor or as a test step for a reusable module in a CI
system.
Validation requires an initialized working directory with any referenced plugins and modules installed. To initialize a working directory for validation without accessing any configured backend, use:
```
$ terraform init -backend=false
```
To verify the configuration in the context of a particular run (a particular
target workspace, input variable values, etc), use the `terraform plan`
command instead, which includes an implied validation check.
## Usage
Usage: `terraform validate [options]`
This command accepts the following options:
* `-json` - Produce output in a machine-readable JSON format, suitable for
use in text editor integrations and other automated systems. Always disables
color.
* `-no-color` - If specified, output won't contain any color.
## JSON Output Format
When you use the `-json` option, Terraform will produce validation results
in JSON format to allow using the validation result for tool integrations, such
as highlighting errors in a text editor.
As with all JSON output options, it's possible that Terraform will encounter
an error prior to beginning the validation task that will thus not be subject
to the JSON output setting. For that reason, external software consuming
Terraform's output should be prepared to find data on stdout that _isn't_ valid
JSON, which it should then treat as a generic error case.
The output includes a `format_version` key, which as of Terraform 1.1.0 has
value `"1.0"`. The semantics of this version are:
* We will increment the minor version, e.g. `"1.1"`, for backward-compatible
changes or additions. Ignore any object properties with unrecognized names to
remain forward-compatible with future minor versions.
* We will increment the major version, e.g. `"2.0"`, for changes that are not
backward-compatible. Reject any input which reports an unsupported major
version.
We will introduce new major versions only within the bounds of
[the Terraform 1.0 Compatibility Promises](/terraform/language/v1-compatibility-promises).
In the normal case, Terraform will print a JSON object to the standard output
stream. The top-level JSON object will have the following properties:
- `valid` (boolean): Summarizes the overall validation result, by indicating
`true` if Terraform considers the current configuration to be valid or
`false` if it detected any errors.
- `error_count` (number): A zero or positive whole number giving the count
of errors Terraform detected. If `valid` is `true` then `error_count` will
always be zero, because it is the presence of errors that indicates that
a configuration is invalid.
- `warning_count` (number): A zero or positive whole number giving the count
of warnings Terraform detected. Warnings do not cause Terraform to consider
a configuration to be invalid, but they do indicate potential caveats that
a user should consider and possibly resolve.
- `diagnostics` (array of objects): A JSON array of nested objects that each
describe an error or warning from Terraform.
The nested objects in `diagnostics` have the following properties:
- `severity` (string): A string keyword, either `"error"` or
`"warning"`, indicating the diagnostic severity.
The presence of errors causes Terraform to consider a configuration to be
invalid, while warnings are just advice or caveats to the user which do not
block working with the configuration. Later versions of Terraform may
introduce new severity keywords, so consumers should be prepared to accept
and ignore severity values they don't understand.
- `summary` (string): A short description of the nature of the problem that
the diagnostic is reporting.
In Terraform's usual human-oriented diagnostic messages, the summary serves
as a sort of "heading" for the diagnostic, printed after the "Error:" or
"Warning:" indicator.
Summaries are typically short, single sentences, but can sometimes be longer
as a result of returning errors from subsystems that are not designed to
return full diagnostics, where the entire error message becomes the
summary. In those cases, the summary might include newline characters which
a renderer should honor when presenting the message visually to a user.
- `detail` (string): An optional additional message giving more detail about
the problem.
In Terraform's usual human-oriented diagnostic messages, the detail provides
the paragraphs of text that appear after the heading and the source location
reference.
Detail messages are often multiple paragraphs and possibly interspersed with
non-paragraph lines, so tools that aim to present detailed messages to the
user should distinguish between lines without leading spaces, treating them
as paragraphs, and lines with leading spaces, treating them as preformatted
text. Renderers should then soft-wrap the paragraphs to fit the width of the
rendering container, but leave the preformatted lines unwrapped.
Some Terraform detail messages contain an approximation of bullet
lists using ASCII characters to mark the bullets. This is not a
contractual formatting convention, so renderers should avoid depending on
it and should instead treat those lines as either paragraphs or preformatted
text.
- `range` (object): An optional object referencing a portion of the configuration
source code that the diagnostic message relates to. For errors, this will
typically indicate the bounds of the specific block header, attribute, or
expression which was detected as invalid.
A source range is an object with a property `filename` that gives the
filename as a relative path from the current working directory, and then
two properties `start` and `end` which are both themselves objects
describing source positions, as described below.
Not all diagnostic messages are connected with specific portions of the
configuration, so `range` will be omitted or `null` for diagnostic messages
where it isn't relevant.
- `snippet` (object): An optional object including an excerpt of the
configuration source code that the diagnostic message relates to.
The snippet information includes:
- `context` (string): An optional summary of the root context of the
diagnostic. For example, this might be the resource block containing the
expression that triggered the diagnostic. For some diagnostics, this
information is not available, and then this property will be `null`.
- `code` (string): A snippet of Terraform configuration including the
source of the diagnostic. This can be multiple lines and may include
additional configuration source code around the expression which
triggered the diagnostic.
- `start_line` (number): A one-based line count representing the position
in the source file at which the `code` excerpt begins. This is not
necessarily the same value as `range.start.line`, as it is possible for
`code` to include one or more lines of context before the source of the
diagnostic.
- `highlight_start_offset` (number): A zero-based character offset into the
`code` string, pointing at the start of the expression which triggered
the diagnostic.
- `highlight_end_offset` (number): A zero-based character offset into the
`code` string, pointing at the end of the expression which triggered the
diagnostic.
- `values` (array of objects): Contains zero or more expression values
which may be useful in understanding the source of a diagnostic in a
complex expression. These expression value objects are described below.
### Source Position
A source position object, as used in the `range` property of a diagnostic
object, has the following properties:
- `byte` (number): A zero-based byte offset into the indicated file.
- `line` (number): A one-based line count for the line containing the relevant
position in the indicated file.
- `column` (number): A one-based count of _Unicode characters_ from the start
of the line indicated in `line`.
A `start` position is inclusive while an `end` position is exclusive. The
exact positions used for particular error messages are intended for human
interpretation only.
### Expression Value
An expression value object gives additional information about a value that is
part of the expression which triggered the diagnostic. This is especially
useful when using `for_each` or similar constructs, in order to identify
exactly which values are responsible for an error. The object has two properties:
- `traversal` (string): An HCL-like traversal string, such as
`var.instance_count`. Complex index key values may be elided, so this will
not always be valid, parseable HCL. The contents of this string are intended
to be human-readable.
- `statement` (string): A short English-language fragment describing the value
of the expression when the diagnostic was triggered. The contents of this
string are intended to be human-readable and are subject to change in future
versions of Terraform.

View file

@ -1,59 +0,0 @@
---
page_title: terraform version command reference
description: >-
The terraform version command prints the Terraform version and the version
of all installed plugins.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform version` command
The `terraform version` command prints the current version of the Terraform binary and all
installed plugins.
## Usage
Usage: `terraform version [options]`
With no additional arguments, `version` displays the version of Terraform,
the platform it is installed on, installed providers, and the results of upgrade
and security checks unless disabled. Refer to [Upgrade and Security Bulletin Checks](/terraform/cli/commands#upgrade-and-security-bulletin-checks) for additional information.
## Flags
This command has one optional flag:
* `-json` - Formats version information as a JSON object. No upgrade or security information is included.
## Example
Basic usage, with upgrade and security information shown if relevant:
```shellsession
$ terraform version
Terraform v0.15.0
on darwin_amd64
+ provider registry.terraform.io/hashicorp/null v3.0.0
Your version of Terraform is out of date! The latest version
is X.Y.Z. You can update by downloading from https://developer.hashicorp.com/terraform/install
```
As JSON:
```shellsession
$ terraform version -json
{
"terraform_version": "0.15.0",
"platform": "darwin_amd64",
"provider_selections": {
"registry.terraform.io/hashicorp/null": "3.0.0"
},
"terraform_outdated": true
}
```

View file

@ -1,49 +0,0 @@
---
page_title: terraform workspace delete command reference
description: The terraform workspace delete command deletes the specified workspace.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace delete` command
The `terraform workspace delete` command deletes the specified workspace.
## Usage
Usage: `terraform workspace delete [OPTIONS] NAME [DIR]`
This command will delete the specified workspace.
To delete a workspace, it must already exist, it must not be tracking resources,
and it must not be your current workspace. If the workspace is tracking resources,
Terraform will not allow you to delete it unless the `-force` flag is specified.
Additionally, different [backends](/terraform/language/backend#backend-types) may implement other
restrictions on whether a workspace is considered safe to delete without the `-force` flag, such as whether the workspace is locked.
If you delete a workspace which is tracking resources (via `-force`), then resources
may become "dangling". These are resources that physically exist but that
Terraform can no longer manage. This is sometimes preferred: you may want
Terraform to stop managing resources, so they can be managed some other way.
Most of the time, however, this is not intended and so Terraform protects you
from getting into this situation.
The command-line flags are all optional. The only supported flags are:
* `-force` - Delete the workspace even if it is tracking resources. After deletion, Terraform can no longer track or manage the workspace's infrastructure. Defaults to false.
* `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
* `-lock-timeout=DURATION` - Duration to retry a state lock. Default 0s.
## Example
```
$ terraform workspace delete example
Deleted workspace "example".
```

View file

@ -1,22 +0,0 @@
---
page_title: terraform workspace command reference
description: The terraform workspace command helps you manage workspaces.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace` command
The `terraform workspace` command group helps you manage [workspaces](/terraform/language/state/workspaces).
This command is a container for further subcommands that each have their own page in the documentation.
## Usage
Usage: `terraform workspace <subcommand> [options] [args]`
Choose a subcommand page for more information.

View file

@ -1,30 +0,0 @@
---
page_title: terraform workspace list command reference
description: The terraform workspace list command lists all existing workspaces.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace list` command
The `terraform workspace list` command lists all existing workspaces.
## Usage
Usage: `terraform workspace list [DIR]`
The command will list all existing workspaces. The current workspace is
indicated using an asterisk (`*`) marker.
## Example
```
$ terraform workspace list
default
* development
jsmith-test
```

View file

@ -1,56 +0,0 @@
---
page_title: terraform workspace new command reference
description: The terraform workspace new command creates a new workspace with the specified name.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace new` command
The `terraform workspace new` command is used to create a new workspace.
## Usage
Usage: `terraform workspace new [OPTIONS] NAME [DIR]`
This command will create a new workspace with the given name. A workspace with
this name must not already exist.
If the `-state` flag is given, the state specified by the given path
will be copied to initialize the state for this new workspace.
The command-line flags are all optional. The supported flags are:
* `-lock=false` - Don't hold a state lock during the operation. This is
dangerous if others might concurrently run commands against the same
workspace.
* `-lock-timeout=DURATION` - Duration to retry a state lock. Default 0s.
* `-state=path` - Path to an existing state file to initialize the state of this environment.
## Example: Create
```
$ terraform workspace new example
Created and switched to workspace "example"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
```
## Example: Create from State
To create a new workspace from a pre-existing local state file:
```
$ terraform workspace new -state=old.terraform.tfstate example
Created and switched to workspace "example".
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
```

View file

@ -1,37 +0,0 @@
---
page_title: terraform workspace select` command reference
description: The terraform workspace select command selects a workspace.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace select` command
The `terraform workspace select` selects a different workspace to use for further operations.
## Usage
Usage: `terraform workspace select NAME [DIR]`
This command will select another workspace. The named workspace must already
exist.
The supported flags are:
* `-or-create` - If the workspace that is being selected does not exist, create it. Default is `false`.
## Example
```
$ terraform workspace list
default
* development
jsmith-test
$ terraform workspace select default
Switched to workspace "default".
```

View file

@ -1,27 +0,0 @@
---
page_title: terraform workspace show command reference
description: The terraform workspace show command outputs the current workspace.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform workspace show` command
The `terraform workspace show` command outputs the current workspace.
## Usage
Usage: `terraform workspace show`
The command displays the current workspace.
## Example
```
$ terraform workspace show
development
```

View file

@ -1,544 +0,0 @@
---
page_title: Create a Terraform CLI configuration file
description: >-
Learn how to create a `.terraformrc` or `terraform.rc` file to define Terraform CLI settings, including credentials, plugin caching, and provider installation.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Create a Terraform CLI configuration file
This topic describes how create a configuration file to customize the behavior of the Terraform CLI.
## Introduction
The CLI configuration file configures per-user settings for CLI behaviors,
which apply across all Terraform working directories. This is separate from
[your infrastructure configuration](/terraform/language).
You can define custom configurations in file called `.terraformrc` or `terraform.rc`
depending on the host operating system as explained below.
## Locations
The configuration can be placed in a single file whose location depends
on the host operating system:
* On Windows, the file must be named `terraform.rc` and placed
in the relevant user's `%APPDATA%` directory. The physical location
of this directory depends on your Windows version and system configuration;
use `$env:APPDATA` in PowerShell to find its location on your system.
* On all other systems, the file must be named `.terraformrc` (note
the leading period) and placed directly in the home directory
of the relevant user.
On Windows, beware of Windows Explorer's default behavior of hiding filename
extensions. Terraform will not recognize a file named `terraform.rc.txt` as a
CLI configuration file, even though Windows Explorer may _display_ its name
as just `terraform.rc`. Use `dir` from PowerShell or Command Prompt to
confirm the filename.
The location of the Terraform CLI configuration file can also be specified
using the `TF_CLI_CONFIG_FILE` [environment variable](/terraform/cli/config/environment-variables).
Any such file should follow the naming pattern `*.tfrc`.
## Configuration File Syntax
The configuration file uses the same _HCL_ syntax as `.tf` files, but with
different attributes and blocks. The following example illustrates the
general syntax; see the following section for information on the meaning
of each of these settings:
```hcl
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true
```
## Available Settings
The following settings can be set in the CLI configuration file:
* `credentials` - configures credentials for use with HCP Terraform or
Terraform Enterprise. See [Credentials](#credentials) below for more
information.
* `credentials_helper` - configures an external helper program for the storage
and retrieval of credentials for HCP Terraform or Terraform Enterprise.
See [Credentials Helpers](#credentials-helpers) below for more information.
* `disable_checkpoint` — when set to `true`, disables
[upgrade and security bulletin checks](/terraform/cli/commands#upgrade-and-security-bulletin-checks)
that require reaching out to HashiCorp-provided network services.
* `disable_checkpoint_signature` — when set to `true`, allows the upgrade and
security bulletin checks described above but disables the use of an anonymous
id used to de-duplicate warning messages.
* `plugin_cache_dir` — enables
[plugin caching](#provider-plugin-cache)
and specifies, as a string, the location of the plugin cache directory.
* `provider_installation` - customizes the installation methods used by
`terraform init` when installing provider plugins. See
[Provider Installation](#provider-installation) below for more information.
## Credentials
[HCP Terraform](https://cloud.hashicorp.com/products/terraform) provides a number of remote network
services for use with Terraform, and
[Terraform Enterprise](/terraform/enterprise) allows hosting those
services inside your own infrastructure. For example, these systems offer both
[remote operations](/terraform/cloud-docs/run/cli) and a
[private module registry](/terraform/cloud-docs/registry).
When interacting with Terraform-specific network services, Terraform expects
to find API tokens in CLI configuration files in `credentials` blocks:
```hcl
credentials "app.terraform.io" {
token = "xxxxxx.atlasv1.zzzzzzzzzzzzz"
}
```
If you are running the Terraform CLI interactively on a computer with a web browser, you can use [the `terraform login` command](/terraform/cli/commands/login)
to get credentials and automatically save them in the CLI configuration. If
not, you can manually write `credentials` blocks.
You can have multiple `credentials` blocks if you regularly use services from
multiple hosts. Many users will configure only one, for either
HCP Terraform (at `app.terraform.io`) or for their organization's own
Terraform Enterprise host. Each `credentials` block contains a `token` argument
giving the API token to use for that host.
~> **Important:** If you are using HCP Terraform or Terraform Enterprise,
the token provided must be either a
[user token](/terraform/cloud-docs/users-teams-organizations/users#api-tokens)
or a
[team token](/terraform/cloud-docs/users-teams-organizations/api-tokens#team-api-tokens);
organization tokens cannot be used for command-line Terraform actions.
-> **Note:** The credentials hostname must match the hostname in your module
sources and/or backend configuration. If your Terraform Enterprise instance
is available at multiple hostnames, use only one of them consistently.
HCP Terraform responds to API calls at both its current hostname
`app.terraform.io`, and its historical hostname `atlas.hashicorp.com`.
### Environment Variable Credentials
-> **Note:** Environment variable credentials are supported in Terraform v1.2.0 and later.
If you would prefer not to store your API tokens directly in the CLI configuration, you may use
a host-specific environment variable. Environment variable names should have the prefix
`TF_TOKEN_` added to the domain name, with periods encoded as underscores. For example, the
value of a variable named `TF_TOKEN_app_terraform_io` will be used as a bearer authorization
token when the CLI makes service requests to the hostname `app.terraform.io`.
You must convert domain names containing non-ASCII characters to their [punycode equivalent](https://www.charset.org/punycode)
with an ACE prefix. For example, token credentials for 例えば.com must be set in a variable
called `TF_TOKEN_xn--r8j3dr99h_com`.
Hyphens are also valid within host names but usually invalid as variable names and
may be encoded as double underscores. For example, you can set a token for the domain name
`café.fr` as `TF_TOKEN_xn--caf-dma.fr`, `TF_TOKEN_xn--caf-dma_fr`, or `TF_TOKEN_xn____caf__dma_fr`.
If multiple variables evaluate to the same hostname, Terraform will choose the one defined last
in the operating system's variable table.
### Credentials Helpers
You can configure a `credentials_helper` to instruct Terraform to use a different credentials storage mechanism.
```hcl
credentials_helper "example" {
args = []
}
```
`credentials_helper` is a configuration block that can appear at most once
in the CLI configuration. Its label (`"example"` above) is the name of the
credentials helper to use. The `args` argument is optional and allows passing
additional arguments to the helper program, for example if it needs to be
configured with the address of a remote host to access for credentials.
A configured credentials helper will be consulted only to retrieve credentials
for hosts that are _not_ explicitly configured in a `credentials` block as
described in the previous section.
Conversely, this means you can override the credentials returned by the helper
for a specific hostname by writing a `credentials` block alongside the
`credentials_helper` block.
Terraform does not include any credentials helpers in the main distribution.
To learn how to write and install your own credentials helpers to integrate
with existing in-house credentials management systems, see
[the guide to Credentials Helper internals](/terraform/internals/credentials-helpers).
### Credentials Source Priority Order
Credentials found in an environment variable for a particular service host
as described above will be preferred over those in CLI config as set by `terraform login`.
If neither are set, any configured credentials helper will be consulted.
~> **Note:** For users of [terraform-credentials-helper](https://github.com/apparentlymart/terraform-credentials-env), this priority has been effectively reversed following the
release of Terraform 1.2. Previously, credentials found within CLI config or set by
`terraform login` were preferred to `TF_TOKEN_*` variables.
## Provider Installation
The default way to install provider plugins is from a provider registry. The
origin registry for a provider is encoded in the provider's source address,
like `registry.terraform.io/hashicorp/aws`. For convenience in the common case,
Terraform allows omitting the hostname portion for providers on
`registry.terraform.io`, so you can write shorter public provider addresses like
`hashicorp/aws`.
Downloading a plugin directly from its origin registry is not always
appropriate, though. For example, the system where you are running Terraform
may not be able to access an origin registry due to firewall restrictions
within your organization or your locality.
To allow using Terraform providers in these situations, there are some
alternative options for making provider plugins available to Terraform which
we'll describe in the following sections.
### Explicit Installation Method Configuration
A `provider_installation` block in the CLI configuration allows overriding
Terraform's default installation behaviors, so you can force Terraform to use
a local mirror for some or all of the providers you intend to use.
The general structure of a `provider_installation` block is as follows:
```hcl
provider_installation {
filesystem_mirror {
path = "/usr/share/terraform/providers"
include = ["example.com/*/*"]
}
direct {
exclude = ["example.com/*/*"]
}
}
```
Each of the nested blocks inside the `provider_installation` block specifies
one installation method. Each installation method can take both `include`
and `exclude` patterns that specify which providers a particular installation
method can be used for. In the example above, we specify that any provider
whose origin registry is at `example.com` can be installed only from the
filesystem mirror at `/usr/share/terraform/providers`, while all other
providers can be installed only directly from their origin registries.
If you set both `include` and `exclude` for a particular installation
method, the exclusion patterns take priority. For example, including
`registry.terraform.io/hashicorp/*` but also excluding
`registry.terraform.io/hashicorp/dns` will make that installation method apply
to everything in the `hashicorp` namespace with the exception of
`hashicorp/dns`.
As with provider source addresses in the main configuration, you can omit
the `registry.terraform.io/` prefix for providers distributed through the
public Terraform registry, even when using wildcards. For example,
`registry.terraform.io/hashicorp/*` and `hashicorp/*` are equivalent.
`*/*` is a shorthand for `registry.terraform.io/*/*`, not for
`*/*/*`.
The following are the two supported installation method types:
* `direct`: request information about the provider directly from its origin
registry and download over the network from the location that registry
indicates. This method expects no additional arguments.
* `filesystem_mirror`: consult a directory on the local disk for copies of
providers. This method requires the additional argument `path` to indicate
which directory to look in.
Terraform expects the given directory to contain a nested directory structure
where the path segments together provide metadata about the available
providers. The following two directory structures are supported:
* Packed layout: `HOSTNAME/NAMESPACE/TYPE/terraform-provider-TYPE_VERSION_TARGET.zip`
is the distribution zip file obtained from the provider's origin registry.
* Unpacked layout: `HOSTNAME/NAMESPACE/TYPE/VERSION/TARGET` is a directory
containing the result of extracting the provider's distribution zip file.
In both layouts, the `VERSION` is a string like `2.0.0` and the `TARGET`
specifies a particular target platform using a format like `darwin_amd64`,
`linux_arm`, `windows_amd64`, etc.
If you use the unpacked layout, Terraform will attempt to create a symbolic
link to the mirror directory when installing the provider, rather than
creating a deep copy of the directory. The packed layout prevents this
because Terraform must extract the zip file during installation.
You can include multiple `filesystem_mirror` blocks in order to specify
several different directories to search.
* `network_mirror`: consult a particular HTTPS server for copies of providers,
regardless of which registry host they belong to. This method requires the
additional argument `url` to indicate the mirror base URL, which should
use the `https:` scheme and end with a trailing slash.
Terraform expects the given URL to be a base URL for an implementation of
[the provider network mirror protocol](/terraform/internals/provider-network-mirror-protocol),
which is designed to be relatively easy to implement using typical static
website hosting mechanisms.
~> **Warning:** Don't configure `network_mirror` URLs that you do not trust.
Provider mirror servers are subject to TLS certificate checks to verify
identity, but a network mirror with a TLS certificate can potentially serve
modified copies of upstream providers with malicious content.
Terraform will try all of the specified methods whose include and exclude
patterns match a given provider, and select the newest version available across
all of those methods that matches the version constraint given in each
Terraform configuration. If you have a local mirror of a particular provider
and intend Terraform to use that local mirror exclusively, you must either
remove the `direct` installation method altogether or use its `exclude`
argument to disable its use for specific providers.
### Implied Local Mirror Directories
If your CLI configuration does not include a `provider_installation` block at
all, Terraform produces an _implied_ configuration. The implied configuration
includes a selection of `filesystem_mirror` methods and then the `direct`
method.
The set of directories Terraform can select as filesystem mirrors depends on
the operating system where you are running Terraform:
* **Windows:** `%APPDATA%/terraform.d/plugins` and `%APPDATA%/HashiCorp/Terraform/plugins`
* **Mac OS X:** `$HOME/.terraform.d/plugins`,
`~/Library/Application Support/io.terraform/plugins`, and
`/Library/Application Support/io.terraform/plugins`
* **Linux and other Unix-like systems**:`$HOME/.terraform.d/plugins` and
`terraform/plugins` located within a valid
[XDG Base Directory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
data directory such as `$XDG_DATA_HOME/terraform/plugins`.
Without any XDG environment variables set, Terraform will use
`~/.local/share/terraform/plugins`,
`/usr/local/share/terraform/plugins`, and `/usr/share/terraform/plugins`.
If a `terraform.d/plugins` directory exists in the current working directory
then Terraform will also include that directory, regardless of your operating
system. This behavior changes when you use the `-chdir` option with the `init` command. In that case, Terraform checks for the `terraform.d/plugins` directory in the launch directory and not in the directory you specified with `-chdir`.
Terraform will check each of the paths above to see if it exists, and if so
treat it as a filesystem mirror. The directory structure inside each one must
therefore match one of the two structures described for `filesystem_mirror`
blocks in [Explicit Installation Method Configuration](#explicit-installation-method-configuration).
In addition to the zero or more implied `filesystem_mirror` blocks, Terraform
also creates an implied `direct` block. Terraform will scan all of the
filesystem mirror directories to see which providers are placed there and
automatically exclude all of those providers from the implied `direct` block.
(This automatic `exclude` behavior applies only to _implicit_ `direct` blocks;
if you use explicit `provider_installation` you will need to write the intended
exclusions out yourself.)
### Provider Plugin Cache
By default, `terraform init` downloads plugins into a subdirectory of the
working directory so that each working directory is self-contained. As a
consequence, if you have multiple configurations that use the same provider
then a separate copy of its plugin will be downloaded for each configuration.
Given that provider plugins can be quite large (on the order of hundreds of
megabytes), this default behavior can be inconvenient for those with slow
or metered Internet connections. Therefore Terraform optionally allows the
use of a local directory as a shared plugin cache, which then allows each
distinct plugin binary to be downloaded only once.
To enable the plugin cache, use the `plugin_cache_dir` setting in
the CLI configuration file. For example:
```hcl
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
```
This directory must already exist before Terraform will cache plugins;
Terraform will not create the directory itself.
Please note that on Windows it is necessary to use forward slash separators
(`/`) rather than the conventional backslash (`\`) since the configuration
file parser considers a backslash to begin an escape sequence.
Setting this in the configuration file is the recommended approach for a
persistent setting. Alternatively, the `TF_PLUGIN_CACHE_DIR` environment
variable can be used to enable caching or to override an existing cache
directory within a particular shell session:
```bash
export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache"
```
When a plugin cache directory is enabled, the `terraform init` command will
still use the configured or implied installation methods to obtain metadata
about which plugins are available, but once a suitable version has been
selected it will first check to see if the chosen plugin is already available
in the cache directory. If so, Terraform will use the previously-downloaded
copy.
If the selected plugin is not already in the cache, Terraform will download
it into the cache first and then copy it from there into the correct location
under your current working directory. When possible Terraform will use
symbolic links to avoid storing a separate copy of a cached plugin in multiple
directories.
The plugin cache directory _must not_ also be one of the configured or implied
filesystem mirror directories, since the cache management logic conflicts with
the filesystem mirror logic when operating on the same directory.
Terraform will never itself delete a plugin from the plugin cache once it has
been placed there. Over time, as plugins are upgraded, the cache directory may
grow to contain several unused versions which you must delete manually.
-> **Note:** The plugin cache directory is not guaranteed to be concurrency
safe. The provider installer's behavior in environments with multiple `terraform
init` calls is undefined.
### Allowing the Provider Plugin Cache to break the dependency lock file
~> **Note:** The option described in is for unusual and exceptional situations
only. Do not set this option unless you are sure you need it and you fully
understand the consequences of enabling it.
By default Terraform will use packages from the global cache directory only
if they match at least one of the checksums recorded in the
[dependency lock file](/terraform/language/files/dependency-lock)
for that provider. This ensures that Terraform can always
generate a complete and correct dependency lock file entry the first time you
use a new provider in a particular configuration.
However, we know that in some special situations teams have been unable to use
the dependency lock file as intended, and so they don't include it in their
version control as recommended and instead let Terraform re-generate it each
time it installs providers.
For those teams that don't preserve the dependency lock file in their version
control systems between runs, Terraform allows an additional CLI Configuration
setting which tells Terraform to always treat a package in the cache directory
as valid even if there isn't already an entry in the dependency lock file
to confirm it:
```hcl
plugin_cache_may_break_dependency_lock_file = true
```
Alternatively, you can set the environment variable
`TF_PLUGIN_CACHE_MAY_BREAK_DEPENDENCY_LOCK_FILE` to any value other than the
empty string or `0`, which is equivalent to the above setting.
Setting this option gives Terraform CLI permission to create an incomplete
dependency lock file entry for a provider if that would allow Terraform to
use the cache to install that provider. In that situation the dependency lock
file will be valid for use on the current system but may not be valid for use on
another computer with a different operating system or CPU architecture, because
it will include only a checksum of the package in the global cache.
We recommend that most users leave this option unset, in which case Terraform
will always install a provider from upstream the first time you use it with
a particular configuration, but can then re-use the cache entry on later runs
once the dependency lock file records valid checksums for the provider package.
~> **Note:** The Terraform team intends to improve the dependency lock file
mechanism in future versions so that it will be usable in more situations. At
that time this option will become silently ignored. If your workflow relies on
the use of this option, please open a GitHub issue to share details about your
situation so that we can consider how to support it without breaking the
dependency lock file.
### Development Overrides for Provider Developers
-> **Note:** Development overrides work only in Terraform v0.14 and later.
Using a `dev_overrides` block in your CLI configuration will cause Terraform
v0.13 to reject the configuration as invalid.
Normally Terraform verifies version selections and checksums for providers
in order to help ensure that all operations are made with the intended version
of a provider, and that authors can gradually upgrade to newer provider versions
in a controlled manner.
These version and checksum rules are inconvenient when developing a provider
though, because we often want to try a test configuration against a development
build of a provider that doesn't even have an associated version number yet,
and doesn't have an official set of checksums listed in a provider registry.
As a convenience for provider development, Terraform supports a special
additional block `dev_overrides` in `provider_installation` blocks. The contents
of this block effectively override all of the other configured installation
methods, so a block of this type must always appear first in the sequence:
```hcl
provider_installation {
# Use /home/developer/tmp/terraform-null as an overridden package directory
# for the hashicorp/null provider. This disables the version and checksum
# verifications for this provider and forces Terraform to look for the
# null provider plugin in the given directory.
dev_overrides {
"hashicorp/null" = "/home/developer/tmp/terraform-null"
}
# For all other providers, install them directly from their origin provider
# registries as normal. If you omit this, Terraform will _only_ use
# the dev_overrides block, and so no other providers will be available.
direct {}
}
```
With development overrides in effect, the `terraform init` command will still
attempt to select a suitable published version of your provider to install and
record in
[the dependency lock file](/terraform/language/files/dependency-lock)
for future use, but other commands like
`terraform apply` will disregard the lock file's entry for `hashicorp/null` and
will use the given directory instead. Once your new changes are included in a
published release of the provider, you can use `terraform init -upgrade` to
select the new version in the dependency lock file and remove your development
override.
The override path for a particular provider should be a directory similar to
what would be included in a `.zip` file when distributing the provider. At
minimum that includes an executable file named with a prefix like
`terraform-provider-null`, where `null` is the provider type. If your provider
makes use of other files in its distribution package then you can copy those
files into the override directory too.
You may wish to enable a development override only for shell sessions where
you are actively working on provider development. If so, you can write a
local CLI configuration file with content like the above in your development
directory, perhaps called `dev.tfrc` for the sake of example, and then use the
`TF_CLI_CONFIG_FILE` environment variable to instruct Terraform to use that
localized CLI configuration instead of the default one:
```
export TF_CLI_CONFIG_FILE=/home/developer/tmp/dev.tfrc
```
Development overrides are not intended for general use as a way to have
Terraform look for providers on the local filesystem. If you wish to put
copies of _released_ providers in your local filesystem, see
[Implied Local Mirror Directories](#implied-local-mirror-directories)
or
[Explicit Installation Method Configuration](#explicit-installation-method-configuration)
instead.
This development overrides mechanism is intended as a pragmatic way to enable
smoother provider development. The details of how it behaves, how to
configure it, and how it interacts with the dependency lock file may all evolve
in future Terraform releases, including possible breaking changes. We therefore
recommend using development overrides only temporarily during provider
development work.
## Removed Settings
The following settings are supported in Terraform 0.12 and earlier but are
no longer recommended for use:
* `providers` - a configuration block that allows specifying the locations of
specific plugins for each named provider. This mechanism is deprecated
because it is unable to specify a version number and source for each provider.
See [Provider Installation](#provider-installation) above for the replacement
of this setting in Terraform 0.13 and later.

View file

@ -1,183 +0,0 @@
---
page_title: Terraform CLI environment variables reference
description: >-
Terraform environment variables let you customize the Terraform CLI's default behavior.
Learn about the Terraform CLI environment variables.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform CLI environment variables reference
This topic contains reference information about the environment variables you can use with the Terraform CLI.
## Introduction
Terraform refers to a number of environment variables to customize various
aspects of its behavior. None of these environment variables are required
when using Terraform, but you can use them to change some of Terraform's
default behaviors or to increase output verbosity for debugging.
## TF_LOG
Enables detailed logs to appear on stderr which is useful for debugging. For example:
```shell
export TF_LOG=trace
```
To disable, either unset it, or set it to `off`. For example:
```shell
export TF_LOG=off
```
For more on debugging Terraform, check out the section on [Debugging](/terraform/internals/debugging).
## TF_LOG_PATH
This specifies where the log should persist its output to. Note that even when `TF_LOG_PATH` is set, `TF_LOG` must be set in order for any logging to be enabled. For example, to always write the log to the directory you're currently running terraform from:
```shell
export TF_LOG_PATH=./terraform.log
```
For more on debugging Terraform, check out the section on [Debugging](/terraform/internals/debugging).
## TF_INPUT
If set to "false" or "0", causes terraform commands to behave as if the `-input=false` flag was specified. This is used when you want to disable prompts for variables that haven't had their values specified. For example:
```shell
export TF_INPUT=0
```
## TF_VAR_name
Environment variables can be used to set variables. The environment variables must be in the format `TF_VAR_name` and this will be checked last for a value. For example:
```shell
export TF_VAR_region=us-west-1
export TF_VAR_ami=ami-049d8641
export TF_VAR_alist='[1,2,3]'
export TF_VAR_amap='{ foo = "bar", baz = "qux" }'
```
For more on how to use `TF_VAR_name` in context, check out the section on [Variable Configuration](/terraform/language/values/variables).
## TF_CLI_ARGS and TF_CLI_ARGS_name
<a id="tf-cli-args"></a>
The value of `TF_CLI_ARGS` will specify additional arguments to the
command-line. This allows easier automation in CI environments as well as
modifying default behavior of Terraform on your own system.
These arguments are inserted directly _after_ the subcommand
(such as `plan`) and _before_ any flags specified directly on the command-line.
This behavior ensures that flags on the command-line take precedence over
environment variables.
For example, the following command: `TF_CLI_ARGS="-input=false" terraform apply -force`
is the equivalent to manually typing: `terraform apply -input=false -force`.
The flag `TF_CLI_ARGS` affects all Terraform commands. If you specify a
named command in the form of `TF_CLI_ARGS_name` then it will only affect
that command. As an example, to specify that only plans never refresh,
you can set `TF_CLI_ARGS_plan="-refresh=false"`.
The value of the flag is parsed as if you typed it directly to the shell.
Double and single quotes are allowed to capture strings and arguments will
be separated by spaces otherwise.
## TF_DATA_DIR
`TF_DATA_DIR` changes the location where Terraform keeps its
per-working-directory data, such as the current backend configuration.
By default this data is written into a `.terraform` subdirectory of the
current directory, but the path given in `TF_DATA_DIR` will be used instead
if non-empty.
In most cases it should not be necessary to set this variable, but it may
be useful to do so if e.g. the working directory is not writable.
The data directory is used to retain data that must persist from one command
to the next, so it's important to have this variable set consistently throughout
all of the Terraform workflow commands (starting with `terraform init`) or else
Terraform may be unable to find providers, modules, and other artifacts.
## TF_WORKSPACE
For multi-environment deployment, in order to select a workspace, instead of doing `terraform workspace select your_workspace`, it is possible to use this environment variable. Using TF_WORKSPACE allow and override workspace selection.
For example:
```shell
export TF_WORKSPACE=your_workspace
```
Using this environment variable is recommended only for non-interactive usage, since in a local shell environment it can be easy to forget the variable is set and apply changes to the wrong state.
For more information regarding workspaces, check out the section on [Using Workspaces](/terraform/language/state/workspaces).
## TF_IN_AUTOMATION
If `TF_IN_AUTOMATION` is set to any non-empty value, Terraform adjusts its
output to avoid suggesting specific commands to run next. This can make the
output more consistent and less confusing in workflows where users don't
directly execute Terraform commands, like in CI systems or other wrapping
applications.
This is a purely cosmetic change to Terraform's human-readable output, and the
exact output differences can change between minor Terraform versions.
For more details, see [Running Terraform in Automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS).
## TF_REGISTRY_DISCOVERY_RETRY
Set `TF_REGISTRY_DISCOVERY_RETRY` to configure the max number of request retries
the remote registry client will attempt for client connection errors or
500-range responses that are safe to retry.
## TF_REGISTRY_CLIENT_TIMEOUT
The default client timeout for requests to the remote registry is 10s. `TF_REGISTRY_CLIENT_TIMEOUT` can be configured and increased during exceptional circumstances.
```shell
export TF_REGISTRY_CLIENT_TIMEOUT=15
```
## TF_STATE_PERSIST_INTERVAL
The interval in seconds that Terraform attempts to persist state to a remote backend during an apply operation. The default minimum interval for all remote backends is 20 seconds. Backends may override the default minimum value. If the value of `TF_STATE_PERSIST_INTERVAL` is lower than the default interval specified by a remote backend, the default interval will be used.
```shell
export TF_STATE_PERSIST_INTERVAL=100
```
## TF_CLI_CONFIG_FILE
The location of the [Terraform CLI configuration file](/terraform/cli/config/config-file).
```shell
export TF_CLI_CONFIG_FILE="$HOME/.terraformrc-custom"
```
Note that `TERRAFORM_CONFIG` is a deprecated alias for the `TF_CLI_CONFIG_FILE` variable. We recommend using `TF_CLI_CONFIG_FILE` instead of the deprecated `TERRAFORM_CONFIG` variable.
## TF_PLUGIN_CACHE_DIR
The `TF_PLUGIN_CACHE_DIR` environment variable is an alternative way to set [the `plugin_cache_dir` setting in the CLI configuration](/terraform/cli/config/config-file#provider-plugin-cache).
You can also use `TF_PLUGIN_CACHE_MAY_BREAK_DEPENDENCY_LOCK_FILE` to activate [the transitional compatibility setting `plugin_cache_may_break_dependency_lock_file`](/terraform/cli/config/config-file#allowing-the-provider-plugin-cache-to-break-the-dependency-lock-file).
## HCP Terraform CLI Integration
The CLI integration with HCP Terraform lets you use HCP Terraform and Terraform Enterprise on the command line. The integration requires including a `cloud` block in your Terraform configuration. You can define its arguments directly in your configuration file or supply them through environment variables, which can be useful for non-interactive workflows like Continuous Integration (CI).
Refer to [HCP Terraform Settings](/terraform/cli/cloud/settings#environment-variables) for a full list of `cloud` block environment variables.

View file

@ -1,28 +0,0 @@
---
page_title: Terraform CLI configuration overview
description: >-
The CLI configuration file and supported Terraform environment variables let you customize Terraform CLI behavior.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform CLI configuration overview
You can configure the Terraform CLI in global settings, which are separate
from any Terraform configuration and which apply across all working directories.
The default behavior of the Terraform CLI is suitable in most cases. As a result,
most of the global settings relate to advanced or automated workflows, or
unusual environmental conditions, such as running Terraform on an air-gapped
instance.
- The [CLI config file](/terraform/cli/config/config-file) configures provider
installation and security features.
- Several [environment variables](/terraform/cli/config/environment-variables) can
configure Terraform's inputs and outputs; this includes some alternate ways to
provide information that is usually passed on the command line or read from
the state of the shell.

View file

@ -1,48 +0,0 @@
---
page_title: Import existing infrastructure resources
description: >-
Terraform lets you import existing infrastructure into state so that you can begin managing your infrastructure as code.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Import existing resources overview
This topic provides an overview of the Terraform commands that let you import existing infrastructure resources so that you can manage them with Terraform.
> **Hands-on:** Try the [Import Terraform Configuration](/terraform/tutorials/state/state-import?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Workflows
You can import an existing resource to state from the Terraform CLI. You can also perform import operations using HCP Terraform. To import multiple resources, use the `import` block.
### Import to state
Before you run `terraform import` you must manually write a `resource` configuration block for the resource. The resource block describes where Terraform should map the imported object.
The `terraform import` CLI command can only import resources into the [state](/terraform/language/state). Importing via the CLI does _not_ generate configuration. If you want to generate the accompanying configuration for imported resources, [use the `import` block instead](/terraform/language/import).
Terraform expects each remote object to be bound to a single resource address. You should import each remote object to one Terraform resource address. Importing the same object multiple times may result in unwanted behavior. Refer to [State](/terraform/language/state) for more details.
### HCP Terraform
When you use Terraform on the command line with HCP Terraform, commands such as `apply` run inside your HCP Terraform environment. However, the `import` command runs locally, so it does not have access to information from HCP Terraform. To successfully perform an import, you may need to set local variables equivalent to any remote workspace variables in HCP Terraform.
### Import multiple resources
You can specify multiple resources in the `import` block to import more than one resource at a time. You can also review imports as part of your normal plan and apply workflow. Refer to the [`import` block reference ](/terraform/language/import) in the Terraform configuration language documentation for addtitional information.
## Resource importability
Each resource in Terraform must implement some basic logic to become
importable. As a result, you cannot import all Terraform resources.
The resources that you can import are documented at the bottom of
each resource documentation page in the [Terraform Registry](https://registry.terraform.io/). If you have issues importing a resource, report an issue in the relevant provider repository.
To make a resource importable, refer to [Extending Terraform: Resources — Import](/terraform/plugin/sdkv2/resources/import).

View file

@ -1,94 +0,0 @@
---
page_title: Import existing resources
description: Learn now to use the `terraform import` command to import existing infrastructure resources.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Import existing resources
This topic describes how to use the `terraform import` command to import existing infrastructure resources so that you can manage them as code.
> **Hands-on:** Try the [Import Terraform Configuration](/terraform/tutorials/state/state-import?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Overview
Use the `terraform import` command to import existing infrastructure to Terraform state. The `terraform import` command can only import one resource at a time. It cannot simultaneously import an entire collection of resources, such as an AWS VPC.
Complete the following steps to import resources:
1. Add the resource you want to manage with Terraform to your Terraform configuration.
1. Run the `terraform import` command.
~> Warning: Terraform expects that each remote object it is managing will be
bound to only one resource address, which is normally guaranteed by Terraform
itself having created all objects. If you import existing objects into Terraform,
be careful to import each remote object to only one Terraform resource address.
If you import the same object multiple times, Terraform may exhibit unwanted
behavior. For more information on this assumption, see
[the State section](/terraform/language/state).
## Add the resource to your configuration
Write a resource block for the resource you want to import in your configuration.
Provide a name for the resource, which is a unique ID that you can use to reference the resource elsewhere in the configuration.
In the following example, the imported resource is an AWS instance named `example`:
```hcl
resource "aws_instance" "example" {
# ...instance configuration...
}
```
You do not have to complete the body of the resource block. Instead, you can finish defining arguments after the instance is imported.
## Run the `terraform import` command
Run `terraform import` to attach an existing instance to the
resource configuration:
```shell
$ terraform import aws_instance.example i-abcd1234
```
This command locates the AWS EC2 instance with ID `i-abcd1234`. Then it attaches
the existing settings of the instance, as described by the EC2 API, to the
name `aws_instance.example` of a module. In this example, the module path
implies that the root module is used. Finally, the mapping is saved in the
Terraform state.
It is also possible to import to resources in child modules, using their paths,
and to single instances of a resource with `count` or `for_each` set. See
[_Resource Addressing_](/terraform/cli/state/resource-addressing) for more
details on how to specify a target resource.
The syntax of the given ID is dependent on the resource type being imported.
For example, AWS instances use an opaque ID issued by the EC2 API, but
AWS Route53 Zones use the domain name itself. Consult the documentation for
each importable resource for details on what form of ID is required.
As a result of the above command, the resource is recorded in the state file.
You can now run `terraform plan` to see how the configuration compares to
the imported resource, and make any adjustments to the configuration to
align with the current (or desired) state of the imported object.
## Complex Imports
The above import is considered a "simple import": one resource is imported
into the state file. An import may also result in a "complex import" where
multiple resources are imported. For example, an AWS network ACL imports
an `aws_network_acl` but also one `aws_network_acl_rule` for each rule.
In this scenario, the secondary resources will not already exist in
the configuration, so it is necessary to consult the import output and create
a `resource` block in the configuration for each secondary resource. If this is
not done, Terraform will plan to destroy the imported objects on the next run.
If you want to rename or otherwise move the imported resources, the
[state management commands](/terraform/cli/commands/state) can be used.

View file

@ -1,25 +0,0 @@
---
page_title: Terraform CLI Documentation
description: >-
Learn Terraform's CLI-based workflows. You can use the CLI alone or
with HCP Terraform or Terraform Enterprise.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform CLI Documentation
> **Hands-on:** Try the [Terraform: Get Started](/terraform/tutorials/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials.
This documentation provides reference information about Terraform CLI commands,
as well as instructions for using commands to provision infrastructure and manage the
infrastructure lifecyle. It is relevant to anyone working with Terraform's CLI-based
workflows, including people who use Terraform CLI by itself, as well as those who
use Terraform CLI in conjunction with HCTP Terraform or Terraform Enterprise.
For information about the Terraform configuration language syntax and coding patters, refer to the
[Terraform configuration language documentation](/terraform/language).

View file

@ -1,77 +0,0 @@
---
page_title: Initialize the Terraform working directory
description: >-
Learn how to initialize the working directory with the terraform init command, which installs plugins and modules defined in the configuration and retrieves state data.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Initialize the Working Directory
Terraform expects to be invoked from a working directory that contains
configuration files written in
[the Terraform language](/terraform/language). Terraform uses
configuration content from this directory, and also uses the directory to store
settings, cached plugins and modules, and sometimes state data.
A working directory must be initialized before Terraform can perform any
operations in it (like provisioning infrastructure or modifying state).
## Working Directory Contents
A Terraform working directory typically contains:
- A Terraform configuration describing resources Terraform should manage. This
configuration is expected to change over time.
- A hidden `.terraform` directory, which Terraform uses to manage cached
provider plugins and modules, record which
[workspace](/terraform/cli/workspaces) is currently active, and
record the last known backend configuration in case it needs to migrate state
on the next run. This directory is automatically managed by Terraform, and is
created during initialization.
- State data when the configuration uses the default `local` backend. Terraform manages state in a `terraform.tfstate` file when the directory only uses
the default workspace or a `terraform.tfstate.d` directory when the directory
uses multiple workspaces.
## Initialization
Run the `terraform init` command to initialize a working directory that contains
a Terraform configuration. After initialization, you will be able to perform
other commands, like `terraform plan` and `terraform apply`.
If you try to run a command that relies on initialization without first
initializing, the command will fail with an error and explain that you need to
run init.
Initialization performs several tasks to prepare a directory, including
accessing state in the configured backend, downloading and installing provider
plugins, and downloading modules. Under some conditions (usually when changing
from one backend to another), it might ask the user for guidance or
confirmation.
For details, see [the `terraform init` command](/terraform/cli/commands/init).
## Reinitialization
Certain types of changes to a Terraform configuration can require
reinitialization before normal operations can continue. This includes changes to
provider requirements, module sources or version constraints, and backend
configurations.
You can reinitialize a directory by running `terraform init` again. In fact, you
can reinitialize at any time; the init command is idempotent, and will have no
effect if no changes are required.
If reinitialization is required, any commands that rely on initialization will
fail with an error and tell you so.
## Reinitializing Only Modules
The `terraform get` command will download modules referenced in the
configuration, but will not perform the other required initialization tasks.
This command is only useful for niche workflows, and most Terraform users can
ignore it in favor of `terraform init`.

View file

@ -1,41 +0,0 @@
---
page_title: Inspect infrastructure
description: >-
The terraform inspect commands return dependency information and outputs. Learn how to use terraform inspect commands
to understand your infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Inspect Infrastructure Commands Overview
Terraform configurations and state data include some highly structured
information about the resources they manage; this includes dependency
information, outputs (which are pieces of generated or discovered data that the
configuration's author considers important enough to surface to users), and
more.
Terraform CLI includes some commands for inspecting or transforming this data.
You can use these to integrate other tools with Terraform's infrastructure data,
or just to gain a deeper or more holistic understanding of your infrastructure.
- [The `terraform graph` command](/terraform/cli/commands/graph) creates a visual
representation of a configuration or a set of planned changes.
- [The `terraform output` command](/terraform/cli/commands/output) can get the
values for the top-level [output values](/terraform/language/values/outputs) of
a configuration, which are often helpful when making use of the infrastructure
Terraform has provisioned.
- [The `terraform show` command](/terraform/cli/commands/show) can generate
human-readable versions of a state file or plan file, or generate
machine-readable versions that can be integrated with other tools.
- [The `terraform state list` command](/terraform/cli/commands/state/list) can list
the resources being managed by the current working directory and workspace,
providing a complete or filtered list.
- [The `terraform state show` command](/terraform/cli/commands/state/show) can print
all of the attributes of a given resource being managed by the current working
directory and workspace, including generated read-only attributes like the
unique ID assigned by the cloud provider.

View file

@ -1,62 +0,0 @@
---
page_title: Manage Terraform plugins
description: >-
Providers are types of plugins for Terraform that manage infrastructure resources. Learn about managing plugins using the Terraform CLI.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Manage plugins overview
This topic provides an overview of the how to manage plugins that Terraform relies on to manage various types
of resources. Providers are the only plugin type Terraform users interact with. Refer to [Providers](/terraform/language/providers) in the Terraform
language docs for additional information about providers.
## Workflow
When you initialize a working directory, Terraform installs any providers the Terraform configuration requires. Refer to
[Provider Requirements](/terraform/language/providers/requirements) in the Terraform configuration language information about requiring providers. Refer to the [`terraform init` command documentation](/terraform/cli/init) for additional information about how initialize the working directory.
By default, Terraform initializes the working directory without any additional interaction, but you must have network access to
download providers from their source registry.
You can configure Terraform's provider installation behavior to limit or skip
network access, and to enable use of providers that are not available through a
networked source. Terraform also includes commands that show information
about providers and commands that reduce the effort of installing providers in air-gapped
environments.
## Configuring Plugin Installation
Terraform's configuration file includes options for caching downloaded plugins,
or explicitly specifying a local or HTTPS mirror to install plugins from. For
more information, see [CLI Config File](/terraform/cli/config/config-file).
## Getting Plugin Information
Use the [`terraform providers`](/terraform/cli/commands/providers) command to get information
about the providers required by the current working directory's configuration.
Use the [`terraform version`](/terraform/cli/commands/version) command (or
`terraform -version`) to show the specific provider versions installed for the
current working directory.
Use the [`terraform providers schema`](/terraform/cli/commands/providers/schema) command to
get machine-readable information about the resources and configuration options
offered by each provider.
## Managing Plugin Installation
Use the [`terraform providers mirror`](/terraform/cli/commands/providers/mirror) command to
download local copies of every provider required by the current working
directory's configuration. The directory uses the nested directory layout
that Terraform expects when installing plugins from a local source, so you can
transfer it directly to an air-gapped system that runs Terraform.
Use the [`terraform providers lock`](/terraform/cli/commands/providers/lock) command
to update the lock file that Terraform uses to ensure predictable runs when
using ambiguous provider version constraints.

View file

@ -1,35 +0,0 @@
---
page_title: Plugin signatures
description: >-
Signatures help you determine the authenticity of the plugins you want to install. Learn about the types of signatures providers can have on the Terraform registry.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
<!-- THIS PAGED IS LINKED TO IN THE CLI -->
# Plugin signatures
This topic provides information about the types of signatures that can be built into plugins you install. Terraform only authenticates provider plugins fetched from a registry.
## Types of plugin signatures
Terraform providers installed from the registry are cryptographically signed. Terraform verifies the signature during installation. There are three types of signatures:
* Providers signed by HashiCorp: HashiCorp builds, signs, and supports these providers.
* Providers signed by trusted partners: A third party builds, signs, and supports these providers. HashiCorp verifies the ownership of the private key and provides a chain of trust to the CLI to verify ownership programatically.
* Self-signed providers: A third party builds, signs, and supports these providers. HashiCorp does not provide a
verification or chain of trust for the signature. You may obtain and validate fingerprints manually
if you want to ensure you are using a binary you can trust.
## Unsigned binaries
You cannot fetch and use unsigned binaries from the registry, but you can manually install unsigned binaries. We strongly recommend that you thoroughly vetting providers that you manually install so that these providers do not programatically authenticate.
## Registry terms of use
Use of plugins from the registry is subject to the registry's [terms of use](https://registry.terraform.io/terms).

View file

@ -1,80 +0,0 @@
---
page_title: Terraform workflow for provisioning infrastructure
description: Learn how to use the Terraform CLI to provision infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform workflow for provisioning infrastructure
This topic provides overview information about the Terraform workflow for provisioning infrastructure using the Terraform CLI.
## Workflows
You can use Terraform to create, modify, and destroy infrastructure
resources to match the desired state described in a
[Terraform configuration](/terraform/language). The
Terraform binary includes commands and subcommands for a wide variety of infrastructure lifecycle management
actions, but the following commands provide basic provisioning tasks:
- `terrafrom plan`
- `terraform apply`
- `terraform destroy`
All of these commands require an [initialized](/terraform/cli/init) working directory, and all of them act
only upon the currently selected [workspace](/terraform/cli/workspaces).
### Plan
The `terraform plan` command evaluates a Terraform configuration to determine
the desired state of all the resources it declares, then compares that desired
state to the real infrastructure objects being managed with the current working
directory and workspace. It uses state data to determine which real objects
correspond to which declared resources, and checks the current state of each
resource using the relevant infrastructure provider's API.
Once it has determined the difference between the current state and the desired
state, `terraform plan` presents a description of the changes necessary to
achieve the desired state. It _does not_ perform any actual changes to real
world infrastructure objects; it only presents a plan for making changes.
Plans are usually run to validate configuration changes and confirm that the
resulting actions are as expected. However, `terraform plan` can also save its
plan as a runnable artifact, which `terraform apply` can use to carry out those
exact changes.
For details, see [the `terraform plan` command](/terraform/cli/commands/plan).
### Apply
The `terraform apply` command performs a plan just like `terraform plan` does,
but then actually carries out the planned changes to each resource using the
relevant infrastructure provider's API. It asks for confirmation from the user
before making any changes, unless it was explicitly told to skip approval.
By default, `terraform apply` performs a fresh plan right before applying
changes, and displays the plan to the user when asking for confirmation.
However, it can also accept a plan file produced by `terraform plan` in lieu of
running a new plan. You can use this to reliably perform an exact set of
pre-approved changes, even if the configuration or the state of the real
infrastructure has changed in the minutes since the original plan was created.
For details, see [the `terraform apply` command](/terraform/cli/commands/apply).
### Destroy
The `terraform destroy` command destroys all of the resources being managed by
the current working directory and workspace, using state data to determine which
real world objects correspond to managed resources. Like `terraform apply`, it
asks for confirmation before proceeding.
A destroy behaves exactly like deleting every resource from the configuration
and then running an apply, except that it doesn't require editing the
configuration. This is more convenient if you intend to provision similar
resources at a later date.
For details, see [the `terraform destroy` command](/terraform/cli/commands/destroy).

View file

@ -1,38 +0,0 @@
---
page_title: Update Terraform state manually
description: >-
State data is the record of how real-world objects map to resources in the Terraform configuration. Learn how to manually update with state data.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Update Terraform state manually overview
This topic provides overview information about how to manually update state in Terraform.
> **Hands-on:** Try the [Manage Resources in Terraform State](/terraform/tutorials/state/state-cli?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Introduction
Terraform stores information about real-world object that correspond to resources in the configuration as [state data](/terraform/language/state).
Doing so allows Terraform to modify an existing object when its resource declaration changes.
Terraform automatically updates state when you run the `terraform plan` and `terraform apply` commands, but you may need to manually adjustment state data as a result of changes to the configuration or the real managed infrastructure.
## Workflow
Modifying state data outside of normal `terraform plan` or `terraform apply` operations can cause Terraform to lose track of managed resources, leading to increased costs, reduced productivity, or compromised security. Make sure to keep backups of your state data if you choose to manually modify state.
You can use the Terraform CLI to perform the following state interations:
- [Inspect state](/terraform/cli/state/inspect)
- [Re-create resources](/terraform/cli/state/taint)
- [Move resources](/terraform/cli/state/move)
- [Import existing resources](/terraform/cli/import)
- [Recover state from backup](/terraform/cli/state/recover)

View file

@ -1,27 +0,0 @@
---
page_title: Inspect Terraform state
description: The `terraform state` group of commands help you inspect Terraform state. Learn how inspecting Terraform state can help you read and update state.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Inspect Terraform State Overview
Terraform includes some commands for reading and updating state without taking
any other actions.
- [The `terraform state list` command](/terraform/cli/commands/state/list)
shows the resource addresses for every resource Terraform knows about in a
configuration, optionally filtered by partial resource address.
- [The `terraform state show` command](/terraform/cli/commands/state/show)
displays detailed state data about one resource.
- [The `terraform refresh` command](/terraform/cli/commands/refresh) updates
state data to match the real-world condition of the managed resources. This is
done automatically during plans and applies, but not when interacting with
state directly.

View file

@ -1,52 +0,0 @@
---
page_title: Move resources
description: >-
Terraform state commands can move and remove resources and transfer existing resources to a different provider. Learn how about changing or moving resources.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Move Resources
Terraform's state associates each real-world object with a configured resource
at a specific [resource address](/terraform/cli/state/resource-addressing). This
is seamless when changing a resource's attributes, but Terraform will lose track
of a resource if you change its name, move it to a different module, or change
its provider.
Usually that's fine: Terraform will destroy the old resource, replace it with a
new one (using the new resource address), and update any resources that rely on
its attributes.
In cases where it's important to preserve an existing infrastructure object, you
can explicitly tell Terraform to associate it with a different configured
resource.
For most cases we recommend using
[the Terraform language's refactoring features](/terraform/language/modules/develop/refactoring)
to document in your module exactly how the resource names have changed over
time. Terraform reacts to this information automatically during planning, so users of your module do not need to take any unusual extra steps.
> **Hands On:** Try the [Use Configuration to Move Resources](/terraform/tutorials/configuration-language/move-config) tutorial.
There are some other situations which require explicit state modifications,
though. For those, consider the following Terraform commands:
- [The `terraform state mv` command](/terraform/cli/commands/state/mv) changes
which resource address in your configuration is associated with a particular
real-world object. Use this to preserve an object when renaming a resource, or
when moving a resource into or out of a child module.
- [The `terraform state rm` command](/terraform/cli/commands/state/rm) tells
Terraform to stop managing a resource as part of the current working directory
and workspace, _without_ destroying the corresponding real-world object. (You
can later use `terraform import` to start managing that resource in a
different workspace or a different Terraform configuration.)
- [The `terraform state replace-provider` command](/terraform/cli/commands/state/replace-provider)
transfers existing resources to a new provider without requiring them to be
re-created.

View file

@ -1,25 +0,0 @@
---
page_title: Recover state from backup
description: >-
Learn how to restore state backups and override Terraform state protections to fix state errors with the Terraform CLI.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Recover state from backup overview
This topic provides overview information about recovering Terraform state from a backup after a disaster, such as an accident when performing
other state manipulation actions.
## Workflow
1. **Unlock Terraform**: You may need to unlock Terraform when a `terraform apply` or other process unexpectedly terminates before Terraform can release its lock on the state backend. Unlocking Terraform overrides protectionsthat prevent two processes from modifying state at the same time. We do not recommend unlocking until you determine what caused the lock to get stuck.
Refer to the [`terraform force-unlock` command](/terraform/cli/commands/force-unlock) documentation for additional information.
1. **Read state data**: Run the [`terraform state pull` command](/terraform/cli/commands/state/pull) to read the state files from the configured backend.
1. **Write state data**: Run the [`terraform state push` command](/terraform/cli/commands/state/push) to write state files to the configured backend.

View file

@ -1,144 +0,0 @@
---
page_title: Resource address reference
description: Use the resource address to reference specific instances of resources elsewhere in the configuration. Learn how Terraform creates addresses for resources.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Resource Address Reference
This topic provides reference information about resource addresses in Terraform.
## Syntax
A _resource address_ is a string that identifies zero or more resource
instances in your overall configuration.
An address is made up of two parts:
```
[module path][resource spec]
```
In some contexts Terraform might allow for an incomplete resource address that
only refers to a module as a whole, or that omits the index for a
multi-instance resource. In those cases, the meaning depends on the context,
so you'll need to refer to the documentation for the specific feature you
are using which parses resource addresses.
## Module path
A module path addresses a module within the tree of modules. It takes the form:
```
module.module_name[module index]
```
- `module` - Module keyword indicating a child module (non-root). Multiple `module`
keywords in a path indicate nesting.
- `module_name` - User-defined name of the module.
- `[module index]` - (Optional) [Index](#index-values-for-modules-and-resources)
to select an instance from a module call that has multiple instances,
surrounded by square bracket characters (`[` and `]`).
An address without a resource spec, i.e. `module.foo` applies to every resource within
the module if a single module, or all instances of a module if a module has multiple instances.
To address all resources of a particular module instance, include the module index in the address,
such as `module.foo[0]`.
If the module path is omitted, the address applies to the root module.
An example of the `module` keyword delineating between two modules that have multiple instances:
```
module.foo[0].module.bar["a"]
```
-> Module index only applies to modules in Terraform v0.13 or later. In earlier
versions of Terraform, a module could not have multiple instances.
## Resource spec
A resource spec addresses a specific resource instance in the selected module.
It has the following syntax:
```
resource_type.resource_name[instance index]
```
- `resource_type` - Type of the resource being addressed.
- `resource_name` - User-defined name of the resource.
- `[instance index]` - (Optional) [Index](#index-values-for-modules-and-resources)
to select an instance from a resource that has multiple instances,
surrounded by square bracket characters (`[` and `]`).
-> In Terraform v0.12 and later, a resource spec without a module path prefix
matches only resources in the root module. In earlier versions, a resource spec
without a module path prefix would match resources with the same type and name
in any descendant module.
## Index values for Modules and Resources
The following specifications apply to index values on modules and resources with multiple instances:
- `[N]` where `N` is a `0`-based numerical index into a resource with multiple
instances specified by the `count` meta-argument. Omitting an index when
addressing a resource where `count > 1` means that the address references
all instances.
- `["INDEX"]` where `INDEX` is a alphanumerical key index into a resource with
multiple instances specified by the `for_each` meta-argument.
## Examples
### count Example
Given a Terraform config that includes:
```hcl
resource "aws_instance" "web" {
# ...
count = 4
}
```
An address like this:
```
aws_instance.web[3]
```
Refers to only the last instance in the config, and an address like this:
```
aws_instance.web
```
Refers to all four "web" instances.
### for_each Example
Given a Terraform config that includes:
```hcl
resource "aws_instance" "web" {
# ...
for_each = tomap({
"terraform": "value1",
"resource": "value2",
"indexing": "value3",
"example": "value4",
})
}
```
An address like this:
```
aws_instance.web["example"]
```
Refers to only the "example" instance in the config, and resolves to "value4".

View file

@ -1,70 +0,0 @@
---
page_title: Recreate resources
description: The -replace flag and taint command help you replace infrastructure objects. Learn how the -replace flag and taint command can help you recreate resources.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Recreate resources overview
This topic provides an overview of how to recreate resources in Terraform.
## Introduction
By default, Terraform retrieves the latest state of each existing object and compares it with the current configuration when you run the `terraform apply` command. Terraform only takes action on objects that do not match the configuration.
When remote objects become damaged or degraded, such as when software
running inside a virtual machine crashes but the virtual machine is
still running, Terraform does not have no way to detect and respond
to the problem. This is because Terraform only directly manages the machine as a whole.
In some cases, Terraform can automatically infer that an object is in an
incomplete or degraded state. For example, when a complex object is partially created in the remote system or
when a provisioner step failed. When this occurs, Terraform automatically flags resources to recreate.
You can manually replace objects when Terraform is unable to infer that an object should be replaced.
## Workflows
When you meed to replace an object, you can use the following methods.
### Manually replace resources
Add the [`-replace` flag](/terraform/cli/commands/plan#replace-address)
to your `terraform plan` or `terraform apply` command:
```shellsession
$ terraform apply -replace="aws_instance.example"
# ...
# aws_instance.example will be replaced, as requested
-/+ resource "aws_instance" "example" {
# ...
}
```
### Replace resource in `tainted` state
Terraform applies the `tainted` status to objects in the state data when Terraform is able to infer that the object is in a degraded or damaged state. This status indicates that the object exists but may not be fully-functional. Terraform replaces objects in a `tainted` states during the next `plan` or `apply` operation.
```
# aws_instance.example is tainted, so must be replaced
-/+ resource "aws_instance" "example" {
# ...
}
```
If Terraform has marked an object as tainted but you consider it to be working
correctly and do not want to replace it, you can override Terraform's
determination using [the `terraform untaint` command](/terraform/cli/commands/untaint),
after which Terraform will consider the object to be ready for use by any
downstream resource declarations.
You can force Terraform to mark a particular object as tainted using
[the `terraform taint` command](/terraform/cli/commands/taint), but that approach is
deprecated in favor of the `-replace=...` option, which avoids the need to
create an interim state snapshot with a tainted object.

View file

@ -1,60 +0,0 @@
---
page_title: Testing features in Terraform
description: >-
Learn about the terraform test command, which runs structured tests and validations for your configuration to ensure
correctness in your infrastructure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Testing features in Terraform overview
This topic provides an overview of the testing features in Terraform to help you validate your infrastructure.
## Introduction
Terraform provides the following types of testing capabilities:
1. Configuration and infrastructure validation as part of your regular Terraform operations. Refer to [Custom Conditions](/terraform/language/expressions/custom-conditions) and [Checks](/terraform/language/checks) to learn more about these types of testing capabilities.
1. Traditional unit and integration testing on your configuration. Refer to the [`terraform test` command](/terraform/cli/commands/test) documentation to learn more about this testing capability.
### Additional testing and validation features
- [Input Variable Validation](/terraform/language/expressions/custom-conditions#input-variable-validation)
- [Pre and Post-conditions](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions)
- [Checks](/terraform/language/checks)
## How the `terraform test` command works
The `test` command performs the following actions:
- Locates Terraform testing files within your configuration directory.
- Provisions the infrastructure within your configuration as specified by each testing file.
- Runs the assertions from the test file against the provisioned infrastructure.
- Destroys the provisioned infrastructure at the end of the test.
For details about using the `test` command, refer to the [`test` command reference documentation](/terraform/cli/commands/test).
### Write configuration for tests
Terraform test files [have their own configuration syntax](/terraform/language/tests). This test file syntax focuses on customizing Terraform executions for the current configuration and overriding variables and providers to test different behaviors.
## Validations
Validations allow you to verify aspects of your configuration and infrastructure as it is applied and created. HCP Terraform also supports automated [continuous validation](/terraform/cloud-docs/workspaces/health#continuous-validation).
The Terraform `test` command also executes any validations within your configuration as part of the tests it executes. For more information on the available validation, refer to [Checks](/terraform/language/checks) and [Custom Conditions](/terraform/language/expressions/custom-conditions).
## Tests versus validations
You can write many validations as test assertions, but there are specific use cases for both.
Validations are executed during Terraform plan and apply operations, and the Terraform `test` command also runs validations while executing tests. Therefore, use validations to validate aspects of your configuration that should always be true and could impact the valid execution of your infrastructure.
Module authors should note that validations are executed and exposed to module users, so if they fail, ensure the failure messages are understandable and actionable.
In contrast, Terraform only executes tests when you run `terraform test`. Use tests to assert the correctness of any logical operations or specific behavior within your configuration. For example, you can test that Terraform creates conditional resources based on an input by setting the input controlling those resources to a certain value then verifying the resources Terraform creates.

View file

@ -1,91 +0,0 @@
---
page_title: Manage workspaces
description: >-
Workspaces are separate instances of Terraform state data. Learn commands for managing workspaces.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Manage Workspaces Overview
Workspaces in the Terraform CLI refer to separate instances of [state data](/terraform/language/state) inside the same Terraform working directory. They are distinctly different from [workspaces in HCP Terraform](/terraform/cloud-docs/workspaces), which each have their own Terraform configuration and function as separate working directories.
Terraform relies on state to associate resources with real-world objects. When you run the same configuration multiple times with separate state data, Terraform can manage multiple sets of non-overlapping resources.
Workspaces can be helpful for specific [use cases](#use-cases), but they are not required to use the Terraform CLI. We recommend using [alternative approaches](#alternatives-to-workspaces) for complex deployments requiring separate credentials and access controls.
## Managing CLI Workspaces
Every [initialized working directory](/terraform/cli/init) starts with one workspace named `default`.
Use the [`terraform workspace list`](/terraform/cli/commands/workspace/list), [`terraform workspace new`](/terraform/cli/commands/workspace/new), and [`terraform workspace delete`](/terraform/cli/commands/workspace/delete) commands to manage the available workspaces in the current working directory.
Use [the `terraform workspace select` command](/terraform/cli/commands/workspace/select) to change the currently selected workspace. For a given working directory, you can only select one workspace at a time. Most Terraform commands only interact with the currently selected workspace. This includes [provisioning](/terraform/cli/run) and [state manipulation](/terraform/cli/state).
When you provision infrastructure in each workspace, you usually need to manually specify different [input variables](/terraform/language/values/variables) to differentiate each collection. For example, you might deploy test infrastructure to a different region.
## Use Cases
You can create multiple [working directories](/terraform/cli/init) to maintain multiple instances of a configuration with completely separate state data. However, Terraform installs a separate cache of plugins and modules for each working directory, so maintaining multiple directories can waste bandwidth and disk space. This approach also requires extra tasks like updating configuration from version control for each directory separately and reinitializing each directory when you change the configuration. Workspaces are convenient because they let you create different sets of infrastructure with the same working copy of your configuration and the same plugin and module caches.
A common use for multiple workspaces is to create a parallel, distinct copy of
a set of infrastructure to test a set of changes before modifying production infrastructure.
Non-default workspaces are often related to feature branches in version control.
The default workspace might correspond to the `main` or `trunk` branch, which describes the intended state of production infrastructure. When a developer creates a feature branch for a change, they might also create a corresponding workspace and deploy into it a temporary copy of the main infrastructure. They can then test changes on the copy without affecting the production infrastructure. Once the change is merged and deployed to the default workspace, they destroy the test infrastructure and delete the temporary workspace.
### When Not to Use Multiple Workspaces
Workspaces let you quickly switch between multiple instances of a **single configuration** within its **single backend**. They are not designed to solve all problems.
When using Terraform to manage larger systems, you should create separate Terraform configurations that correspond to architectural boundaries within the system. This lets teams manage different components separately. Workspaces alone are not a suitable tool for system decomposition because each subsystem should have its own separate configuration and backend.
In particular, organizations commonly want to create a strong separation
between multiple deployments of the same infrastructure serving different
development stages or different internal teams. In this case, the backend for each deployment often has different credentials and access controls. CLI workspaces within a working directory use the same backend, so they are not a suitable isolation mechanism for this scenario.
## Alternatives to Workspaces
Instead of creating CLI workspaces, you can use one or more [re-usable modules](/terraform/language/modules/develop) to represent the common elements and then represent each instance as a separate configuration that instantiates those common elements in the context of a different [backend](/terraform/language/backend). The root module of each configuration consists only of a backend configuration and a small number of `module` blocks with arguments describing any small differences between the deployments.
When multiple configurations represent distinct system components rather than multiple deployments, you can pass data from one component to another using paired resources types and data sources.
- When a shared [Consul](https://www.consul.io/) cluster is available, use [`consul_key_prefix`](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/resources/key_prefix) to publish to the key/value store and [`consul_keys`](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/data-sources/keys) to retrieve those values in other configurations.
- In systems that support user-defined labels or tags, use a tagging convention to make resources automatically discoverable. For example, use [the `aws_vpc` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc) to assign suitable tags and then [the `aws_vpc` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) to query by those tags in other configurations.
- For server addresses, use a provider-specific resource to create a DNS record with a predictable name. Then you can either use that name directly or use [the `dns` provider](https://registry.terraform.io/providers/hashicorp/dns/latest/docs) to retrieve the published addresses in other configurations.
- If you store a Terraform state for one configuration in a remote backend that other configurations can access, then the other configurations can use [`terraform_remote_state`](/terraform/language/state/remote-state-data) to directly consume its root module outputs. This setup creates a tighter coupling between configurations, and the root configuration does not need to publish its results in a separate system.
## Interactions with HCP Terraform Workspaces
HCP Terraform organizes infrastructure using workspaces, but its workspaces
act more like completely separate working directories. Each HCP Terraform
workspace has its own Terraform configuration, set of variable values, state
data, run history, and settings.
When you [integrate Terraform CLI with HCP Terraform](/terraform/cli/cloud), you can associate the current CLI working directory with one or more remote HCP Terraform workspaces. Then, use the `terraform workspace` commands to select the remote workspace you want to use for each run.
Refer to [CLI-driven Runs](/terraform/cloud-docs/run/cli) in the HCP Terraform documentation for more details.
## Workspace Internals
Workspaces are technically equivalent to renaming your state file. Terraform then includes a set of protections and support for remote state.
Workspaces are also meant to be a shared resource. They are not private, unless you use purely local state and do not commit your state to version control.
For local state, Terraform stores the workspace states in a directory called `terraform.tfstate.d`. This directory should be treated similarly to local-only `terraform.tfstate`. Some teams commit these files to version control, but we recommend using a remote backend instead when there are multiple collaborators.
For [remote state](/terraform/language/state/remote), the workspaces are stored directly in the configured [backend](/terraform/language/backend). For example, if you use [Consul](/terraform/language/backend/consul), the workspaces are stored by appending the workspace name to the state path. To ensure that workspace names are stored correctly and safely in all backends, the name must be valid to use in a URL path segment without escaping.
Terraform stores the current workspace name locally in the ignored `.terraform` directory. This allows multiple team members to work on different workspaces concurrently. Workspace names are also attached to associated remote workspaces in HCP Terraform. For more details about workspace names in HCP Terraform, refer to the [CLI Integration (recommended)](/terraform/cli/cloud/settings#arguments) and [remote backend](/terraform/language/backend/remote#workspaces) and documentation.

View file

@ -1,34 +0,0 @@
---
page_title: Archiving Providers
description: >-
Terraform is built on a plugin-based architecture, much of which is maintained
by our user community. Occasionally, unmaintained providers may archived to
reduce confusion for users and developers.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
<!--
This page is not in the Terraform documentation intentionally. Only link it from the README files of archived providers.
-->
# Archiving Providers
As contributors' circumstances change, development on a community-maintained Terraform provider can slow. When this happens, HashiCorp may use GitHub's "archiving" feature on the provider's repository, to clearly signal the provider's status to users.
What does archiving mean?
1. The code repository and all commit, issue, and PR history will still be available.
1. Existing released binaries will remain available on the releases site.
1. Documentation for the provider will remain on the Terraform website.
1. Issues and pull requests are not being monitored, merged, or added.
1. No new releases will be published.
1. Nightly acceptance tests may not be run.
HashiCorp may archive a provider when we or the community are not able to support it at a level consistent with our guidelines and community expectations.
Archiving is reversible. If anyone from the community is willing to maintain an archived provider, please reach out to the [Terraform Provider Development Program](/terraform/docs/partnerships) at _<terraform-registry@hashicorp.com>_.

View file

@ -1,181 +0,0 @@
---
page_title: Create Credentials Helpers
description: >-
Credentials helpers are external programs that can store and retrieve
API tokens for remote Terraform services. Learn how to create credentials helpers.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Create Credentials Helpers
This topic describes how to write and install a credentials helper so that you can customize how Terraform obtains credentials. To learn
how to configure a credentials helper that was already installed, refer to
[Credentials Helpers](/terraform/cli/config/config-file#credentials-helpers) in the Terraform CLI documentation.
## Introduction
For Terraform-specific features that interact with remote network services,
such as [module registries](/terraform/registry) and
[remote operations](/terraform/cloud-docs/run/cli), Terraform by default looks for
API credentials to use in these calls in
[the CLI configuration](/terraform/cli/config/config-file).
Credentials helpers offer an alternative approach that allows you to customize
how Terraform obtains credentials using an external program, which can then
directly access an existing secrets management system in your organization.
## How Terraform finds Credentials Helpers
A credentials helper is a normal executable program that is installed in a
particular location and whose name follows a specific naming convention.
A credentials helper called "credstore", for example, would be implemented as
an executable program named `terraform-credentials-credstore` (with an `.exe`
extension on Windows only), and installed in one of the
[default plugin search locations](/terraform/plugin/how-terraform-works#plugin-locations).
## How Terraform runs Credentials Helpers
Once Terraform has located the configured credentials helper, it will execute
it once for each credentials request that cannot be satisfied by a `credentials`
block in the CLI configuration.
For the following examples, we'll assume a "credstore" credentials helper
configured as follows:
```hcl
credentials_helper "credstore" {
args = ["--host=credstore.example.com"]
}
```
Terraform runs the helper program with each of the arguments given in `args`,
followed by an _verb_ and then the hostname that the verb will apply to.
The current set of verbs are:
* `get`: retrieve the credentials for the given hostname
* `store`: store new credentials for the given hostname
* `forget`: delete any stored credentials for the given hostname
To represent credentials, the credentials helper protocol uses a JSON object
whose contents correspond with the contents of
[`credentials` blocks in the CLI configuration](/terraform/cli/config/config-file#credentials).
To represent an API token, the object contains a property called "token" whose
value is the token string:
```json
{
"token": "example-token-value"
}
```
The following sections describe the specific expected behaviors for each of the
three verbs.
## `get`: retrieve the credentials for the given hostname
To retrieve credentials for `app.terraform.io`, Terraform would run the
"credstore" helper as follows:
```
terraform-credentials-credstore --host=credstore.example.com get app.terraform.io
```
If the credentials helper is able to provide credentials for the given host
then it must print a JSON credentials object to its stdout stream and then
exit with status code zero to indicate success.
If the credentials helper definitively has no credentials for the given host,
then it must print an empty JSON object to stdout and exit with status zero.
If the credentials helper is unable to provide the requested credentials for
any other reason, it must print an end-user-oriented plain text error message
to its stderr stream and then exit with a _non-zero_ status code.
## `store`: store new credentials for the given hostname
To store new credentials for `app.terraform.io`, Terraform would run the
"credstore" helper as follows:
```
terraform-credentials-credstore --host=credstore.example.com store app.terraform.io
```
Terraform then writes a JSON credentials object to the helper program's stdin
stream. If the helper is able to store the given credentials then it must do
so and then exit with status code zero and no output on stdout or stderr to
indicate success.
If it is unable to store the given credentials for any reason, it _must_ still
fully read its stdin until EOF and then print an end-user-oriented plain text
error message to its stderr stream before exiting with a non-zero status
code.
The new credentials must fully replace any existing credentials stored for the
given hostname.
## `forget`: delete any stored credentials for the given hostname
To forget any existing credentials for `app.terraform.io`, Terraform would run
the "credstore" helper as follows:
```
terraform-credentials-credstore --host=credstore.example.com forget app.terraform.io
```
No JSON credentials objects are used for the `forget` verb.
If the helper program is able to delete its stored credentials for the given
hostname or if there are no such credentials stored already then it must
exist with status code zero and produce no output on stdout or stderr.
If it is unable to forget the stored credentials for any reason, particularly
if the helper cannot be sure that the credentials are no longer available for
retrieval, the helper program must print an end-user-oriented plain text error
message to its stderr stream and then exit with a non-zero status code.
## Handling Other Commands
The credentials helper protocol may be extended with additional verbs in future,
so for forward-compatibility a credentials helper must react to any unsupported
verb by printing an end-user-oriented plain text error message to its stderr
stream and then exiting with a non-zero status code.
## Handling Unsupported Credentials Object Properties
Terraform defines only the `token` property within JSON credentials
objects.
If a credentials helper is asked to store an object that has any properties
other than `token` and if it is not able to faithfully retain them then it
must behave as if the object is unstorable, returning an error. It must _not_
store the `token` value in isolation and silently drop other properties, as
that might change the meaning of the credentials object.
If technically possible within the constraints of the target system, a
credentials helper should prefer to store the whole JSON object as-is for
later retrieval. For systems that are more constrained, it's acceptable to
store only the `token` string so long as the program rejects objects containing
other properties as described above.
## Installing a Credentials Helper
Terraform does not have any automatic installation mechanism for credentials
helpers. Instead, the user must extract the helper program executable into
one of the [default plugin search locations](/terraform/plugin/how-terraform-works#plugin-locations).
If you are packaging a credentials helper for distribution, place it in an
named with the expected naming scheme (`terraform-credentials-example`) and,
if the containing archive format supports it and it's meaningful for the
target operating system, mark the file as executable to increase the chances
that it will work immediately after extraction.
Terraform does _not_ honor the `-plugin-dir` argument to `terraform init` when
searching for credentials helpers, because credentials are also used by other
commands that can be run prior to `terraform init`. Only the default search
locations are supported.

View file

@ -1,37 +0,0 @@
---
page_title: Enable logs to debug Terraform
description: >-
Enable Terraform to generate logs so that you can debug unexpected behaviors.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Enable Terraform logs
This topic describes how to enable Terraform logs so that you can debug unexpected behaviors.
> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/troubleshooting-workflow#bug-reporting-best-practices?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial.
## Set the `TF_LOG` variable
Terraform has detailed logs that you can enable by setting the `TF_LOG` environment variable to any value. Enabling this setting causes detailed logs to appear on `stderr`.
You can set `TF_LOG` to one of the log levels (in order of decreasing verbosity) `TRACE`, `DEBUG`, `INFO`, `WARN` or `ERROR` to change the verbosity of the logs.
Setting `TF_LOG` to `JSON` outputs logs at the `TRACE` level or higher, and uses a parseable JSON encoding as the formatting.
~> **Warning:** The JSON encoding of log files is not considered a stable interface. It may change at any time, without warning. It is meant to support tooling that will be forthcoming, and that tooling is the only supported way to interact with JSON formatted logs.
## Set the `TF_LOG_CORE` variable
Logging can be enabled separately for Terraform itself and the provider plugins
using the `TF_LOG_CORE` or `TF_LOG_PROVIDER` environment variables. These take
the same level arguments as `TF_LOG`, but only activate a subset of the logs.
To persist logged output you can set `TF_LOG_PATH` in order to force the log to always be appended to a specific file when logging is enabled. Note that even when `TF_LOG_PATH` is set, `TF_LOG` must be set in order for any logging to be enabled.
If you find a bug with Terraform, please include the detailed log by using a service such as gist.

View file

@ -1,107 +0,0 @@
---
page_title: terraform metadata functions command reference
description: >-
The `terraform metadata functions` command prints signatures for all the
functions available in the current Terraform version.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# `terraform metadata functions` command
The `terraform metadata functions` command prints signatures for the functions available in the current Terraform version.
-> `terraform metadata functions` requires **Terraform v1.4 or later**.
## Usage
Usage: `terraform metadata functions [options]`
The following flags are available:
- `-json` - Displays the function signatures in a machine-readable, JSON format.
Please note that, at this time, the `-json` flag is a _required_ option. In future releases, this command will be extended to allow for additional options.
The output includes a `format_version` key, which as of Terraform 1.4.0 has
value `"1.0"`. The semantics of this version are:
- We will increment the minor version, e.g. `"1.1"`, for backward-compatible
changes or additions. Ignore any object properties with unrecognized names to
remain forward-compatible with future minor versions.
- We will increment the major version, e.g. `"2.0"`, for changes that are not
backward-compatible. Reject any input which reports an unsupported major
version.
We will introduce new major versions only within the bounds of
[the Terraform 1.0 Compatibility Promises](/terraform/language/v1-compatibility-promises).
## Format Summary
The following sections describe the JSON output format by example, using a pseudo-JSON notation.
Important elements are described with comments, which are prefixed with `//`.
To avoid excessive repetition, we've split the complete format into several discrete sub-objects, described under separate headers. References wrapped in angle brackets (like `<block-representation>`) are placeholders which, in the real output, would be replaced by an instance of the specified sub-object.
The JSON output format consists of the following objects and sub-objects:
- [Function Signature Representation](#function-signature-representation) - the top-level object returned by `terraform metadata functions -json`
- [Parameter Representation](#parameter-representation) - a sub-object of signatures that describes their parameters
## Function Signature Representation
```javascript
{
"format_version": "1.0",
// "function_signatures" describes the signatures for all
// available functions.
"function_signatures": {
// keys in this map are the function names, such as "abs"
"example_function": {
// "description" is an English-language description of
// the purpose and usage of the function in Markdown.
"description": "string",
// "return_type" is a representation of a type specification
// that the function returns.
"return_type": "string",
// "parameters" is an optional list of the positional parameters
// that the function accepts.
"parameters": [
<parameter-representation>,
],
// "variadic_parameter" is an optional representation of the
// additional arguments that the function accepts after those
// matching with the fixed parameters.
"variadic_parameter": <parameter-representation>
},
"example_function_two": { … }
}
}
```
## Parameter Representation
A parameter representation describes a parameter to a function.
```javascript
{
// "name" is the internal name of the parameter
"name": "string",
// "description" is an optional English-language description of
// the purpose and usage of the parameter in Markdown.
"description": "string",
// "type" is a representation of a type specification
// that the parameter's value must conform to.
"type": "string"
}
```

View file

@ -1,115 +0,0 @@
---
page_title: Dependency Graph
description: >-
Learn how Terraform builds a dependency graph from the Terraform configurations and
uses the graph to generate plans, refresh state, perform other operations.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Dependency Graph
This topic explains the dependency graph Terraform builds from Terraform configurations. This is an advanced topic and not required to understand how to use Terraform.
## Introduction
Terraform builds a dependency graph and uses it to perform operations, such as generate plans and refresh state.
For background on graph theory and a summary of how
Terraform applies it, refer the HashiCorp 2016 presentation
[_Applying Graph Theory to Infrastructure as Code_](https://www.youtube.com/watch?v=Ce3RNfRbdZ0).
## Graph Nodes
The following node types can exist within the graph:
- **Resource Node** - Represents a single resource. If you have
the `count` metaparameter set, then there will be one resource
node for each count. The configuration, diff, state, etc. of
the resource under change is attached to this node.
- **Provider Configuration Node** - Represents the time to fully
configure a provider. This is when the provider configuration
block is given to a provider, such as AWS security credentials.
- **Resource Meta-Node** - Represents a group of resources, but
does not represent any action on its own. This is done for
convenience on dependencies and making a prettier graph. This
node is only present for resources that have a `count`
parameter greater than 1.
When visualizing a configuration with `terraform graph`, you can
see all of these nodes present.
## Building the Graph
Building the graph is done in a series of sequential steps:
1. Resources nodes are added based on the configuration. If a
diff (plan) or state is present, that meta-data is attached
to each resource node.
1. Resources are mapped to provisioners if they have any
defined. This must be done after all resource nodes are
created so resources with the same provisioner type can
share the provisioner implementation.
1. Explicit dependencies from the `depends_on` meta-parameter
are used to create edges between resources.
1. If a state is present, any "orphan" resources are added to
the graph. Orphan resources are any resources that are no
longer present in the configuration but are present in the
state file. Orphans never have any configuration associated
with them, since the state file does not store configuration.
1. Resources are mapped to providers. Provider configuration
nodes are created for these providers, and edges are created
such that the resources depend on their respective provider
being configured.
1. Interpolations are parsed in resource and provider configurations
to determine dependencies. References to resource attributes
are turned into dependencies from the resource with the interpolation
to the resource being referenced.
1. Create a root node. The root node points to all resources and
is created so there is a single root to the dependency graph. When
traversing the graph, the root node is ignored.
1. If a diff is present, traverse all resource nodes and find resources
that are being destroyed. These resource nodes are split into two:
one node that destroys the resource and another that creates
the resource (if it is being recreated). The reason the nodes must
be split is because the destroy order is often different from the
create order, and so they can't be represented by a single graph
node.
1. Validate the graph has no cycles and has a single root.
## Walking the Graph
<a id="walking-the-graph"></a>
To walk the graph, a standard depth-first traversal is done. Graph
walking is done in parallel: a node is walked as soon as all of its
dependencies are walked.
The amount of parallelism is limited using a semaphore to prevent too many
concurrent operations from overwhelming the resources of the machine running
Terraform. By default, up to 10 nodes in the graph will be processed
concurrently. This number can be set using the `-parallelism` flag on the
[plan](/terraform/cli/commands/plan), [apply](/terraform/cli/commands/apply), and
[destroy](/terraform/cli/commands/destroy) commands.
Setting `-parallelism` is considered an advanced operation and should not be
necessary for normal usage of Terraform. It may be helpful in certain special
use cases or to help debug Terraform issues.
Note that some providers (AWS, for example), handle API rate limiting issues at
a lower level by implementing graceful backoff/retry in their respective API
clients. For this reason, Terraform does not use this `parallelism` feature to
address API rate limits directly.

View file

@ -1,17 +0,0 @@
---
page_title: Terraform internals
description: >-
Learn about internal Terraform processes, such as generating the resource dependency graph.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Terraform internals overview
This topic provides overview information about the internals of Terraform.
Topics in this section explain how Terraform generates plans and describe the provider lifecycle.
You do not have to understand Terraform internals to use Terraform.

View file

@ -1,778 +0,0 @@
---
page_title: JSON output format
description: >-
Learn how to configure Terraform to print JSON-formatted details about state, configuration, and proposed infrastructure plans.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# JSON Output Format Overview
This topic provides overview information about the JSON output Terraform prints to the terminal.
## Introduction
When Terraform plans to make changes, it prints a human-readable summary to the terminal. It can also, when run with `-out=<PATH>`, write a much more detailed binary plan file, which can later be used to apply those changes.
Terraform can output a machine-readable JSON representation of a plan file's changes. It can also convert state files to the same format, to simplify data loading and provide better long-term compatibility.
Use `terraform show -json <FILE>` to generate a JSON representation of a plan or state file. See [the `terraform show` documentation](/terraform/cli/commands/show) for more details.
The output includes a `format_version` key, which as of Terraform 1.1.0 has
value `"1.0"`. The semantics of this version are:
- We will increment the minor version, e.g. `"1.1"`, for backward-compatible
changes or additions. Ignore any object properties with unrecognized names to
remain forward-compatible with future minor versions.
- We will increment the major version, e.g. `"2.0"`, for changes that are not
backward-compatible. Reject any input which reports an unsupported major
version.
## Format Summary
The following sections describe the JSON output format by example, using a pseudo-JSON notation.
Important elements are described with comments, which are prefixed with `//`.
To avoid excessive repetition, we've split the complete format into several discrete sub-objects, described under separate headers. References wrapped in angle brackets (like `<values-representation>`) are placeholders which, in the real output, would be replaced by an instance of the specified sub-object.
The JSON output format consists of the following objects and sub-objects:
- [State Representation](#state-representation) — The complete top-level object returned by `terraform show -json <STATE FILE>`.
- [Plan Representation](#plan-representation) — The complete top-level object returned by `terraform show -json <PLAN FILE>`.
- [Values Representation](#values-representation) — A sub-object of both plan and state output that describes current state or planned state.
- [Configuration Representation](#configuration-representation) — A sub-object of plan output that describes a parsed Terraform configuration.
- [Expression Representation](#expression-representation) — A sub-object of a configuration representation that describes an unevaluated expression.
- [Block Expressions Representation](#block-expressions-representation) — A sub-object of a configuration representation that describes the expressions nested inside a block.
- [Change Representation](#change-representation) — A sub-object of plan output that describes changes to an object.
- [Checks Representation](#checks-representation) — A property of both the plan and state representations that describes the current status of any checks (e.g. preconditions and postconditions) in the configuration.
## State Representation
State does not have any significant metadata not included in the common [values representation](#values-representation), so the `<state-representation>` uses the following format:
```javascript
{
// "values" is a values representation object derived from the values in the
// state. Because the state is always fully known, this is always complete.
"values": <values-representation>
"terraform_version": "version.string"
}
```
## Plan Representation
A plan consists of a prior state, the configuration that is being applied to that state, and the set of changes Terraform plans to make to achieve that.
For ease of consumption by callers, the plan representation includes a partial representation of the values in the final state (using a [value representation](#values-representation)), allowing callers to easily analyze the planned outcome using similar code as for analyzing the prior state.
```javascript
{
"format_version": "1.0",
// "prior_state" is a representation of the state that the configuration is
// being applied to, using the state representation described above.
"prior_state": <state-representation>,
// "applyable" indicates that it would make sense for a wrapping automation
// to try to apply this plan, possibly after asking a human operator for
// approval.
//
// Other attributes may give additional context about why the plan is not
// applyable, but wrapping automations should use this flag as their
// primary condition to accommodate potential changes to the exact definition
// of "applyable" in future Terraform versions.
"applyable": true,
// "complete" indicates that Terraform expects that after applying this
// plan the actual state will match the desired state.
//
// An incomplete plan is expected to require at least one additional
// plan/apply round to achieve convergence, and so wrapping automations
// should ideally either automatically start a new plan/apply round after
// this plan is applied, or prompt the operator that they should do so.
//
// Other attributes may give additional context about why the plan is not
// complete, but wrapping automations should use this flag as their
// primary condition to accommodate potential changes to the exact definition
// of "complete" in future Terraform versions.
"complete": true,
// "errored" indicates whether planning failed. An errored plan cannot be applied,
// but the actions planned before failure may help to understand the error.
"errored": false,
// "configuration" is a representation of the configuration being applied to the
// prior state, using the configuration representation described above.
"configuration": <configuration-representation>,
// "planned_values" is a description of what is known so far of the outcome in
// the standard value representation, with any as-yet-unknown values omitted.
"planned_values": <values-representation>,
// "proposed_unknown" is a representation of the attributes, including any
// potentially-unknown attributes. Each value is replaced with "true" or
// "false" depending on whether it is known in the proposed plan.
"proposed_unknown": <values-representation>,
// "variables" is a representation of all the variables provided for the given
// plan. This is structured as a map similar to the output map so we can add
// additional fields in later.
"variables": {
"varname": {
"value": "varvalue"
},
},
// "resource_changes" is a description of the individual change actions that
// Terraform plans to use to move from the prior state to a new state
// matching the configuration.
"resource_changes": [
// Each element of this array describes the action to take
// for one instance object. All resources in the
// configuration are included in this list.
{
// "address" is the full absolute address of the resource instance this
// change applies to, in the same format as addresses in a value
// representation.
"address": "module.child.aws_instance.foo[0]",
// "previous_address" is the full absolute address of this resource
// instance as it was known after the previous Terraform run.
// Included only if the address has changed, e.g. by handling
// a "moved" block in the configuration.
"previous_address": "module.instances.aws_instance.foo[0]",
// "module_address", if set, is the module portion of the above address.
// Omitted if the instance is in the root module.
"module_address": "module.child",
// "mode", "type", "name", and "index" have the same meaning as in a
// value representation.
"mode": "managed",
"type": "aws_instance",
"name": "foo",
"index": 0,
// "deposed", if set, indicates that this action applies to a "deposed"
// object of the given instance rather than to its "current" object.
// Omitted for changes to the current object. "address" and "deposed"
// together form a unique key across all change objects in a particular
// plan. The value is an opaque key representing the specific deposed
// object.
"deposed": "deadbeef",
// "change" describes the change that will be made to the indicated
// object. The <change-representation> is detailed in a section below.
"change": <change-representation>,
// "action_reason" is some optional extra context about why the
// actions given inside "change" were selected. This is the JSON
// equivalent of annotations shown in the normal plan output like
// "is tainted, so must be replaced" as opposed to just "must be
// replaced".
//
// These reason codes are display hints only and the set of possible
// hints may change over time. Users of this must be prepared to
// encounter unrecognized reasons and treat them as unspecified reasons.
//
// The current set of possible values is:
// - "replace_because_tainted": the object in question is marked as
// "tainted" in the prior state, so Terraform planned to replace it.
// - "replace_because_cannot_update": the provider indicated that one
// of the requested changes isn't possible without replacing the
// existing object with a new object.
// - "replace_by_request": the user explicitly called for this object
// to be replaced as an option when creating the plan, which therefore
// overrode what would have been a "no-op" or "update" action otherwise.
// - "delete_because_no_resource_config": Terraform found no resource
// configuration corresponding to this instance.
// - "delete_because_no_module": The resource instance belongs to a
// module instance that's no longer declared, perhaps due to changing
// the "count" or "for_each" argument on one of the containing modules.
// - "delete_because_wrong_repetition": The instance key portion of the
// resource address isn't of a suitable type for the corresponding
// resource's configured repetition mode (count, for_each, or neither).
// - "delete_because_count_index": The corresponding resource uses count,
// but the instance key is out of range for the currently-configured
// count value.
// - "delete_because_each_key": The corresponding resource uses for_each,
// but the instance key doesn't match any of the keys in the
// currently-configured for_each value.
// - "read_because_config_unknown": For a data resource, Terraform cannot
// read the data during the plan phase because of values in the
// configuration that won't be known until the apply phase.
// - "read_because_dependency_pending": For a data resource, Terraform
// cannot read the data during the plan phase because the data
// resource depends on at least one managed resource that also has
// a pending change in the same plan.
//
// If there is no special reason to note, Terraform will omit this
// property altogether.
"action_reason": "replace_because_tainted"
}
],
// "resource_drift" is a description of the changes Terraform detected
// when it compared the most recent state to the prior saved state.
"resource_drift": [
{
// "resource_drift" uses the same object structure as
// "resource_changes".
}
],
// "relevant_attributes" lists the sources of all values contributing to
// changes in the plan. You can use "relevant_attributes" to filter
// "resource_drift" and determine which external changes may have affected the
// plan result.
"relevant_attributes": [
{
"resource": "aws_instance.foo",
"attribute": "attr",
}
]
// "output_changes" describes the planned changes to the output values of the
// root module.
"output_changes": {
// Keys are the defined output value names.
"foo": {
// "change" describes the change that will be made to the indicated output
// value, using the same representation as for resource changes except
// that the only valid actions values are:
// ["create"]
// ["update"]
// ["delete"]
// In the Terraform CLI 0.12.0 release, Terraform is not yet fully able to
// track changes to output values, so the actions indicated may not be
// fully accurate, but the "after" value will always be correct.
"change": <change-representation>,
}
},
// "checks" describes the partial results for any checkable objects, such as
// resources with postconditions, with as much information as Terraform can
// recognize at plan time. Some objects will have status "unknown" to
// indicate that their status will only be determined after applying the plan.
"checks" <checks-representation>
}
```
This overall plan structure, fully expanded, is what will be printed by the `terraform show -json <planfile>` command.
## Values Representation
A values representation is used in both state and plan output to describe current state (which is always complete) and planned state (which omits values not known until apply).
The following example illustrates the structure of a `<values-representation>`:
```javascript
{
// "outputs" describes the outputs from the root module. Outputs from
// descendant modules are not available because they are not retained in all
// of the underlying structures we will build this values representation from.
"outputs": {
"private_ip": {
"value": "192.168.3.2",
"type": "string",
"sensitive": false
}
},
// "root_module" describes the resources and child modules in the root module.
"root_module": {
"resources": [
{
// "address" is the absolute resource address, which callers must consider
// opaque but may do full string comparisons with other address strings or
// pass this verbatim to other Terraform commands that are documented to
// accept absolute resource addresses. The module-local portions of this
// address are extracted in other properties below.
"address": "aws_instance.example[1]",
// "mode" can be "managed", for resources, or "data", for data resources
"mode": "managed",
"type": "aws_instance",
"name": "example",
// If the count or for_each meta-arguments are set for this resource, the
// additional key "index" is present to give the instance index key. This
// is omitted for the single instance of a resource that isn't using count
// or for_each.
"index": 1,
// "provider_name" is the name of the provider that is responsible for
// this resource. This is only the provider name, not a provider
// configuration address, and so no module path nor alias will be
// indicated here. This is included to allow the property "type" to be
// interpreted unambiguously in the unusual situation where a provider
// offers a resource type whose name does not start with its own name,
// such as the "googlebeta" provider offering "google_compute_instance".
"provider_name": "aws",
// "schema_version" indicates which version of the resource type schema
// the "values" property conforms to.
"schema_version": 2,
// "values" is the JSON representation of the attribute values of the
// resource, whose structure depends on the resource type schema. Any
// unknown values are omitted or set to null, making them
// indistinguishable from absent values; callers which need to distinguish
// unknown from unset must use the plan-specific or configuration-specific
// structures described in later sections.
"values": {
"id": "i-abc123",
"instance_type": "t2.micro",
// etc, etc
},
// "sensitive_values" is the JSON representation of the sensitivity of
// the resource's attribute values. Only attributes which are sensitive
// are included in this structure.
"sensitive_values": {
"id": true,
}
}
]
"child_modules": [
// Each entry in "child_modules" has the same structure as the root_module
// object, with the additional "address" property shown below.
{
// "address" is the absolute module address, which callers must treat as
// opaque but may do full string comparisons with other module address
// strings and may pass verbatim to other Terraform commands that are
// documented as accepting absolute module addresses.
"address": "module.child",
// "resources" is the same as in "root_module" above
"resources": [
{
"address": "module.child.aws_instance.foo",
// etc, etc
}
],
// Each module object can optionally have its own
// nested "child_modules", recursively describing the
// full module tree.
"child_modules": [ ... ],
}
]
}
}
```
The translation of attribute and output values is the same intuitive mapping from HCL types to JSON types used by Terraform's [`jsonencode`](/terraform/language/functions/jsonencode) function. This mapping does lose some information: lists, sets, and tuples all lower to JSON arrays while maps and objects both lower to JSON objects. Unknown values and null values are both treated as absent or null.
Output values include a `"type"` field, which is a [serialization of the value's type](https://pkg.go.dev/github.com/zclconf/go-cty/cty#Type.MarshalJSON). For primitive types this is a string value, such as `"number"` or `"bool"`. Complex types are represented as a nested JSON array, such as `["map","string"]` or `["object",{"a":"number"}]`. This can be used to reconstruct the output value with the correct type.
Only the "current" object for each resource instance is described. "Deposed" objects are not reflected in this structure at all; in plan representations, you can refer to the change representations for further details.
The intent of this structure is to give a caller access to a similar level of detail as is available to expressions within the configuration itself. This common representation is not suitable for all use-cases because it loses information compared to the data structures it is built from. For more complex needs, use the more elaborate changes and configuration representations.
## Configuration Representation
Configuration is the most complicated structure in Terraform, since it includes unevaluated expression nodes and other complexities.
Because the configuration models are produced at a stage prior to expression evaluation, it is not possible to produce a values representation for configuration. Instead, we describe the physical structure of the configuration, giving access to constant values where possible and allowing callers to analyze any references to other objects that are present:
```javascript
{
// "provider_configs" describes all of the provider configurations throughout
// the configuration tree, flattened into a single map for convenience since
// provider configurations are the one concept in Terraform that can span
// across module boundaries.
"provider_config": {
// Keys in the provider_configs map are to be considered opaque by callers,
// and used just for lookups using the "provider_config_key" property in each
// resource object.
"opaque_provider_ref_aws": {
// "name" is the name of the provider without any alias
"name": "aws",
// "full_name" is the fully-qualified provider name
"full_name": "registry.terraform.io/hashicorp/aws",
// "alias" is the alias set for a non-default configuration, or unset for
// a default configuration.
"alias": "foo",
// "module_address" is included only for provider configurations that are
// declared in a descendant module, and gives the opaque address for the
// module that contains the provider configuration.
"module_address": "module.child",
// "expressions" describes the provider-specific content of the
// configuration block, as a block expressions representation (see section
// below).
"expressions": <block-expressions-representation>
}
},
// "root_module" describes the root module in the configuration, and serves
// as the root of a tree of similar objects describing descendant modules.
"root_module": {
// "outputs" describes the output value configurations in the module.
"outputs": {
// Property names here are the output value names
"example": {
"expression": <expression-representation>,
"sensitive": false
}
},
// "resources" describes the "resource" and "data" blocks in the module
// configuration.
"resources": [
{
// "address" is the opaque absolute address for the resource itself.
"address": "aws_instance.example",
// "mode", "type", and "name" have the same meaning as for the resource
// portion of a value representation.
"mode": "managed",
"type": "aws_instance",
"name": "example",
// "provider_config_key" is the key into "provider_configs" (shown
// above) for the provider configuration that this resource is
// associated with. If the provider configuration was passed into
// this module from the parent module, the key will point to the
// original provider config block.
"provider_config_key": "opaque_provider_ref_aws",
// "provisioners" is an optional field which describes any provisioners.
// Connection info will not be included here.
"provisioners": [
{
"type": "local-exec",
// "expressions" describes the provisioner configuration
"expressions": <block-expressions-representation>
},
],
// "expressions" describes the resource-type-specific content of the
// configuration block.
"expressions": <block-expressions-representation>,
// "schema_version" is the schema version number indicated by the
// provider for the type-specific arguments described in "expressions".
"schema_version": 2,
// "count_expression" and "for_each_expression" describe the expressions
// given for the corresponding meta-arguments in the resource
// configuration block. These are omitted if the corresponding argument
// isn't set.
"count_expression": <expression-representation>,
"for_each_expression": <expression-representation>
},
],
// "module_calls" describes the "module" blocks in the module. During
// evaluation, a module call with count or for_each may expand to multiple
// module instances, but in configuration only the block itself is
// represented.
"module_calls": {
// Key is the module call name chosen in the configuration.
"child": {
// "resolved_source" is the resolved source address of the module, after
// any normalization and expansion. This could be either a
// go-getter-style source address or a local path starting with "./" or
// "../". If the user gave a registry source address then this is the
// final location of the module as returned by the registry, after
// following any redirect indirection.
"resolved_source": "./child"
// "expressions" describes the expressions for the arguments within the
// block that correspond to input variables in the child module.
"expressions": <block-expressions-representation>,
// "count_expression" and "for_each_expression" describe the expressions
// given for the corresponding meta-arguments in the module
// configuration block. These are omitted if the corresponding argument
// isn't set.
"count_expression": <expression-representation>,
"for_each_expression": <expression-representation>,
// "module" is a representation of the configuration of the child module
// itself, using the same structure as the "root_module" object,
// recursively describing the full module tree.
"module": <module-configuration-representation>
}
}
}
}
```
### Expression Representation
Each unevaluated expression in the configuration is represented with an `<expression-representation>` object with the following structure:
```javascript
{
// "constant_value" is set only if the expression contains no references to
// other objects, in which case it gives the resulting constant value. This is
// mapped as for the individual values in a value representation.
"constant_value": "hello",
// Alternatively, "references" will be set to a list of references in the
// expression. Multi-step references will be unwrapped and duplicated for each
// significant traversal step, allowing callers to more easily recognize the
// objects they care about without attempting to parse the expressions.
// Callers should only use string equality checks here, since the syntax may
// be extended in future releases.
"references": [
"data.template_file.foo[1].vars[\"baz\"]",
"data.template_file.foo[1].vars", // implied by previous
"data.template_file.foo[1]", // implied by previous
"data.template_file.foo", // implied by previous
"module.foo.bar",
"module.foo", // implied by the previous
"var.example[0]",
"var.example", // implied by the previous
// Partial references like "data" and "module" are not included, because
// Terraform considers "module.foo" to be an atomic reference, not an
// attribute access.
]
}
```
-> **Note:** Expressions in `dynamic` blocks are not included in the configuration representation.
### Block Expressions Representation
In some cases, it is the entire content of a block (possibly after certain special arguments have already been handled and removed) that must be represented. For that, we have an `<block-expressions-representation>` structure:
```javascript
{
// Attribute arguments are mapped directly with the attribute name as key and
// an <expression-representation> as value.
"ami": <expression-representation>,
"instance_type": <expression-representation>,
// Nested block arguments are mapped as either a single nested
// <block-expressions-representation> or an array object of these, depending on the
// block nesting mode chosen in the schema.
// - "single" nesting is a direct <block-expressions-representation>
// - "list" and "set" produce arrays
// - "map" produces an object
"root_block_device": <expression-representation>,
"ebs_block_device": [
<expression-representation>
]
}
```
For now we expect callers to just hard-code assumptions about the schemas of particular resource types in order to process these expression representations. In a later release we will add new inspection commands to return machine-readable descriptions of the schemas themselves, allowing for more generic handling in programs such as visualization tools.
## Change Representation
A `<change-representation>` describes the change to the indicated object.
```javascript
{
// "actions" are the actions that will be taken on the object selected by the
// properties below.
// Valid actions values are:
// ["no-op"]
// ["create"]
// ["read"]
// ["update"]
// ["delete", "create"]
// ["create", "delete"]
// ["delete"]
// The two "replace" actions are represented in this way to allow callers to
// e.g. just scan the list for "delete" to recognize all three situations
// where the object will be deleted, allowing for any new deletion
// combinations that might be added in future.
"actions": ["update"],
// "before" and "after" are representations of the object value both before
// and after the action. For ["create"] and ["delete"] actions, either
// "before" or "after" is unset (respectively). For ["no-op"], the before and
// after values are identical. The "after" value will be incomplete if there
// are values within it that won't be known until after apply.
"before": <value-representation>,
"after": <value-representation>,
// "after_unknown" is an object value with similar structure to "after", but
// with all unknown leaf values replaced with "true", and all known leaf
// values omitted. This can be combined with "after" to reconstruct a full
// value after the action, including values which will only be known after
// apply.
"after_unknown": {
"id": true
},
// "before_sensitive" and "after_sensitive" are object values with similar
// structure to "before" and "after", but with all sensitive leaf values
// replaced with true, and all non-sensitive leaf values omitted. These
// objects should be combined with "before" and "after" to prevent accidental
// display of sensitive values in user interfaces.
"before_sensitive": {},
"after_sensitive": {
"triggers": {
"boop": true
}
},
// "replace_paths" is an array of arrays representing a set of paths into the
// object value which resulted in the action being "replace". This will be
// omitted if the action is not replace, or if no paths caused the
// replacement (for example, if the resource was tainted). Each path
// consists of one or more steps, each of which will be a number or a
// string.
"replace_paths": [["triggers"]],
// "importing" is present only when the object is being imported as part
// of this change.
"importing": {
// "id" is the import ID of the object being imported.
"id": "foo"
}
}
```
## Checks Representation
~> **Warning:** The JSON representation of checks is experimental
and some details may change in future Terraform versions based on feedback,
even in minor releases of Terraform CLI.
A `<checks-representation>` describes the current state of a checkable object in the configuration. For example, a resource with one or more preconditions or postconditions is an example of a checkable object, and its check state represents the results of those conditions.
```javascript
[
{
// "address" describes the address of the checkable object whose status
// this object is describing.
"address": {
// "kind" specifies what kind of checkable object this is. Different
// kinds of object will have different additional properties inside the
// address object, but all kinds include both "kind" and "to_display".
// The two valid kinds are "resource" and "output_value".
"kind": "resource",
// "to_display" contains an opaque string representation of the address
// of the object that is suitable for display in a UI. For consumers that
// have special handling depending on the value of "kind", this property
// is a good fallback to use when the application doesn't recognize the
// "kind" value.
"to_display": "aws_instance.example",
// "mode" is included for kind "resource" only, and specifies the resource
// mode which can either be "managed" (for "resource" blocks) or "data"
// (for "data" blocks).
"mode": "managed",
// "type" is included for kind "resource" only, and specifies the resource
// type.
"type": "aws_instance",
// "name" is the local name of the object. For a resource this is the
// second label in the resource block header, and for an output value
// this is the single label in the output block header.
"name": "example",
// "module" is included if the object belongs to a module other than
// the root module, and provides an opaque string representation of the
// module this object belongs to. This example is of a root module
// resource and so "module" is not included.
}
// "status" is the aggregate status of all of the instances of the object
// being described by this object.
// The possible values are "pass", "fail", "error", and "unknown".
"status": "fail",
// "instances" describes the current status of each of the instances of
// the object being described. An object can have multiple instances if
// it is either a resource which has "count" or "for_each" set, or if
// it's contained within a module that has "count" or "for_each" set.
//
// If "instances" is empty or omitted, that can either mean that the object
// has no instances at all (e.g. count = 0) or that an error blocked
// evaluation of the repetition argument. You can distinguish these cases
// using the "status" property, which will be "pass" or "error" for a
// zero-instance object and "unknown" for situations where an error blocked
// evalation.
"instances": [
{
// "address" is an object similar to the property of the same name in
// the containing object. Merge the instance-level address into the
// object-level address, overwriting any conflicting property names,
// to create a full description of the instance's address.
"address": {
// "to_display" overrides the property of the same name in the main
// object's address, to include any module instance or resource
// instance keys that uniquely identify this instance.
"to_display": "aws_instance.example[0]",
// "instance_key" is included for resources only and specifies the
// resource-level instance key, which can either be a number or a
// string. Omitted for single-instance resources.
"instance_key": 0,
// "module" is included if the object belongs to a module other than
// the root module, and provides an opaque string representation of the
// module instance this object belongs to.
},
// "status" describes the result of running the configured checks
// against this particular instance of the object, with the same
// possible values as the "status" in the parent object.
//
// "fail" means that the condition evaluated successfully but returned
// false, while "error" means that the condition expression itself
// was invalid.
"status": "fail",
// "problems" might be included for statuses "fail" or "error", in
// which case it describes the individual conditions that failed for
// this instance, if any.
// When a condition expression is invalid, Terraform returns that as
// a normal error message rather than as a problem in this list.
"problems": [
{
// "message" is the string that resulted from evaluating the
// error_message argument of the failing condition.
"message": "Server does not have a public IPv6 address."
}
]
},
]
}
]
```
The "checks" model includes both static checkable objects and instances of
those objects to ensure that the set of checkable objects will be consistent
even if an error prevents full evaluation of the configuration. Any object
in the configuration which has associated checks, such as a resource with
preconditions or postconditions, will always be included as a checkable object
even if a runtime error prevents Terraform from evaluating its "count" or
"for_each" argument and therefore determining which instances of that object
exist dynamically.
When summarizing checks in a UI, we recommend preferring to list only the
individual instances and typically ignoring the top-level objects altogether.
However, in any case where an object has _zero_ instances, the UI should show
the top-level object instead to serve as a placeholder so that the user can
see that Terraform recognized the existence of the checks, even if it wasn't
able to evaluate them on the most recent run.

View file

@ -1,116 +0,0 @@
---
page_title: Login protocol reference
description: >-
The login protocol authenticates Terraform against servers that provide Terraform-native services. Learn about the login protocol.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Login Protocol Reference
This topic provides reference information about the login protocol Terraform uses for authentication against servers that profide Terraform-native services. You can use this reference information to offer Terraform-native services in a third-party system.
## Introduction
The `terraform login` command supports performing an OAuth 2.0 authorization
request using configuration provided by the target host. You may wish to
implement this protocol if you are producing a third-party implementation of
any [Terraform-native services](/terraform/internals/remote-service-discovery),
such as a Terraform module registry.
## OAuth Configuration
Terraform uses [remote service discovery](/terraform/internals/remote-service-discovery) to
find the OAuth configuration for the host. The host must support the service
name `login.v1` and define for it an object containing OAuth client
configuration values. The following example describes a client that authenticates at ports `10000` and `10010`:
```json
{
"login.v1": {
"client": "terraform-cli",
"grant_types": ["authz_code"],
"authz": "/oauth/authorization",
"token": "/oauth/token",
"ports": [10000, 10010],
}
}
```
The properties within the discovery object are as follows:
* `client` (Required): The `client_id` value to use when making requests, as
defined in [RFC 6749 section 2.2](https://tools.ietf.org/html/rfc6749#section-2.2).
Because Terraform is a _public client_ (it is installed on end-user systems
and thus cannot protect an OAuth client secret), the `client_id` is purely
advisory and the server must not use it as a guarantee that an authorization
request is truly coming from Terraform.
* `grant_types` (Optional): A JSON array of strings describing a set of OAuth
2.0 grant types the server is able to support. A "grant type" selects a
specific mechanism by which an OAuth server authenticates the request and
issues an authorization token.
Terraform CLI supports a single grant type:
* `authz_code`: [authorization code grant](https://tools.ietf.org/html/rfc6749#section-4.1).
Both the `authz` and `token` properties are required when `authz_code` is
present.
If not specified, `grant_types` defaults to `["authz_code"]`.
* `authz` (Required if needed for a given grant type): the server's
[authorization endpoint](https://tools.ietf.org/html/rfc6749#section-3.1).
If given as a relative URL, it is resolved from the location of the
service discovery document.
* `token` (Required if needed for a given grant type): the server's
[token endpoint](https://tools.ietf.org/html/rfc6749#section-3.2).
If given as a relative URL, it is resolved from the location of the
service discovery document.
* `ports` (Optional): A two-element JSON array giving an inclusive range of
TCP ports that Terraform may use for the temporary HTTP server it will start
to provide the [redirection endpoint](https://tools.ietf.org/html/rfc6749#section-3.1.2)
for the first step of an authorization code grant. Terraform opens a TCP
listen port on the loopback interface in order to receive the response from
the server's authorization endpoint.
If not specified, Terraform is free to select any TCP port greater than or
equal to 1024.
Terraform allows constraining this port range for interoperability with OAuth
server implementations that require each `client_id` to be associated with
a fixed set of valid redirection endpoint URLs. Configure such a server
to expect a range of URLs of the form `http://localhost:10000/`
with different consecutive port numbers, and then specify that port range
using `ports`.
We recommend allowing at least 10 distinct port numbers if possible, and
assigning them to numbers greater than or equal to 10000, to minimize the
risk that all of the possible ports will already be in use on a particular
system.
When requesting an authorization code grant, Terraform CLI implements the
[Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636) extension in
order to protect against other applications on the system intercepting the
incoming request to the redirection endpoint. We strongly recommend that you
select an OAuth server implementation that also implements this extension and
verifies the code challenge sent to the token endpoint.
Terraform CLI does not support OAuth refresh tokens or token expiration. If your
server issues time-limited tokens, Terraform CLI will simply begin receiving
authorization errors once the token expires, after which the user can run
`terraform login` again to obtain a new token.
-> **Note:** As a special case, Terraform can use a
[Resource Owner Password Credentials Grant](https://tools.ietf.org/html/rfc6749#section-4.3)
only when interacting with `app.terraform.io` ([HCP Terraform](https://cloud.hashicorp.com/products/terraform)),
under the recommendation in the OAuth specification to use this grant type only
when the client and server are closely related. The `password` grant type is
not supported for any other hostname and will be ignored.

File diff suppressed because it is too large Load diff

View file

@ -1,226 +0,0 @@
---
page_title: Module registry protocol reference
description: |-
Terraform discovers modules available for installation using the module registry protocol. Learn about the module registry protocol so consumers can find your modules.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Module Registry Protocol Reference
This topic provides reference information about the module registry protocol.
-> Third-party module registries are supported only in Terraform CLI 0.11 and later. Prior versions do not support this protocol.
## Introduction
The Terraform CLI uses the module registry protocol to discover metadata
about modules available for installation and to locate the distribution
package for a selected module.
The primary implementation of this protocol is the public
[Terraform Registry](https://registry.terraform.io/) at `registry.terraform.io`.
By writing and deploying your own implementation of this protocol, you can
create a separate registry to distribute your own modules, as an alternative to
publishing them on the public Terraform Registry.
The public Terraform Registry implements a superset of the API described on
this page, in order to capture additional information used in the registry UI.
For information on those extensions, see
[Terraform Registry HTTP API](/terraform/registry/api-docs). Third-party registry
implementations may choose to implement those extensions if desired, but
Terraform CLI itself does not use them.
## Module Addresses
Each Terraform module has an associated address. A module address has the
syntax `hostname/namespace/name/system`, where:
- `hostname` is the hostname of the module registry that serves this module.
- `namespace` is the name of a namespace, unique on a particular hostname, that
can contain one or more modules that are somehow related. On the public
Terraform Registry the "namespace" represents the organization that is
packaging and distributing the module.
- `name` is the module name, which generally names the abstraction that the
module is intending to create.
- `system` is the name of a remote system that the module is primarily written
to target. For multi-cloud abstractions, there can be multiple modules with
addresses that differ only in "system" to reflect provider-specific
implementations of the abstraction, like
`registry.terraform.io/hashicorp/consul/aws` vs.
`registry.terraform.io/hashicorp/consul/azurerm`. The system name commonly
matches the type portion of the address of an official provider, like `aws`
or `azurerm` in the above examples, but that is not required and so you can
use whichever system keywords make sense for the organization of your
particular registry.
The `hostname/` portion of a module address (including its slash delimiter)
is optional, and if omitted defaults to `registry.terraform.io/`.
For example:
- `hashicorp/consul/aws` is a shorthand for
`registry.terraform.io/hashicorp/consul/aws`, which is a module on the
public registry for deploying Consul clusters in Amazon Web Services.
- `example.com/awesomecorp/consul/happycloud` is a hypothetical module published
on a third-party registry.
If you intend to share a module you've developed for use by all Terraform
users, please consider publishing it into the public
[Terraform Registry](https://registry.terraform.io/) to make your module more
discoverable. You only need to implement this module registry protocol if you
wish to publish modules whose addresses include a different hostname that is
under your control.
## Module Versions
Each distinct module address has associated with it a set of versions, each
of which has an associated version number. Terraform assumes version numbers
follow the [Semantic Versioning 2.0](https://semver.org/) conventions, with
the user-facing behavior of the module serving as the "public API".
Each `module` block may select a distinct version of a module, even if multiple
blocks have the same source address.
## Service Discovery
The module registry protocol begins with Terraform CLI using
[Terraform's remote service discovery protocol](/terraform/internals/remote-service-discovery),
with the hostname in the module address acting as the "User-facing Hostname".
The service identifier for the module registry protocol is `modules.v1`.
Its associated string value is the base URL for the relative URLs defined in
the sections that follow.
For example, the service discovery document for a host that _only_ implements
the module registry protocol might contain the following:
```json
{
"modules.v1": "/terraform/modules/v1/"
}
```
If the given URL is a relative URL then Terraform will interpret it as relative
to the discovery document itself. The specific module registry protocol
endpoints are defined as URLs relative to the given base URL, and so the
specified base URL should generally end with a slash to ensure that those
relative paths will be resolved as expected.
The following sections describe the various operations that a module
registry must implement to be compatible with Terraform CLI's module
installer. The indicated URLs are all relative to the URL resulting from
service discovery, as described above. We use the current URLs on
Terraform Registry as working examples, assuming that the caller already
performed service discovery on `registry.terraform.io` to learn the base URL.
The URLs are shown with the convention that a path portion with a colon `:`
prefix is a placeholder for a dynamically-selected value, while all other
path portions are literal. For example, in `:namespace/:type/versions`,
the first two path portions are placeholders while the third is literally
the string "versions".
## List Available Versions for a Specific Module
This is the primary endpoint for resolving module sources, returning the
available versions for a given fully-qualified module.
| Method | Path | Produces |
| ------ | ----------------------------------- | ------------------ |
| `GET` | `:namespace/:name/:system/versions` | `application/json` |
### Parameters
- `namespace` `(string: <required>)` - The user or organization the module is
owned by. This is required and is specified as part of the URL path.
- `name` `(string: <required>)` - The name of the module.
This is required and is specified as part of the URL path.
- `system` `(string: <required>)` - The name of the target system.
This is required and is specified as part of the URL path.
### Sample Request
```text
$ curl 'https://registry.terraform.io/v1/modules/hashicorp/consul/aws/versions'
```
### Sample Response
The `modules` array in the response always includes the requested module as the
first element.
Terraform does not use the other elements of this list. However, third-party implementations should always use a single-element list for forward compatiblity.
Each returned module has an array of available versions, which Terraform
matches against any version constraints given in configuration.
```json
{
"modules": [
{
"versions": [
{"version": "1.0.0"},
{"version": "1.1.0"},
{"version": "2.0.0"}
]
}
]
}
```
Return `404 Not Found` to indicate that no module is available with the
requested namespace, name, and target system.
## Download Source Code for a Specific Module Version
This endpoint downloads the specified version of a module for a single target system.
| Method | Path | Produces |
| ------ | -------------------------------------------- | ------------------ |
| `GET` | `:namespace/:name/:system/:version/download` | `application/json` |
### Parameters
- `namespace` `(string: <required>)` - The user the module is owned by.
This is required and is specified as part of the URL path.
- `name` `(string: <required>)` - The name of the module.
This is required and is specified as part of the URL path.
- `system` `(string: <required>)` - The name of the target system.
This is required and is specified as part of the URL path.
- `version` `(string: <required>)` - The version of the module.
This is required and is specified as part of the URL path.
### Sample Request
```text
$ curl -i 'https://registry.terraform.io/v1/modules/hashicorp/consul/aws/0.0.1/download'
```
### Sample Response
```text
HTTP/1.1 204 No Content
Content-Length: 0
X-Terraform-Get: https://api.github.com/repos/hashicorp/terraform-aws-consul/tarball/v0.0.1//*?archive=tar.gz
```
A successful response has no body, and includes the location from which the
module version's source can be downloaded in the `X-Terraform-Get` header.
The value of this header accepts the same values as the `source` argument
in a `module` block in Terraform configuration, as described in
[Module Sources](/terraform/language/modules/sources),
except that it may not recursively refer to another module registry address.
The value of `X-Terraform-Get` may instead be a relative URL, indicated by
beginning with `/`, `./` or `../`, in which case it is resolved relative to
the full URL of the download endpoint to produce
[an HTTP URL module source](/terraform/language/modules/sources#http-urls).

View file

@ -1,84 +0,0 @@
---
page_title: Collect Provider Metadata
description: >-
Provider developers can enable the modules created for the their providers to collect provider metadata.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Collect Provider Metadata
This topic describes how to create an inferface in the providers you develop that allows you to collect metadata that is unrelated to the resources in the module, such as usage statistics. This is an advanced topic and is not required to use Terraform.
## Introduction
In some situations it is 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.
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.
~> **Experimental Feature:** This functionality is
experimental. You should [coordinate
with the Terraform team](https://github.com/hashicorp/terraform/issues/new)
so that they can understand how you are using this functionality. Doing so ensures that your use cases are taken into account as the feature evolves.
## Defining the Schema
Before a provider can receive information from a module, the provider
must strictly define the data it can accept. You can do this by setting
the `ProviderMeta` property on your `schema.Provider` struct. Its value
functions similarly to the provider config: a map of strings to the
`schema.Schema` describing the values those strings accept.
## Using the Data
When Terraform calls your provider, you can use the `schema.ResourceData`
that your `Create`, `Read`, and `Update` functions already use to get
access to the provider metadata being passed. First define a struct
that matches your schema, then call the `GetProviderSchema` method on
your `schema.ResourceData`, passing a pointer to a variable of that type.
The variable will be populated with the provider metadata, and will return
an error if there was an issue with parsing the data into the struct.
## Specifying Data in Modules
To include data in your modules, create a `provider_meta` nested block under
your module's `terraform` block, with the name of the provider it's trying
to pass information to:
```hcl
terraform {
provider_meta "my-provider" {
hello = "world"
}
}
```
The `provider_meta` block must match the schema the provider has defined.
## Versioning Your Modules
Any module taking advantage of this functionality must make sure that the
provider metadata supplied matches the schema defined in the provider, and
that the version of Terraform that is being run has support for the provider
metadata functionality. It's therefore recommended that any module taking
advantage of this functionality should specify a minimum Terraform version of
0.13.0 or higher, and a minimum version of each of the providers it specifies
metadata as the first version the schema being used was supported by the
provider.

View file

@ -1,276 +0,0 @@
---
page_title: Provider network mirror protocol reference
description: |-
The provider network mirror protocol lets you provide an alternate installation source for your providers. Learn about the provider network mirror protocol.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Provider Network Mirror Protocol Reference
This topic provides reference information about the provider network mirror protocol. You can implement an alternative installation source for Terraform providers and make the source available over the provider network mirror protocol, regardless of their origin registries.
-> Provider network mirrors are supported only in Terraform CLI v0.13.2 and later. Prior versions do not support this protocol.
## Introduction
Terraform uses network mirrors only if you activate them explicitly in
[the CLI configuration's `provider_installation` block](/terraform/cli/config/config-file#provider-installation).
When enabled, a network mirror can serve providers belonging to any registry
hostname, which can allow an organization to serve all of the Terraform
providers they intend to use from an internal server, rather than from each
provider's origin registry.
This is _not_ the protocol that should be implemented by a host intending to
serve as an origin registry for Terraform Providers. To provide an origin
registry (whose hostname would then be included in the source addresses of the
providers it hosts), implement
[the provider registry protocol](/terraform/internals/provider-registry-protocol)
instead.
## Provider Addresses
Each Terraform provider has an associated address which uniquely identifies it
within Terraform. A provider address has the syntax `hostname/namespace/type`,
which is described in more detail in
[the Provider Requirements documentation](/terraform/language/providers/requirements).
By default, the `hostname` portion of a provider address serves both as part
of its unique identifier _and_ as the location of the registry to retrieve it
from. However, when you configure Terraform to install providers from a network
mirror, the `hostname` serves _only_ as an identifier and no longer as
an installation source. A provider mirror can therefore serve providers
belonging to a variety of different provider registry hostnames, including
providers from the public Terraform Registry at `registry.terraform.io`, from a
single server.
In the relative URL patterns later in this document, the placeholder `:hostname`
refers to the hostname from the address of the provider being requested, not
the hostname where the provider network mirror is deployed.
## Protocol Base URL
Most Terraform-native services use
[the remote service discovery protocol](/terraform/internals/remote-service-discovery) so
that the physical location of the endpoints can potentially be separated from
the hostname used in identifiers. The Provider Network Mirror protocol does
_not_ use the service discovery indirection, because a network mirror location
is only a physical location and is never used as part of the identifier of a
dependency in a Terraform configuration.
Instead, the provider installation section of the CLI configuration accepts
a base URL directly. The given URL must use the scheme `https:`, and should
end with a trailing slash so that the relative URLs of the individual operation
endpoints will be resolved beneath it.
```hcl
provider_installation {
network_mirror {
url = "https://terraform.example.com/providers/"
}
}
```
Terraform uses the base URL only as a stem to resolve the operation endpoint
URLs against, and so it will never access the base URL directly. You can
therefore, if desired, publish human-readable usage documentation for your
network mirror at that URL.
The following sections describe the various operations that a provider
network mirror server must implement to be compatible with Terraform CLI's
provider installer. The indicated URLs are all relative to the given base URL,
as described above.
The URLs are shown with the convention that a path portion with a colon `:`
prefix is a placeholder for a dynamically-selected value, while all other
path portions are literal. For example, in `:hostname/:namespace/:type/index.json`,
the first three path portions are placeholders while the third is literally
the string "index.json".
The example requests in the following sections will assume the example mirror
base URL from the above CLI configuration example.
### Authentication
If the CLI configuration includes
[credentials](/terraform/cli/config/config-file#credentials) for the hostname
given in the network mirror base URL, Terraform will include those credentials
in its requests for operations described below.
If the given URL uses a non-standard port number (other than 443) then the
credentials must be associated with a hostname that includes the port number,
such as `terraform.example.com:8443`.
Terraform does _not_ send credentials when retrieving the archives whose
URLs are given in the "List Available Installation Packages" response below.
If a particular mirror considers the distribution packages themselves to be
sensitive then it must use cryptographically-secure, user-specific, and
time-limited URLs in the metadata response. Strategies for doing so are out
of scope of this protocol documentation.
## List Available Versions
This operation determines which versions are currently available for a
particular provider.
| Method | Path | Produces |
| ------ | --------------------------------------- | ------------------ |
| `GET` | `:hostname/:namespace/:type/index.json` | `application/json` |
### Parameters
* `hostname` (required): the hostname portion of the address of the requested
provider.
* `namespace` (required): the namespace portion of the address of the requested
provider.
* `type` (required): the type portion of the address of the requested provider.
### Sample Request
```
curl 'https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/index.json'
```
### Sample Response
```json
{
"versions": {
"2.0.0": {},
"2.0.1": {}
}
}
```
### Response Properties
A successful result is a JSON object containing a single property `versions`,
which must be a JSON object.
Each of the property names of the `versions` object represents an available
version number. The property values must be objects, but no properties are defined for those objects. We recommend leaving those objects empty for forward compatibility.
Return `404 Not Found` to signal that the mirror does not have a provider
with the given address.
## List Available Installation Packages
This operation returns download URLs and associated metadata for the
distribution packages for a particular version of a provider.
Each distribution package is associated with a particular operating system
and architecture. A network mirror may host only a subset of the available
packages for a provider version, if the users of the mirror are known to all
use only a subset of the target platforms that Terraform supports.
Terraform CLI uses this operation after it has selected the newest available
version matching the configured version constraints, in order to find a zip
archive containing the plugin itself.
| Method | Path | Produces |
| ------ | ------------------------------------------ | ------------------ |
| `GET` | `:hostname/:namespace/:type/:version.json` | `application/json` |
### Parameters
* `hostname` (required): the hostname portion of the address of the requested
provider.
* `namespace` (required): the namespace portion of the address of the requested
provider.
* `type` (required): the type portion of the address of the requested provider.
* `version` (required): the version selected to download. This will exactly
match one of the version strings returned from a previous call to
[List Available Versions](#list-available-versions).
### Sample Request
```
curl 'https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/2.0.0.json'
```
### Sample Response
```json
{
"archives": {
"darwin_amd64": {
"url": "terraform-provider-random_2.0.0_darwin_amd64.zip",
"hashes": [
"h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs="
]
},
"linux_amd64": {
"url": "terraform-provider-random_2.0.0_linux_amd64.zip",
"hashes": [
"h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ="
]
}
}
}
```
### Response Properties
A successful result is a JSON object with a property called `archives`, which
must be a JSON object.
Each of the property names of the `archives` object is a target platform
identifier, which consists of an operating system and architecture concatenated
with an underscore (`_`).
Each property value in the `archives` object is itself a nested object with
the following properties:
* `url` (required): a string specifying the URL from which Terraform should
download the `.zip` archive containing the requested provider plugin version.
Terraform resolves the URL relative to the URL from which the current
JSON document was returned, so the examples above containing only a
filename would cause Terraform to construct a URL like:
```
https://terraform.example.com/providers/registry.terraform.io/hashicorp/random/terraform-provider-random_2.0.0_darwin_amd64.zip
```
* `hashes` (optional): a JSON array of strings containing one or more hash
values for the indicated archive. These hashes use Terraform's provider
package hashing algorithm. At present, the easiest way to populate these
is to construct a mirror's JSON indices using the `terraform providers mirror`
command, as described in a later section, which will include the calculated
hashes of each provider.
If the response includes at least one hash, Terraform will select the hash
whose algorithm it considers to be strongest and verify that the downloaded
package matches that hash. If the response does not include a `hashes`
property then Terraform will install the indicated archive with no
verification.
Terraform CLI will only attempt to download versions that it has previously
seen in response to [List Available Versions](#list-available-versions).
## Provider Mirror as a Static Website
The provider mirror protocol is designed so that it can potentially be implemented
by placing files on typical static website hosting services. When using this
strategy, implement the JSON index responses described above as `.json` files
in the appropriate nested subdirectories, and ensure that your system is
configured to serve `.json` files with the `application/json` media type.
As a convenience, Terraform CLI includes
[the `terraform providers mirror` subcommand](/terraform/cli/commands/providers/mirror),
which will analyze the current configuration for the providers it requires,
download the packages for those providers from their origin registries, and
place them into a local directory suitable for use as a mirror.
The `terraform providers mirror` subcommand also generates `index.json` and
version-specific `.json` files that can, when placed in a static website hosting
system, produce responses compatible with the provider mirror protocol.
If you wish to create a mirror with providers for a number of different
Terraform configurations, run `terraform providers mirror` in each configuration
in turn while providing the same output directory each time. Terraform will
then merge together all of the requirements into a single set of JSON indices.

View file

@ -1,346 +0,0 @@
---
page_title: Provider registry protocol reference
description: |-
Use the provider registry protocol to enable Terraform to discover metadata about available providers and locate their distribution packages.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Provider Registry Protocol Reference
This topic provides reference information about the provider registry protocol. The protocol allows the Terraform CLI to discover metadata about the providers available for installation and to locate the distribution packages for a selected provider.
## Introduction
The primary implementation of this protocol is the public
[Terraform Registry](https://registry.terraform.io/) at `registry.terraform.io`.
By writing and deploying your own implementation of this protocol, you can
create a separate _origin registry_ to distribute your own providers, as an
alternative to publishing them on the public Terraform Registry.
This page describes the provider _registry_ protocol, which is the protocol
for finding providers available for installation. It _doesn't_ describe the
API that provider plugins themselves implement to serve requests from Terraform
CLI at runtime. For more information on the provider API, see the Terraform
SDK documentation.
The public Terraform Registry implements a superset of the API described on
this page, in order to capture additional information used in the registry UI.
Third-party implementations should not include those extensions because they
may change in future without notice.
## Provider Addresses
Each Terraform provider has an associated address which uniquely identifies it
within Terraform. A provider address has the syntax `hostname/namespace/type`,
where:
* `hostname` is the registry host that the provider is considered to have
originated from, and the default location Terraform will consult for
information about the provider
[unless overridden in the CLI configuration](/terraform/cli/config/config-file#provider-installation).
* `namespace` is the name of a namespace, unique on a particular hostname, that
can contain one or more providers that are somehow related. On the public
Terraform Registry the "namespace" represents the organization that is
packaging and distributing the provider.
* `type` is the provider type, like "azurerm", "aws", "google", "dns", etc.
A provider type is unique within a particular hostname and namespace.
The `hostname/` portion of a provider address (including its slash delimiter)
is optional, and if omitted defaults to `registry.terraform.io/`.
For example:
* `hashicorp/aws` is a shorthand for `registry.terraform.io/hashicorp/aws`,
which is the official AWS provider published by HashiCorp.
* `example/foo` is a shorthand for `registry.terraform.io/example/foo`, which
is a hypothetical third-party provider published on the public
Terraform Registry.
* `example.com/bar/baz` is a hypothetical third-party provider published at a
third-party provider registry on `example.com`.
If you intend only to share a provider you've developed for use by all
Terraform users, please consider publishing it into the public
[Terraform Registry](https://registry.terraform.io/), which will make your
provider discoverable. You only need to implement this provider registry
protocol if you wish to publish providers whose addresses include a different
hostname that is under your control.
Terraform uses the full address (after normalization to always include a
hostname) as its global identifier for providers internally, and so it's
important to note that re-uploading the `hashicorp/azurerm` provider into
another namespace or publishing it on a different hostname will cause Terraform
to see it as an entirely separate provider that will _not_ be usable by modules
that declare a dependency on `hashicorp/azurerm`. If your goal is to create
an alternative local distribution source for an existing provider -- that is,
a _mirror_ of the provider -- refer to
[the provider installation method configuration](/terraform/cli/config/config-file#provider-installation)
instead.
## Provider Versions
Each distinct provider address has associated with it a set of versions, each
of which has an associated version number. Terraform assumes version numbers
follow the [Semantic Versioning 2.0](https://semver.org/) conventions, with
the schema and behavior of the provider as documented from the perspective of
an end-user of Terraform serving as the "public API".
All available versions for a particular provider address are considered to be
the same provider by Terraform. Each Terraform configuration selects only one
version of each provider for use in the entire configuration, so the version
constraints across all modules are considered together for the purposes of
version selection.
## Service Discovery
The providers protocol begins with Terraform CLI using
[Terraform's remote service discovery protocol](/terraform/internals/remote-service-discovery),
with the hostname in the provider address acting as the "User-facing Hostname".
The service identifier for the provider registry protocol is `providers.v1`.
Its associated string value is the base URL for the relative URLs defined in
the sections that follow.
For example, the service discovery document for a host that _only_ implements
the provider registry protocol might contain the following:
```json
{
"providers.v1": "/terraform/providers/v1/"
}
```
If the given URL is a relative URL then Terraform will interpret it as relative
to the discovery document itself. The specific provider registry protocol
endpoints are defined as URLs relative to the given base URL, and so the
specified base URL should generally end with a slash to ensure that those
relative paths will be resolved as expected.
The following sections describe the various operations that a provider
registry must implement to be compatible with Terraform CLI's provider
installer. The indicated URLs are all relative to the URL resulting from
service discovery, as described above. We use the current URLs on
Terraform Registry as working examples, assuming that the caller already
performed service discovery on `registry.terraform.io` to learn the base URL.
The URLs are shown with the convention that a path portion with a colon `:`
prefix is a placeholder for a dynamically-selected value, while all other
path portions are literal. For example, in `:namespace/:type/versions`,
the first two path portions are placeholders while the third is literally
the string "versions".
## List Available Versions
This operation determines which versions are currently available for a
particular provider.
| Method | Path | Produces |
| ------ | --------------------------- | ------------------ |
| `GET` | `:namespace/:type/versions` | `application/json` |
### Parameters
* `namespace` (required): the namespace portion of the address of the requested
provider.
* `type` (required): the type portion of the address of the requested provider.
### Sample Request
```
curl 'https://registry.terraform.io/v1/providers/hashicorp/random/versions'
```
### Sample Response
```json
{
"versions": [
{
"version": "2.0.0",
"protocols": ["4.0", "5.1"],
"platforms": [
{"os": "darwin", "arch": "amd64"},
{"os": "linux", "arch": "amd64"},
{"os": "linux", "arch": "arm"},
{"os": "windows", "arch": "amd64"}
]
},
{
"version": "2.0.1",
"protocols": ["5.2"],
"platforms": [
{"os": "darwin", "arch": "amd64"},
{"os": "linux", "arch": "amd64"},
{"os": "linux", "arch": "arm"},
{"os": "windows", "arch": "amd64"}
]
}
]
}
```
### Response Properties
A successful result is a JSON object containing a single property `versions`.
`versions` is an array of objects that each describe one available version,
with the following properties:
* `version` (required): the version number this object is describing, using
the semantic versioning string notation. `version` must be unique across
all objects in the response.
* `protocols` (recommended): an array of Terraform provider API versions that
this version supports, each given in `MAJOR.MINOR` format where each major
version appears only once and the given minor version is the highest minor
version supported. For example, `5.1` means that the provider supports both
protocol `5.0` and protocol `5.1`.
Terraform uses this information, when available, to provide hints to users
about upgrading or downgrading their version of a particular provider to
work with their current version of Terraform, if their currently-selected
versions are not compatible.
Which API versions are supported is, for most providers, decided by which
version of the Terraform SDK they are built against. Consult the Terraform
SDK documentation for more information.
Only Terraform 0.13 and later support third-party provider registries and
that Terraform version requires API version `5.0` or later, so in practice
it isn't useful to list major versions 4 or earlier in a third-party
provider registry.
* `platforms` (recommended): an array of objects describing platforms that have
packages available for this version.
Terraform may use this information, when available, to provide hints to
users about upgrading or downgrading their version of a particular provider
for compatibility with their current platform.
The `platforms` objects have properties `os` and `arch`, whose values match
the properties of the same name in the response to
[Find a Provider Package](#find-a-provider-package).
Return `404 Not Found` to signal that the registry does not have a provider
with the given namespace and type.
## Find a Provider Package
This operation returns the download URL of and associated metadata about the
distribution package for a particular version of a provider for a particular
operating system and architecture.
Terraform CLI uses this operation after it has selected the newest available
version matching the configured version constraints, in order to find the zip
archive containing the plugin itself.
| Method | Path | Produces |
| ------ | ---------------------------------------------- | ------------------ |
| `GET` | `:namespace/:type/:version/download/:os/:arch` | `application/json` |
### Parameters
* `namespace` (required): the namespace portion of the address of the requested
provider.
* `type` (required): the type portion of the address of the requested provider.
* `version` (required): the version selected to download. This will exactly
match one of the version strings returned from a previous call to
[List Available Versions](#list-available-versions).
* `os` (required): a keyword identifying the operating system that the returned
package should be compatible with, like "linux" or "darwin".
* `arch` (required): a keyword identifying the CPU architecture that the
returned package should be compatible with, like "amd64" or "arm".
### Sample Request
```
curl 'https://registry.terraform.io/v1/providers/hashicorp/random/2.0.0/download/linux/amd64'
```
### Sample Response
```json
{
"protocols": ["4.0", "5.1"],
"os": "linux",
"arch": "amd64",
"filename": "terraform-provider-random_2.0.0_linux_amd64.zip",
"download_url": "https://releases.hashicorp.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_linux_amd64.zip",
"shasums_url": "https://releases.hashicorp.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_SHA256SUMS",
"shasums_signature_url": "https://releases.hashicorp.com/terraform-provider-random/2.0.0/terraform-provider-random_2.0.0_SHA256SUMS.sig",
"shasum": "5f9c7aa76b7c34d722fc9123208e26b22d60440cb47150dd04733b9b94f4541a",
"signing_keys": {
"gpg_public_keys": [
{
"key_id": "51852D87348FFC4C",
"ascii_armor": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n\nmQENBFMORM0BCADBRyKO1MhCirazOSVwcfTr1xUxjPvfxD3hjUwHtjsOy/bT6p9f\nW2mRPfwnq2JB5As+paL3UGDsSRDnK9KAxQb0NNF4+eVhr/EJ18s3wwXXDMjpIifq\nfIm2WyH3G+aRLTLPIpscUNKDyxFOUbsmgXAmJ46Re1fn8uKxKRHbfa39aeuEYWFA\n3drdL1WoUngvED7f+RnKBK2G6ZEpO+LDovQk19xGjiMTtPJrjMjZJ3QXqPvx5wca\nKSZLr4lMTuoTI/ZXyZy5bD4tShiZz6KcyX27cD70q2iRcEZ0poLKHyEIDAi3TM5k\nSwbbWBFd5RNPOR0qzrb/0p9ksKK48IIfH2FvABEBAAG0K0hhc2hpQ29ycCBTZWN1\ncml0eSA8c2VjdXJpdHlAaGFzaGljb3JwLmNvbT6JATgEEwECACIFAlMORM0CGwMG\nCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEFGFLYc0j/xMyWIIAIPhcVqiQ59n\nJc07gjUX0SWBJAxEG1lKxfzS4Xp+57h2xxTpdotGQ1fZwsihaIqow337YHQI3q0i\nSqV534Ms+j/tU7X8sq11xFJIeEVG8PASRCwmryUwghFKPlHETQ8jJ+Y8+1asRydi\npsP3B/5Mjhqv/uOK+Vy3zAyIpyDOMtIpOVfjSpCplVRdtSTFWBu9Em7j5I2HMn1w\nsJZnJgXKpybpibGiiTtmnFLOwibmprSu04rsnP4ncdC2XRD4wIjoyA+4PKgX3sCO\nklEzKryWYBmLkJOMDdo52LttP3279s7XrkLEE7ia0fXa2c12EQ0f0DQ1tGUvyVEW\nWmJVccm5bq25AQ0EUw5EzQEIANaPUY04/g7AmYkOMjaCZ6iTp9hB5Rsj/4ee/ln9\nwArzRO9+3eejLWh53FoN1rO+su7tiXJA5YAzVy6tuolrqjM8DBztPxdLBbEi4V+j\n2tK0dATdBQBHEh3OJApO2UBtcjaZBT31zrG9K55D+CrcgIVEHAKY8Cb4kLBkb5wM\nskn+DrASKU0BNIV1qRsxfiUdQHZfSqtp004nrql1lbFMLFEuiY8FZrkkQ9qduixo\nmTT6f34/oiY+Jam3zCK7RDN/OjuWheIPGj/Qbx9JuNiwgX6yRj7OE1tjUx6d8g9y\n0H1fmLJbb3WZZbuuGFnK6qrE3bGeY8+AWaJAZ37wpWh1p0cAEQEAAYkBHwQYAQIA\nCQUCUw5EzQIbDAAKCRBRhS2HNI/8TJntCAClU7TOO/X053eKF1jqNW4A1qpxctVc\nz8eTcY8Om5O4f6a/rfxfNFKn9Qyja/OG1xWNobETy7MiMXYjaa8uUx5iFy6kMVaP\n0BXJ59NLZjMARGw6lVTYDTIvzqqqwLxgliSDfSnqUhubGwvykANPO+93BBx89MRG\nunNoYGXtPlhNFrAsB1VR8+EyKLv2HQtGCPSFBhrjuzH3gxGibNDDdFQLxxuJWepJ\nEK1UbTS4ms0NgZ2Uknqn1WRU1Ki7rE4sTy68iZtWpKQXZEJa0IGnuI2sSINGcXCJ\noEIgXTMyCILo34Fa/C6VCm2WBgz9zZO8/rHIiQm1J5zqz0DrDwKBUM9C\n=LYpS\n-----END PGP PUBLIC KEY BLOCK-----",
"trust_signature": "",
"source": "HashiCorp",
"source_url": "https://www.hashicorp.com/security.html"
}
]
}
}
```
### Response Properties
A successful result is a JSON object with the following properties:
* `protocols` (required): an array of Terraform provider API versions that
the provider supports, in the same format as for
[List Available Versions](#list-available-versions).
While this property is optional when listing available options, it is
_required_ for describing an individual provider package so that Terraform
CLI can avoid downloading a package that will not be compatible with it.
* `os` (required): this must echo back the `os` parameter from the
request.
* `arch` (required): this must echo back the `arch` parameter from the
request.
* `filename` (required): the filename for this provider's zip archive as
recorded in the "shasums" document, so that Terraform CLI can determine which
of the given checksums should be used for this specific package.
* `download_url` (required): a URL from which Terraform can retrieve the
provider's zip archive. If this is a relative URL then it will be resolved
relative to the URL that returned the containing JSON object.
* `shasums_url` (required): a URL from which Terraform can retrieve a text
document recording expected SHA256 checksums for this package and possibly
other packages for the same provider version on other platforms.
The indicated document must be in the format generated by the `sha256`
command available on many Unix systems, with one entry recording the
same filename given in the `filename` property (case sensitive).
* `shasums_signature_url` (required): a URL from which Terraform can retrieve
a binary, detached GPG signature for the document at `shasums_url`, signed
by one of the keys indicated in the `signing_keys` property.
* `shasum` (required): the SHA256 checksum for this provider's zip archive as
recorded in the shasums document.
* `signing_keys` (required): an object describing signing keys for this
provider package, one of which must have been used to produce the signature
at `shasums_signature_url`. The object has the following nested properties:
* `gpg_public_keys` (required): an array of objects, each describing one
GPG signing key that is allowed to sign the checksums for this provider
version. At least one element must be included, representing the key that
produced the signature at `shasums_signature_url`. These objects have
the following nested properties:
* `key_id` (required): uppercase-hexadecimal-formatted ID for this GPG key
* `ascii_armor` (required): an "ascii-armor" encoding of the **public key**
associated with this GPG key.
Return `404 Not Found` to signal that the given provider version isn't
available for the requested operating system and/or architecture. Terraform
CLI will only attempt to download versions that it has previously seen in
response to [List Available Versions](#list-available-versions).

View file

@ -1,118 +0,0 @@
---
page_title: Remote service discovery protocol reference
description: |-
The remote service discovery protocol presents Terraform-native services at a human-readable hostname. Learn about the remote service discovery protocol.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Remote Service Discovery Protocol Reference
This topic provides reference information about the remote service discovery protocol in Terraform.
## Introduction
Terraform implements much of its functionality as remote services.
Some of these are native services that Terraform
interacts with through the remote service discovery protocol.
## User-facing Hostname
Terraform provides native services at a
human-readable hostname. The hostname is the key for configuration and
for any authentication credentials required.
The discovery protocol's purpose is to map from a user-provided hostname to
the base URL of a particular service. Each host can provide different
combinations of services -- or no services at all! -- and so the discovery
protocol has a secondary purpose of allowing Terraform to identify _which_
services are valid for a given hostname.
For example, module source strings can include a module registry hostname
as their first segment, like `example.com/namespace/name/provider`, and
Terraform uses service discovery to determine whether `example.com` _has_
a module registry, and if so where its API is available.
A user-facing hostname is a fully-specified
[internationalized domain name](https://en.wikipedia.org/wiki/Internationalized_domain_name)
expressed in its Unicode form (the corresponding "punycode" form is not allowed)
which must be resolvable in DNS to an address that has an HTTPS server running
on port 443.
User-facing hostnames are normalized for internal comparison using the
standard Unicode [Nameprep](https://en.wikipedia.org/wiki/Nameprep) algorithm,
which includes converting all letters to lowercase, normalizing combining
diacritics to precomposed form where possible, and various other normalization
steps.
## Discovery Process
Given a hostname, discovery begins by forming an initial discovery URL
using that hostname with the `https:` scheme and the fixed path
`/.well-known/terraform.json`.
For example, given the hostname `example.com` the initial discovery URL
would be `https://example.com/.well-known/terraform.json`.
Terraform then sends a `GET` request to this discovery URL and expects a
JSON response. If the response does not have status 200, does not have a media
type of `application/json` or, if the body cannot be parsed as a JSON object,
then discovery fails and Terraform considers the host to not support _any_
Terraform-native services.
If the response is an HTTP redirect then Terraform repeats this step with the
new location as its discovery URL. Terraform is guaranteed to follow at least
one redirect, but nested redirects are not guaranteed nor recommended.
If the response is a valid JSON object then its keys are Terraform native
service identifiers, consisting of a service type name and a version string
separated by a period. For example, the service identifier for version 1 of
the module registry protocol is `modules.v1`.
The value of each object element is the base URL for the service in question.
This URL may be either absolute or relative, and if relative it is resolved
against the final discovery URL (_after_ following redirects).
The following is an example discovery document declaring support for
version 1 of the module registry protocol:
```json
{
"modules.v1": "https://modules.example.com/v1/"
}
```
## Supported Services
At present, the following service identifiers are in use:
* `login.v1`: [login protocol version 1](/terraform/cli/commands/login)
* `modules.v1`: [module registry API version 1](/terraform/internals/module-registry-protocol)
* `providers.v1`: [provider registry API version 1](/terraform/internals/provider-registry-protocol)
## Authentication
If credentials for the given hostname are available in
[the CLI config](/terraform/cli/config/config-file#Credentials) through a `credentials_helper` or a host-specific environment variable, then they will be included in the request for the discovery document.
The credentials may also be provided to endpoints declared in the discovery
document, depending on the requirements of the service in question.
## Non-standard Ports in User-facing Hostnames
It is strongly recommended to provide the discovery document for a hostname
on the standard HTTPS port 443. However, in development environments this is
not always possible or convenient, so Terraform allows a hostname to end
with a port specification consisting of a colon followed by one or more
decimal digits.
When a custom port number is present, the service on that port is expected to
implement HTTPS and respond to the same fixed discovery path.
For day-to-day use it is strongly recommended _not_ to rely on this mechanism
and to instead provide the discovery document on the standard port, since this
allows use of the most user-friendly hostname form.

View file

@ -1,344 +0,0 @@
---
page_title: Overview of the core Terraform workflow
description: Learn how to provision and manage infrastructure using the core Terraform workflow for individuals, teams, and organizations.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Core Terraform Workflow Overview
The core Terraform workflow has three steps:
1. **Write** - Author infrastructure as code.
1. **Plan** - Preview changes before applying.
1. **Apply** - Provision reproducible infrastructure.
This guide walks through how each of these three steps plays out in the context
of working as an individual practitioner, how they evolve when a team is
collaborating on infrastructure, and how HCP Terraform enables this
workflow to run smoothly for entire organizations.
## Working as an Individual Practitioner
Let's first walk through how these parts fit together as an individual working
on infrastructure as code.
### Write
You write Terraform configuration just like you write code: in your editor of
choice. It's common practice to store your work in a version controlled
repository even when you're just operating as an individual.
```sh
# Create repository
$ git init my-infra && cd my-infra
Initialized empty Git repository in /.../my-infra/.git/
# Write initial config
$ vim main.tf
# Initialize Terraform
$ terraform init
Initializing provider plugins...
# ...
Terraform has been successfully initialized!
```
As you make progress on authoring your config, repeatedly running plans can help
flush out syntax errors and ensure that your config is coming together as you
expect.
```sh
# Make edits to config
$ vim main.tf
# Review plan
$ terraform plan
# Make additional edits, and repeat
$ vim main.tf
```
This parallels working on application code as an individual, where a tight
feedback loop between editing code and running test commands is useful.
### Plan
When the feedback loop of the Write step has yielded a change that looks good,
it's time to commit your work and review the final plan.
```sh
$ git add main.tf
$ git commit -m 'Managing infrastructure as code!'
[main (root-commit) f735520] Managing infrastructure as code!
1 file changed, 1 insertion(+)
```
Because `terraform apply` will display a plan for confirmation before
proceeding to change any infrastructure, that's the command you run for final
review.
```sh
$ terraform apply
An execution plan has been generated and is shown below.
# ...
```
### Apply
After one last check, you are ready to tell Terraform to provision real
infrastructure.
```sh
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
# ...
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
At this point, it's common to push your version control repository to a remote
location for safekeeping.
```sh
$ git remote add origin https://github.com/*user*/*repo*.git
$ git push origin main
```
This core workflow is a loop; the next time you want to make changes, you start
the process over from the beginning.
Notice how closely this workflow parallels the process of writing application
code or scripts as an individual? This is what we mean when we talk about
Terraform enabling infrastructure as code.
## Working as a Team
Once multiple people are collaborating on Terraform configuration, new steps
must be added to each part of the core workflow to ensure everyone is working
together smoothly. You'll see that many of these steps parallel the workflow
changes we make when we work on application code as teams rather than as
individuals.
### Write
While each individual on a team still makes changes to Terraform configuration
in their editor of choice, they save their changes to version control _branches_
to avoid colliding with each other's work. Working in branches enables team
members to resolve mutually incompatible infrastructure changes using their
normal merge conflict workflow.
```sh
$ git checkout -b add-load-balancer
Switched to a new branch 'add-load-balancer'
```
Running iterative plans is still useful as a feedback loop while authoring
configuration, though having each team member's computer able to run them
becomes more difficult with time. As the team and the infrastructure grows, so
does the number of sensitive input variables (e.g. API Keys, SSL Cert Pairs)
required to run a plan.
To avoid the burden and the security risk of each team member arranging all
sensitive inputs locally, it's common for teams to migrate to a model in which
Terraform operations are executed in a shared Continuous Integration (CI)
environment. The work needed to create such a CI environment is nontrivial, and
is outside the scope of this core workflow overview, but a full deep dive on
this topic can be found in our
[Running Terraform in Automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS)
guide.
This longer iteration cycle of committing changes to version control and then
waiting for the CI pipeline to execute is often lengthy enough to prohibit using
speculative plans as a feedback loop while authoring individual Terraform
configuration changes. Speculative plans are still useful before new Terraform
changes are applied or even merged to the main development branch, however, as
we'll see in a minute.
### Plan
For teams collaborating on infrastructure, Terraform's plan output creates an
opportunity for team members to review each other's work. This allows the team
to ask questions, evaluate risks, and catch mistakes before any potentially
harmful changes are made.
The natural place for these reviews to occur is alongside pull requests within
version control--the point at which an individual proposes a merge from their
working branch to the shared team branch. If team members review proposed
config changes alongside speculative plan output, they can evaluate whether the
intent of the change is being achieved by the plan.
The problem becomes producing that speculative plan output for the team to
review. Some teams that still run Terraform locally make a practice that pull
requests should include an attached copy of speculative plan output generated
by the change author. Others arrange for their CI system to post speculative
plan output to pull requests automatically.
![Screenshot of Pull Request with manually posted Terraform plan output](/img/docs/manually-pasted-plan-output.png)
In addition to reviewing the plan for the proper expression of its author's
intent, the team can also make an evaluation whether they want this change to
happen now. For example, if a team notices that a certain change could result
in service disruption, they may decide to delay merging its pull request until
they can schedule a maintenance window.
### Apply
Once a pull request has been approved and merged, it's important for the team
to review the final concrete plan that's run against the shared team branch and
the latest version of the state file.
This plan has the potential to be different than the one reviewed on the pull
request due to issues like merge order or recent infrastructural changes. For
example, if a manual change was made to your infrastructure since the plan was
reviewed, the plan might be different when you merge.
It is at this point that the team asks questions about the potential
implications of applying the change. Do we expect any service disruption from
this change? Is there any part of this change that is high risk? Is there
anything in our system that we should be watching as we apply this? Is there
anyone we need to notify that this change is happening?
Depending on the change, sometimes team members will want to watch the apply
output as it is happening. For teams that are running Terraform locally, this
may involve a screen share with the team. For teams running Terraform in CI,
this may involve gathering around the build log.
Just like the workflow for individuals, the core workflow for teams is a loop
that plays out for each change. For some teams this loop happens a few times a
week, for others, many times a day.
## The Core Workflow Enhanced by HCP Terraform
While the above described workflows enable the safe, predictable, and
reproducible creating or changing of infrastructure, there are multiple
collaboration points that can be streamlined, especially as teams and
organizations scale. We designed HCP Terraform to support and enhance
the core Terraform workflow for anyone collaborating on infrastructure, from
small teams to large organizations. Let's look at how HCP Terraform makes
for a better experience at each step.
### Write
HCP Terraform provides a centralized and secure location for storing
input variables and state while also bringing back a tight feedback loop for
speculative plans for config authors. Terraform configuration can interact with
HCP Terraform through the [CLI integration](/terraform/cli/cloud).
```hcl
terraform {
cloud {
organization = "my-org"
hostname = "app.terraform.io" # Optional; defaults to app.terraform.io
workspaces {
tags = {
layer = "networking"
source = "cli"
}
# For terraform versions below 1.10, you must specify key-only tags
# using a list of strings. Example:
# tags = ["networking", "source:cli"]
}
}
}
```
After you configure the integration, an HCP Terraform API key is all your team members need to edit config and run speculative plans
against the latest version of the state file using all the remotely stored
input variables.
```sh
$ terraform workspace select my-app-dev
Switched to workspace "my-app-dev".
$ terraform plan
Running plan remotely in Terraform Enterprise.
Output will stream here. To view this plan in a browser, visit:
https://app.terraform.io/my-org/my-app-dev/.../
Refreshing Terraform state in-memory prior to plan...
# ...
Plan: 1 to add, 0 to change, 0 to destroy.
```
With the assistance of this plan output, team members can each work on
authoring config until it is ready to propose as a change via a pull request.
### Plan
Once a pull request is ready for review, HCP Terraform makes the process
of reviewing a speculative plan easier for team members. First, the plan is
automatically run when the pull request is created. Status updates to the pull
request indicate while the plan is in progress.
Once the plan is complete, the status update indicates whether there were any
changes in the speculative plan, right from the pull request view.
![Screenshot of Pull Request with resource changes in the status update](/img/docs/pull-request.png)
For certain types of changes, this information is all that's needed for a team
member to be able to approve the pull request. When a teammate needs to do a
full review of the plan, clicking the link to HCP Terraform brings up a
view that allows them to quickly analyze the full plan details.
![Screenshot of Pull Request run in HCP Terraform](/img/docs/pr-plan.png)
This page allows the reviewer to quickly determine if the plan is matching the
config author's intent and evaluate the risk of the change.
### Apply
After merge, HCP Terraform presents the concrete plan to the team for
review and approval.
![Screenshot of concrete plan](/img/docs/concrete-plan.png)
The team can discuss any outstanding questions about the plan before the change
is made.
![Screenshot of back-and-forth in HCP Terraform comments](/img/docs/plan-comments.png)
Once the Apply is confirmed, HCP Terraform displays the progress live
to anyone who'd like to watch.
![Screenshot of in-progress Apply](/img/docs/in-progress-apply.png)
<!--
TODO: Add this back in w/ screenshot of notification
And after the change completes, the team can be notified of its outcome.
[ Multi-screenshot of Slack alert indicating Apply completed successfully and
with error; except it's not gonna be Slack anymore? ]
-->
## Conclusion
There are many different ways to use Terraform: as an individual user, a single
team, or an entire organization at scale. Choosing the best approach for the
density of collaboration needed will provide the most return on your investment
in the core Terraform workflow. For organizations using Terraform at scale,
HCP Terraform introduces new layers that build on this core workflow to
solve problems unique to teams and organizations.

View file

@ -1,70 +0,0 @@
---
layout: "intro"
page_title: What is Terraform
sidebar_current: "what"
description: |-
Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# What is Terraform?
HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
> **Hands On:** Try the Get Started tutorials to start managing infrastructure on popular cloud providers: [Amazon Web Services](/terraform/tutorials/aws-get-started), [Azure](/terraform/tutorials/azure-get-started), [Google Cloud Platform](/terraform/tutorials/gcp-get-started), [Oracle Cloud Infrastructure](/terraform/tutorials/oci-get-started), and [Docker](/terraform/tutorials/docker-get-started).
## How does Terraform work?
Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.
![Terraform creates and manages cloud platforms and services through their APIs](/img/docs/intro-terraform-apis.png)
HashiCorp and the Terraform community have already written **thousands of providers** to manage many different types of resources and services. You can find all publicly available providers on the [Terraform Registry](https://registry.terraform.io/), including Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, and many more.
The core Terraform workflow consists of three stages:
- **Write:** You define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
- **Plan:** Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
- **Apply:** On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
![The Terraform workflow has three steps: Write, Plan, and Apply](/img/docs/intro-terraform-workflow.png)
## Why Terraform?
HashiCorp co-founder and CTO Armon Dadgar explains how Terraform solves infrastructure challenges.
<VideoEmbed url="https://www.youtube.com/embed/h970ZBgKINg"/>
### Manage any infrastructure
Find providers for many of the platforms and services you already use in the [Terraform Registry](https://registry.terraform.io/). You can also [write your own](/terraform/plugin). Terraform takes an [immutable approach to infrastructure](https://www.hashicorp.com/resources/what-is-mutable-vs-immutable-infrastructure), reducing the complexity of upgrading or modifying your services and infrastructure.
### Track your infrastructure
Terraform generates a plan and prompts you for your approval before modifying your infrastructure. It also keeps track of your real infrastructure in a [state file](/terraform/language/state), which acts as a source of truth for your environment. Terraform uses the state file to determine the changes to make to your infrastructure so that it will match your configuration.
### Automate changes
Terraform configuration files are declarative, meaning that they describe the end state of your infrastructure. You do not need to write step-by-step instructions to create resources because Terraform handles the underlying logic. Terraform builds a resource graph to determine resource dependencies and creates or modifies non-dependent resources in parallel. This allows Terraform to provision resources efficiently.
### Standardize configurations
Terraform supports reusable configuration components called [modules](/terraform/language/modules) that define configurable collections of infrastructure, saving time and encouraging best practices. You can use publicly available modules from the Terraform Registry, or write your own.
### Collaborate
Since your configuration is written in a file, you can commit it to a Version Control System (VCS) and use [HCP Terraform](/terraform/intro/terraform-editions#hcp-terraform) to efficiently manage Terraform workflows across teams. HCP Terraform runs Terraform in a consistent, reliable environment and provides secure access to shared state and secret data, role-based access controls, a private registry for sharing both modules and providers, and more.
-> **Tip:** Learn more about [Terraform use cases](/terraform/intro/use-cases) and [how Terraform compares to alternatives](/terraform/intro/vs).
## Community
We welcome questions, suggestions, and contributions from the community.
- Ask questions in [HashiCorp Discuss](https://discuss.hashicorp.com/c/terraform-core/27).
- Read our [contributing guide](https://github.com/hashicorp/terraform/blob/main/.github/CONTRIBUTING.md).
- [Submit an issue](https://github.com/hashicorp/terraform/issues/new/choose) for bugs and feature requests.

View file

@ -1,61 +0,0 @@
---
page_title: Adopt Terraform
description: Establish strong foundational practices that support future scale and make Terraform operations predictable and secure.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Adopt Terraform
An individual practitioner can establish strong foundational practices that support future scale and make Terraform operations predictable and secure.
## Use version control
Store your Terraform configuration in a version control system, such as Git, just as you would with your application code. Terraform configuration files are code, and will benefit from the same features as your application in a version control repository such as versioning and easier code reviews.
<Warning>
Do not store [`terraform.tfstate` state files](/terraform/language/state), provider credentials, or sensitive values in version control. Use a [gitignore file](https://github.com/github/gitignore/blob/main/Terraform.gitignore) to avoid accidentally committing sensitive files.
</Warning>
You can [connect your VCS provider to HCP Terraform](/terraform/cloud-docs/vcs) to automatically initiate Terraform runs and view [speculative plans that let you preview your infrastructure changes](/terraform/cloud-docs/run/ui#speculative-plans-on-pull-requests) in your pull requests.
## Reuse code with modules
Terraform modules group resources that you usually deploy together, letting you define reusable units of infrastructure code. For example, when you create a VPC in AWS, you may also need to create subnets, the route table, the internet gateway, security groups, and more. Instead of defining the individual resources and configuring the relationships between them every time you need a new VPC, you can use the [VPC module](https://registry.terraform.io/modules/terraform-aws-modules/vpc/aws/latest), which you can customize using input variables to quickly create the required infrastructure. The [public Terraform module registry](https://registry.terraform.io/browse/modules) offers many modules that encode best practices for common use cases.
You can also create your own modules to deploy the specific infrastructure required by your services. Even a small three-tier application may require many Terraform-managed resources. A module lets you contain that complexity, turning each deployment of the application stack into a short, readable, and reusable configuration. The following Terraform configuration references a local module stored at `./modules/appstack` that takes in two arguments named `web_instance_count` and `api_instance_count`:
```hcl
module "appstack" {
source = "./modules/appstack"
web_instance_count = 2
api_instance_count = 1
}
output "web_instance_ips" {
value = module.appstack.web_ips
}
```
[Follow our tutorials to learn how to use and develop modules](/terraform/tutorials/modules/module) and explore the [public Terraform module registry](https://registry.terraform.io/browse/modules).
## Use secrets storage
Your configuration may rely on sensitive values, such as provider credentials. Although you can mark certain variables as sensitive to prevent displaying them as plaintext in run output, a more robust solution is to use secrets storage such as [HashiCorp Vault](/vault)
Vault securely stores sensitive information such as credentials and provides granular access control. You can integrate Vault into your Terraform configuration using the [Vault provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs/data-sources/generic_secret). If you deploy your infrastructure to a major cloud provider, such as AWS, you can also [generate short-lived credentials with Vault](/terraform/tutorials/secrets/secrets-vault) or use [dynamic provider credentials](/terraform/cloud-docs/workspaces/dynamic-provider-credentials), which prevents having to store credentials.
Vault also integrates into many popular CI/CD solutions such as [GitHub, Jenkins, and CircleCI](/well-architected-framework/security/security-cicd-vault). Vault provides a central system to store and access data, which lets CI/CD pipelines push and pull secrets programmatically.
## Next steps
Multiple developers working on the same codebase introduces a new set of challenges, but solutions such as remote state backends help ease collaboration and coordinate execution.
[Learn how to collaborate with Terraform](/terraform/intro/phases/collaborate).

View file

@ -1,56 +0,0 @@
---
page_title: Collaborate with Terraform
description: Ease collaboration and coordinate execution across your team.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Collaborate with Terraform
Multiple developers working on the same codebase introduces a new set of challenges, but solutions such as remote state backends help ease collaboration and coordinate execution.
## Use remote state storage
As more team members work on Terraform configuration, you should implement remote state storage to support collaboration. HCP Terraform and remote backends implement several features to help you safely manage your Terraform state:
- **Storage:** Remote state storage lets you manage infrastructure collaboratively and securely. Different state stores may also support additional features for state management, such as encryption, versioning, automated backups, redundancy, and more.
- **Locking:** Some remote state storage options support [state locking](/terraform/language/state/locking). State locking prevents concurrent Terraform operations on single state files.
- **Execution:** HCP Terraform and Terraform Enterprise support executing Terraform operations in stable, remote environments.
Since state files may contain sensitive data, refer to your backend documentation and, if supported, use [state encryption](/well-architected-framework/security/security-sensitive-data). [HCP Terraform and Terraform Enterprise](/terraform/cloud-docs/architectural-details/data-security#data-security) both automatically encrypt state, and [AWS, GCP, and Azure](/well-architected-framework/security/security-sensitive-data#storing-terraform-state) backends can implement encryption as well.
As your team grows, you may run into the risk of concurrent operations on state files. If supported by your remote storage solution, use [state locking](/terraform/language/state/locking) to prevent unpredictable outcomes or corrupted data. [HCP Terraform and Terraform Enterprise](/terraform/cli/cloud/settings) support state locking by default, but other state storage implementations require additional configuration. For example, the [AWS S3 remote backend](/terraform/language/backend/s3) requires that a [DynamoDB table](/terraform/language/backend/s3#dynamodb-table-permissions) for state locking.
| | Storage | Locking | Execution |
|------------------------------|---------|--------------|-----------|
| HCP Terraform / Enterprise | Yes | Yes | Yes |
| Amazon S3 | Yes | via DynamoDB | No |
| Azure Storage | Yes | Yes | No |
| Google Cloud Storage | Yes | Yes | No |
[Get started with HCP Terraform](/terraform/tutorials/cloud-get-started) and learn how to [securely store your Terraform state](/well-architected-framework/security/security-sensitive-data#storing-terraform-state).
## Implement code reviews
Implement good code practices for your Terraform configuration, including using pull requests for code changes and performing proper code reviews.
Code reviews can prevent introducing errors into your infrastructure configuration. They also help team members share their knowledge of the code base and enforce coding standards.
Use the integrations offered by your version control system to help with your code reviews. For example, HCP Terraform's VCS integration [generates speculative plans](/terraform/cloud-docs/run/ui#speculative-plans-on-pull-requests) for each pull request, showing the exact changes that Terraform will make to your infrastructure.
## Automate deployments with CI/CD
A CI/CD pipeline offers a consistent process for shipping new features and fixes. By storing your Terraform configuration in version control, you define a single source of truth for your infrastructure configuration and can automate your deployments. You can configure a CI pipeline to automatically start a Terraform plan and apply operation for any changes to your code.
Terraform [integrates](/terraform/tutorials/automation/automate-terraform) with many automation solutions. If you do not have an existing CI/CD workflow, HashiCorp's [Setup Terraform GitHub action](/terraform/tutorials/automation/github-actions) sets up and configures the Terraform CLI in your Github Actions workflow.
## Next steps
As Terraform usage expands across your organization, you will need to decide how to define boundaries of infrastructure ownership.
You will also need to decide on a cloud deployment strategy based on your organization's practices and needs. Possible approaches include using a single account in a single cloud provider, a hybrid or multi-cloud approach, or to divide up resources across accounts by environment. Regardless of your implementation, Terraform lets you manage your infrastructure with a consistent workflow.
[Learn how to scale Terraform](/terraform/intro/phases/scale).

View file

@ -1,28 +0,0 @@
---
page_title: Govern Terraform
description: Use codified, automated policy enforcement to govern your organization's standards and best practices.
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Govern Terraform
As your teams grow, a common operational challenge is deciding how to enforce your organization's standards and practices. Using codified, automated policy enforcement with Sentinel or OPA ensures consistent application of your standards.
## Govern infrastructure through policy
You can use policy as code to ensure your infrastructure meets your organization's security, governance, and cost requirements. You can configure your workflows to automatically run policy checks as part of your Terraform operations and set conditions for how to handle policy failures. Soft enforcement lets prompts a user to approve an operation that fails a policy check, and hard enforcement blocks the operation entirely.
You can define policies that set standards for both your infrastructure configuration itself, and for the workflows around configuration deployment. Some examples of policy rules you can define include which ports are open in a firewall, the permitted sizes of virtual machines, or that deployments cannot take place on Fridays. In HCP Terraform and Terraform Enterprise you can use either [OPA](/terraform/cloud-docs/policy-enforcement/opa) or [Sentinel](https://www.hashicorp.com/sentinel) for your policy definitions.
Learn how to [write a Sentinel policy for a Terraform Deployment](/terraform/tutorials/policy/sentinel-policy) and how to [detect infrastructure drift and enforce OPA policies](/terraform/tutorials/cloud/drift-and-opa).
## Next steps
This guide introduces considerations to keep in mind as your organization adopts Terraform, but there are many more topics to explore. [HCP Terraform](/terraform/tutorials/cloud-get-started) provides a place to get started with many of these topics, and you can [get started for free](https://app.terraform.io/public/signup/account).
The [HashiCorp Well-Architected Framework](/well-architected-framework) provides more in-depth information on how to adopt and scale your use of Terraform.

View file

@ -1,46 +0,0 @@
---
page_title: Phases of Terraform Adoption
description: Evolve your Terraform strategy as adoption grows within your organization
---
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
# Phases of Terraform Adoption
As more of your organization adopts Terraform, your infrastructure provisioning workflows will need to change and adapt. The workflows that are suitable for individual practitioners may not scale to larger enterprises. This guide will help you plan your organization's Terraform adoption strategy and presents workflow considerations that you should keep in mind to support future scale. This guide focuses on challenges faced by larger organizations, but we recommend implementing each practice as early as you can to help you scale smoothly.
## Adopt
An individual practitioner can establish strong foundational practices that support future scale and make Terraform operations predictable and secure.
[Learn how to adopt Terraform](/terraform/intro/phases/adopt)
## Collaborate
Multiple developers working on the same codebase introduces a new set of challenges, but solutions such as remote state backends help ease collaboration and coordinate execution.
[Learn how to collaborate with Terraform](/terraform/intro/phases/collaborate).
## Scale
As Terraform usage expands across your organization, you will need to decide how to define boundaries of infrastructure ownership.
You will also need to decide on a cloud deployment strategy based on your organization's practices and needs. Possible approaches include using a single account in a single cloud provider, a hybrid or multi-cloud approach, or to divide up resources across accounts by environment. Regardless of your implementation, Terraform lets you manage your infrastructure with a consistent workflow.
[Learn how to scale Terraform](/terraform/intro/phases/scale).
## Govern
As your teams grow, a common operational challenge is deciding how to enforce your organization's standards and practices. Using codified, automated policy enforcement with Sentinel or OPA ensures consistent application of your standards.
[Learn how to govern your organization's best practices](/terraform/intro/phases/govern).
## Next steps
This guide introduces considerations to keep in mind as your organization adopts Terraform, but there are many more topics to explore. To learn more Terraform best practices, refer to [Terraform style guide](/terraform/language/style). The [HashiCorp Well-Architected Framework](/well-architected-framework) provides more in-depth information on how to adopt and scale your use of Terraform.
[HCP Terraform](/terraform/tutorials/cloud-get-started) provides a place to get started with many of these topics, and you can [get started for free](https://app.terraform.io/public/signup/account).

Some files were not shown because too many files have changed in this diff Show more