From 6d11e670c16fae3adccb72475dc9217c2b578a03 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Mon, 11 Aug 2025 10:25:18 +0100 Subject: [PATCH] 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 --- .github/ISSUE_TEMPLATE/config.yml | 3 + .../ISSUE_TEMPLATE/documentation_issue.yml | 76 - .gitignore | 5 - CODEOWNERS | 22 - Makefile | 14 +- README.md | 2 +- commands.go | 2 +- help.go | 2 +- website/Makefile | 60 - website/README.md | 87 +- website/data/cli-nav-data.json | 422 - website/data/internals-nav-data.json | 64 - website/data/intro-nav-data.json | 34 - website/data/language-nav-data.json | 1121 - website/docs/cli/auth/index.mdx | 39 - .../docs/cli/cloud/command-line-arguments.mdx | 30 - website/docs/cli/cloud/index.mdx | 31 - website/docs/cli/cloud/settings.mdx | 164 - website/docs/cli/code/index.mdx | 53 - website/docs/cli/commands/0.12upgrade.mdx | 123 - website/docs/cli/commands/0.13upgrade.mdx | 95 - website/docs/cli/commands/apply.mdx | 125 - website/docs/cli/commands/console.mdx | 151 - website/docs/cli/commands/destroy.mdx | 59 - website/docs/cli/commands/fmt.mdx | 68 - website/docs/cli/commands/force-unlock.mdx | 35 - website/docs/cli/commands/get.mdx | 30 - website/docs/cli/commands/graph.mdx | 60 - website/docs/cli/commands/import.mdx | 169 - website/docs/cli/commands/index.mdx | 174 - website/docs/cli/commands/init.mdx | 211 - website/docs/cli/commands/login.mdx | 49 - website/docs/cli/commands/logout.mdx | 39 - website/docs/cli/commands/modules.mdx | 94 - website/docs/cli/commands/output.mdx | 131 - website/docs/cli/commands/plan.mdx | 373 - website/docs/cli/commands/providers.mdx | 25 - website/docs/cli/commands/providers/lock.mdx | 182 - .../docs/cli/commands/providers/mirror.mdx | 73 - .../docs/cli/commands/providers/schema.mdx | 219 - website/docs/cli/commands/refresh.mdx | 60 - website/docs/cli/commands/show.mdx | 56 - website/docs/cli/commands/state/index.mdx | 60 - website/docs/cli/commands/state/list.mdx | 94 - website/docs/cli/commands/state/mv.mdx | 193 - website/docs/cli/commands/state/pull.mdx | 33 - website/docs/cli/commands/state/push.mdx | 49 - .../cli/commands/state/replace-provider.mdx | 57 - website/docs/cli/commands/state/rm.mdx | 134 - website/docs/cli/commands/state/show.mdx | 95 - website/docs/cli/commands/taint.mdx | 67 - website/docs/cli/commands/test.mdx | 235 - website/docs/cli/commands/untaint.mdx | 80 - website/docs/cli/commands/validate.mdx | 219 - website/docs/cli/commands/version.mdx | 59 - .../docs/cli/commands/workspace/delete.mdx | 49 - website/docs/cli/commands/workspace/index.mdx | 22 - website/docs/cli/commands/workspace/list.mdx | 30 - website/docs/cli/commands/workspace/new.mdx | 56 - .../docs/cli/commands/workspace/select.mdx | 37 - website/docs/cli/commands/workspace/show.mdx | 27 - website/docs/cli/config/config-file.mdx | 544 - .../docs/cli/config/environment-variables.mdx | 183 - website/docs/cli/config/index.mdx | 28 - website/docs/cli/import/index.mdx | 48 - website/docs/cli/import/usage.mdx | 94 - website/docs/cli/index.mdx | 25 - website/docs/cli/init/index.mdx | 77 - website/docs/cli/inspect/index.mdx | 41 - website/docs/cli/plugins/index.mdx | 62 - website/docs/cli/plugins/signing.mdx | 35 - website/docs/cli/run/index.mdx | 80 - website/docs/cli/state/index.mdx | 38 - website/docs/cli/state/inspect.mdx | 27 - website/docs/cli/state/move.mdx | 52 - website/docs/cli/state/recover.mdx | 25 - .../docs/cli/state/resource-addressing.mdx | 144 - website/docs/cli/state/taint.mdx | 70 - website/docs/cli/test/index.mdx | 60 - website/docs/cli/workspaces/index.mdx | 91 - website/docs/internals/archiving.mdx | 34 - .../docs/internals/credentials-helpers.mdx | 181 - website/docs/internals/debugging.mdx | 37 - website/docs/internals/functions-meta.mdx | 107 - website/docs/internals/graph.mdx | 115 - website/docs/internals/index.mdx | 17 - website/docs/internals/json-format.mdx | 778 - website/docs/internals/login-protocol.mdx | 116 - .../docs/internals/machine-readable-ui.mdx | 1072 - .../internals/module-registry-protocol.mdx | 226 - website/docs/internals/provider-meta.mdx | 84 - .../provider-network-mirror-protocol.mdx | 276 - .../internals/provider-registry-protocol.mdx | 346 - .../internals/remote-service-discovery.mdx | 118 - website/docs/intro/core-workflow.mdx | 344 - website/docs/intro/index.mdx | 70 - website/docs/intro/phases/adopt.mdx | 61 - website/docs/intro/phases/collaborate.mdx | 56 - website/docs/intro/phases/govern.mdx | 28 - website/docs/intro/phases/index.mdx | 46 - website/docs/intro/phases/scale.mdx | 46 - website/docs/intro/terraform-editions.mdx | 76 - website/docs/intro/use-cases.mdx | 88 - website/docs/intro/vs/boto.mdx | 26 - website/docs/intro/vs/chef-puppet.mdx | 29 - website/docs/intro/vs/cloudformation.mdx | 43 - website/docs/intro/vs/custom.mdx | 43 - website/docs/intro/vs/index.mdx | 28 - website/docs/language/attr-as-blocks.mdx | 182 - website/docs/language/backend/azurerm.mdx | 587 - website/docs/language/backend/consul.mdx | 64 - website/docs/language/backend/cos.mdx | 229 - website/docs/language/backend/gcs.mdx | 142 - website/docs/language/backend/http.mdx | 81 - website/docs/language/backend/index.mdx | 242 - website/docs/language/backend/kubernetes.mdx | 78 - website/docs/language/backend/local.mdx | 101 - website/docs/language/backend/oci.mdx | 206 - website/docs/language/backend/oss.mdx | 144 - website/docs/language/backend/pg.mdx | 113 - website/docs/language/backend/remote.mdx | 251 - website/docs/language/backend/s3.mdx | 623 - website/docs/language/checks/index.mdx | 127 - website/docs/language/data-sources/index.mdx | 268 - .../language/expressions/conditionals.mdx | 86 - .../expressions/custom-conditions.mdx | 420 - .../language/expressions/dynamic-blocks.mdx | 161 - website/docs/language/expressions/for.mdx | 213 - .../language/expressions/function-calls.mdx | 120 - website/docs/language/expressions/index.mdx | 80 - .../docs/language/expressions/operators.mdx | 113 - .../docs/language/expressions/references.mdx | 364 - website/docs/language/expressions/splat.mdx | 134 - website/docs/language/expressions/strings.mdx | 234 - .../language/expressions/type-constraints.mdx | 447 - website/docs/language/expressions/types.mdx | 194 - .../expressions/version-constraints.mdx | 104 - .../docs/language/files/dependency-lock.mdx | 425 - website/docs/language/files/index.mdx | 64 - website/docs/language/files/override.mdx | 166 - website/docs/language/files/tests.mdx | 27 - website/docs/language/functions/abs.mdx | 57 - website/docs/language/functions/abspath.mdx | 29 - website/docs/language/functions/alltrue.mdx | 32 - website/docs/language/functions/anytrue.mdx | 36 - .../docs/language/functions/base64decode.mdx | 52 - .../docs/language/functions/base64encode.mdx | 54 - .../docs/language/functions/base64gzip.mdx | 62 - .../docs/language/functions/base64sha256.mdx | 37 - .../docs/language/functions/base64sha512.mdx | 37 - website/docs/language/functions/basename.mdx | 47 - website/docs/language/functions/bcrypt.mdx | 42 - website/docs/language/functions/can.mdx | 80 - website/docs/language/functions/ceil.mdx | 31 - website/docs/language/functions/chomp.mdx | 33 - website/docs/language/functions/chunklist.mdx | 58 - website/docs/language/functions/cidrhost.mdx | 64 - .../docs/language/functions/cidrnetmask.mdx | 42 - .../docs/language/functions/cidrsubnet.mdx | 177 - .../docs/language/functions/cidrsubnets.mdx | 110 - website/docs/language/functions/coalesce.mdx | 62 - .../docs/language/functions/coalescelist.mdx | 48 - website/docs/language/functions/compact.mdx | 26 - website/docs/language/functions/concat.mdx | 37 - website/docs/language/functions/contains.mdx | 30 - website/docs/language/functions/csvdecode.mdx | 101 - website/docs/language/functions/dirname.mdx | 45 - website/docs/language/functions/distinct.mdx | 30 - website/docs/language/functions/element.mdx | 51 - website/docs/language/functions/endswith.mdx | 33 - .../language/functions/ephemeralasnull.mdx | 91 - website/docs/language/functions/file.mdx | 52 - .../docs/language/functions/filebase64.mdx | 52 - .../language/functions/filebase64sha256.mdx | 21 - .../language/functions/filebase64sha512.mdx | 21 - .../docs/language/functions/fileexists.mdx | 40 - website/docs/language/functions/filemd5.mdx | 26 - website/docs/language/functions/fileset.mdx | 83 - website/docs/language/functions/filesha1.mdx | 54 - .../docs/language/functions/filesha256.mdx | 56 - .../docs/language/functions/filesha512.mdx | 58 - website/docs/language/functions/flatten.mdx | 145 - website/docs/language/functions/floor.mdx | 31 - website/docs/language/functions/format.mdx | 158 - .../docs/language/functions/formatdate.mdx | 111 - .../docs/language/functions/formatlist.mdx | 55 - website/docs/language/functions/indent.mdx | 41 - website/docs/language/functions/index.mdx | 44 - .../language/functions/index_function.mdx | 40 - .../docs/language/functions/issensitive.mdx | 33 - website/docs/language/functions/join.mdx | 37 - .../docs/language/functions/jsondecode.mdx | 52 - .../docs/language/functions/jsonencode.mdx | 56 - website/docs/language/functions/keys.mdx | 32 - website/docs/language/functions/length.mdx | 45 - website/docs/language/functions/list.mdx | 32 - website/docs/language/functions/log.mdx | 39 - website/docs/language/functions/lookup.mdx | 36 - website/docs/language/functions/lower.mdx | 32 - website/docs/language/functions/map.mdx | 35 - website/docs/language/functions/matchkeys.mdx | 76 - website/docs/language/functions/max.mdx | 33 - website/docs/language/functions/md5.mdx | 38 - website/docs/language/functions/merge.mdx | 57 - website/docs/language/functions/min.mdx | 33 - .../docs/language/functions/nonsensitive.mdx | 132 - website/docs/language/functions/one.mdx | 125 - website/docs/language/functions/parseint.mdx | 56 - .../docs/language/functions/pathexpand.mdx | 60 - .../docs/language/functions/plantimestamp.mdx | 60 - website/docs/language/functions/pow.mdx | 23 - website/docs/language/functions/range.mdx | 145 - website/docs/language/functions/regex.mdx | 167 - website/docs/language/functions/regexall.mdx | 63 - website/docs/language/functions/replace.mdx | 43 - website/docs/language/functions/reverse.mdx | 30 - .../docs/language/functions/rsadecrypt.mdx | 37 - website/docs/language/functions/sensitive.mdx | 48 - .../language/functions/setintersection.mdx | 81 - .../docs/language/functions/setproduct.mdx | 287 - .../docs/language/functions/setsubtract.mdx | 48 - website/docs/language/functions/setunion.mdx | 48 - website/docs/language/functions/sha1.mdx | 37 - website/docs/language/functions/sha256.mdx | 37 - website/docs/language/functions/sha512.mdx | 35 - website/docs/language/functions/signum.mdx | 26 - website/docs/language/functions/slice.mdx | 37 - website/docs/language/functions/sort.mdx | 32 - website/docs/language/functions/split.mdx | 45 - .../docs/language/functions/startswith.mdx | 33 - .../docs/language/functions/strcontains.mdx | 31 - website/docs/language/functions/strrev.mdx | 32 - website/docs/language/functions/substr.mdx | 52 - website/docs/language/functions/sum.mdx | 25 - .../docs/language/functions/templatefile.mdx | 156 - .../language/functions/templatestring.mdx | 74 - .../language/functions/terraform-applying.mdx | 50 - .../functions/terraform-decode_tfvars.mdx | 76 - .../functions/terraform-encode_expr.mdx | 78 - .../functions/terraform-encode_tfvars.mdx | 78 - .../language/functions/textdecodebase64.mdx | 48 - .../language/functions/textencodebase64.mdx | 57 - website/docs/language/functions/timeadd.mdx | 73 - website/docs/language/functions/timecmp.mdx | 72 - website/docs/language/functions/timestamp.mdx | 47 - website/docs/language/functions/title.mdx | 30 - website/docs/language/functions/tobool.mdx | 42 - website/docs/language/functions/tolist.mdx | 45 - website/docs/language/functions/tomap.mdx | 39 - website/docs/language/functions/tonumber.mdx | 37 - website/docs/language/functions/toset.mdx | 56 - website/docs/language/functions/tostring.mdx | 38 - website/docs/language/functions/transpose.mdx | 35 - website/docs/language/functions/trim.mdx | 46 - .../docs/language/functions/trimprefix.mdx | 40 - website/docs/language/functions/trimspace.mdx | 33 - .../docs/language/functions/trimsuffix.mdx | 40 - website/docs/language/functions/try.mdx | 117 - website/docs/language/functions/type.mdx | 87 - website/docs/language/functions/upper.mdx | 32 - website/docs/language/functions/urlencode.mdx | 37 - website/docs/language/functions/uuid.mdx | 40 - website/docs/language/functions/uuidv5.mdx | 86 - website/docs/language/functions/values.mdx | 34 - .../docs/language/functions/yamldecode.mdx | 105 - .../docs/language/functions/yamlencode.mdx | 83 - website/docs/language/functions/zipmap.mdx | 39 - .../import/generating-configuration.mdx | 151 - website/docs/language/import/index.mdx | 217 - website/docs/language/index.mdx | 125 - .../docs/language/meta-arguments/count.mdx | 130 - .../language/meta-arguments/depends_on.mdx | 79 - .../docs/language/meta-arguments/for_each.mdx | 279 - .../language/meta-arguments/lifecycle.mdx | 188 - .../meta-arguments/module-providers.mdx | 132 - .../meta-arguments/resource-provider.mdx | 65 - .../language/modules/develop/composition.mdx | 382 - .../docs/language/modules/develop/index.mdx | 91 - .../language/modules/develop/providers.mdx | 369 - .../docs/language/modules/develop/publish.mdx | 47 - .../language/modules/develop/refactoring.mdx | 456 - .../language/modules/develop/structure.mdx | 135 - website/docs/language/modules/index.mdx | 76 - website/docs/language/modules/sources.mdx | 489 - website/docs/language/modules/syntax.mdx | 227 - website/docs/language/moved.mdx | 59 - .../docs/language/providers/configuration.mdx | 204 - website/docs/language/providers/index.mdx | 142 - .../docs/language/providers/requirements.mdx | 434 - website/docs/language/resources/behavior.mdx | 117 - .../language/resources/ephemeral/index.mdx | 87 - .../resources/ephemeral/reference.mdx | 101 - .../resources/ephemeral/write-only.mdx | 256 - website/docs/language/resources/index.mdx | 42 - .../resources/provisioners/connection.mdx | 220 - .../language/resources/provisioners/file.mdx | 135 - .../resources/provisioners/local-exec.mdx | 110 - .../resources/provisioners/null_resource.mdx | 56 - .../resources/provisioners/remote-exec.mdx | 95 - .../resources/provisioners/syntax.mdx | 357 - website/docs/language/resources/syntax.mdx | 220 - .../language/resources/terraform-data.mdx | 88 - .../docs/language/stacks/create/config.mdx | 97 - .../stacks/create/declare-providers.mdx | 158 - .../language/stacks/deploy/authenticate.mdx | 315 - .../language/stacks/deploy/conditions.mdx | 113 - .../docs/language/stacks/deploy/config.mdx | 121 - .../docs/language/stacks/deploy/pass-data.mdx | 118 - website/docs/language/stacks/design.mdx | 72 - website/docs/language/stacks/index.mdx | 80 - .../language/stacks/reference/tfdeploy.mdx | 433 - .../language/stacks/reference/tfstack.mdx | 313 - .../stacks/reference/tfstacks-cli.mdx | 171 - website/docs/language/stacks/use-cases.mdx | 246 - website/docs/language/state/backends.mdx | 78 - website/docs/language/state/import.mdx | 19 - website/docs/language/state/index.mdx | 89 - website/docs/language/state/locking.mdx | 46 - website/docs/language/state/purpose.mdx | 115 - website/docs/language/state/refactor.mdx | 275 - .../docs/language/state/remote-state-data.mdx | 214 - website/docs/language/state/remote.mdx | 69 - .../docs/language/state/sensitive-data.mdx | 48 - website/docs/language/state/workspaces.mdx | 79 - website/docs/language/style.mdx | 687 - .../docs/language/syntax/configuration.mdx | 135 - website/docs/language/syntax/index.mdx | 29 - website/docs/language/syntax/json.mdx | 475 - website/docs/language/terraform.mdx | 436 - website/docs/language/tests/index.mdx | 1018 - website/docs/language/tests/mocking.mdx | 362 - .../docs/language/upgrade-guides/index.mdx | 20 - .../language/v1-compatibility-promises.mdx | 661 - website/docs/language/values/index.mdx | 26 - website/docs/language/values/locals.mdx | 123 - website/docs/language/values/outputs.mdx | 249 - website/docs/language/values/variables.mdx | 592 - website/img/docs/concrete-plan.png | Bin 342850 -> 0 bytes website/img/docs/graph-example.png | Bin 27282 -> 0 bytes website/img/docs/in-progress-apply.png | Bin 334825 -> 0 bytes website/img/docs/intro-terraform-apis.png | Bin 115073 -> 0 bytes website/img/docs/intro-terraform-workflow.png | Bin 347426 -> 0 bytes .../img/docs/manually-pasted-plan-output.png | Bin 73336 -> 0 bytes website/img/docs/plan-comments.png | Bin 374946 -> 0 bytes website/img/docs/pr-plan.png | Bin 197934 -> 0 bytes website/img/docs/pull-request.png | Bin 108925 -> 0 bytes website/img/docs/stacks-example.png | Bin 63910 -> 0 bytes website/package-lock.json | 29243 ---------------- website/package.json | 17 - website/scripts/should-build.sh | 21 - website/scripts/website-build.sh | 55 - website/scripts/website-start.sh | 47 - website/vercel.json | 5 - 353 files changed, 8 insertions(+), 70469 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/documentation_issue.yml delete mode 100644 website/Makefile delete mode 100644 website/data/cli-nav-data.json delete mode 100644 website/data/internals-nav-data.json delete mode 100644 website/data/intro-nav-data.json delete mode 100644 website/data/language-nav-data.json delete mode 100644 website/docs/cli/auth/index.mdx delete mode 100644 website/docs/cli/cloud/command-line-arguments.mdx delete mode 100644 website/docs/cli/cloud/index.mdx delete mode 100644 website/docs/cli/cloud/settings.mdx delete mode 100644 website/docs/cli/code/index.mdx delete mode 100644 website/docs/cli/commands/0.12upgrade.mdx delete mode 100644 website/docs/cli/commands/0.13upgrade.mdx delete mode 100644 website/docs/cli/commands/apply.mdx delete mode 100644 website/docs/cli/commands/console.mdx delete mode 100644 website/docs/cli/commands/destroy.mdx delete mode 100644 website/docs/cli/commands/fmt.mdx delete mode 100644 website/docs/cli/commands/force-unlock.mdx delete mode 100644 website/docs/cli/commands/get.mdx delete mode 100644 website/docs/cli/commands/graph.mdx delete mode 100644 website/docs/cli/commands/import.mdx delete mode 100644 website/docs/cli/commands/index.mdx delete mode 100644 website/docs/cli/commands/init.mdx delete mode 100644 website/docs/cli/commands/login.mdx delete mode 100644 website/docs/cli/commands/logout.mdx delete mode 100644 website/docs/cli/commands/modules.mdx delete mode 100644 website/docs/cli/commands/output.mdx delete mode 100644 website/docs/cli/commands/plan.mdx delete mode 100644 website/docs/cli/commands/providers.mdx delete mode 100644 website/docs/cli/commands/providers/lock.mdx delete mode 100644 website/docs/cli/commands/providers/mirror.mdx delete mode 100644 website/docs/cli/commands/providers/schema.mdx delete mode 100644 website/docs/cli/commands/refresh.mdx delete mode 100644 website/docs/cli/commands/show.mdx delete mode 100644 website/docs/cli/commands/state/index.mdx delete mode 100644 website/docs/cli/commands/state/list.mdx delete mode 100644 website/docs/cli/commands/state/mv.mdx delete mode 100644 website/docs/cli/commands/state/pull.mdx delete mode 100644 website/docs/cli/commands/state/push.mdx delete mode 100644 website/docs/cli/commands/state/replace-provider.mdx delete mode 100644 website/docs/cli/commands/state/rm.mdx delete mode 100644 website/docs/cli/commands/state/show.mdx delete mode 100644 website/docs/cli/commands/taint.mdx delete mode 100644 website/docs/cli/commands/test.mdx delete mode 100644 website/docs/cli/commands/untaint.mdx delete mode 100644 website/docs/cli/commands/validate.mdx delete mode 100644 website/docs/cli/commands/version.mdx delete mode 100644 website/docs/cli/commands/workspace/delete.mdx delete mode 100644 website/docs/cli/commands/workspace/index.mdx delete mode 100644 website/docs/cli/commands/workspace/list.mdx delete mode 100644 website/docs/cli/commands/workspace/new.mdx delete mode 100644 website/docs/cli/commands/workspace/select.mdx delete mode 100644 website/docs/cli/commands/workspace/show.mdx delete mode 100644 website/docs/cli/config/config-file.mdx delete mode 100644 website/docs/cli/config/environment-variables.mdx delete mode 100644 website/docs/cli/config/index.mdx delete mode 100644 website/docs/cli/import/index.mdx delete mode 100644 website/docs/cli/import/usage.mdx delete mode 100644 website/docs/cli/index.mdx delete mode 100644 website/docs/cli/init/index.mdx delete mode 100644 website/docs/cli/inspect/index.mdx delete mode 100644 website/docs/cli/plugins/index.mdx delete mode 100644 website/docs/cli/plugins/signing.mdx delete mode 100644 website/docs/cli/run/index.mdx delete mode 100644 website/docs/cli/state/index.mdx delete mode 100644 website/docs/cli/state/inspect.mdx delete mode 100644 website/docs/cli/state/move.mdx delete mode 100644 website/docs/cli/state/recover.mdx delete mode 100644 website/docs/cli/state/resource-addressing.mdx delete mode 100644 website/docs/cli/state/taint.mdx delete mode 100644 website/docs/cli/test/index.mdx delete mode 100644 website/docs/cli/workspaces/index.mdx delete mode 100644 website/docs/internals/archiving.mdx delete mode 100644 website/docs/internals/credentials-helpers.mdx delete mode 100644 website/docs/internals/debugging.mdx delete mode 100644 website/docs/internals/functions-meta.mdx delete mode 100644 website/docs/internals/graph.mdx delete mode 100644 website/docs/internals/index.mdx delete mode 100644 website/docs/internals/json-format.mdx delete mode 100644 website/docs/internals/login-protocol.mdx delete mode 100644 website/docs/internals/machine-readable-ui.mdx delete mode 100644 website/docs/internals/module-registry-protocol.mdx delete mode 100644 website/docs/internals/provider-meta.mdx delete mode 100644 website/docs/internals/provider-network-mirror-protocol.mdx delete mode 100644 website/docs/internals/provider-registry-protocol.mdx delete mode 100644 website/docs/internals/remote-service-discovery.mdx delete mode 100644 website/docs/intro/core-workflow.mdx delete mode 100644 website/docs/intro/index.mdx delete mode 100644 website/docs/intro/phases/adopt.mdx delete mode 100644 website/docs/intro/phases/collaborate.mdx delete mode 100644 website/docs/intro/phases/govern.mdx delete mode 100644 website/docs/intro/phases/index.mdx delete mode 100644 website/docs/intro/phases/scale.mdx delete mode 100644 website/docs/intro/terraform-editions.mdx delete mode 100644 website/docs/intro/use-cases.mdx delete mode 100644 website/docs/intro/vs/boto.mdx delete mode 100644 website/docs/intro/vs/chef-puppet.mdx delete mode 100644 website/docs/intro/vs/cloudformation.mdx delete mode 100644 website/docs/intro/vs/custom.mdx delete mode 100644 website/docs/intro/vs/index.mdx delete mode 100644 website/docs/language/attr-as-blocks.mdx delete mode 100644 website/docs/language/backend/azurerm.mdx delete mode 100644 website/docs/language/backend/consul.mdx delete mode 100644 website/docs/language/backend/cos.mdx delete mode 100644 website/docs/language/backend/gcs.mdx delete mode 100644 website/docs/language/backend/http.mdx delete mode 100644 website/docs/language/backend/index.mdx delete mode 100644 website/docs/language/backend/kubernetes.mdx delete mode 100644 website/docs/language/backend/local.mdx delete mode 100644 website/docs/language/backend/oci.mdx delete mode 100644 website/docs/language/backend/oss.mdx delete mode 100644 website/docs/language/backend/pg.mdx delete mode 100644 website/docs/language/backend/remote.mdx delete mode 100644 website/docs/language/backend/s3.mdx delete mode 100644 website/docs/language/checks/index.mdx delete mode 100644 website/docs/language/data-sources/index.mdx delete mode 100644 website/docs/language/expressions/conditionals.mdx delete mode 100644 website/docs/language/expressions/custom-conditions.mdx delete mode 100644 website/docs/language/expressions/dynamic-blocks.mdx delete mode 100644 website/docs/language/expressions/for.mdx delete mode 100644 website/docs/language/expressions/function-calls.mdx delete mode 100644 website/docs/language/expressions/index.mdx delete mode 100644 website/docs/language/expressions/operators.mdx delete mode 100644 website/docs/language/expressions/references.mdx delete mode 100644 website/docs/language/expressions/splat.mdx delete mode 100644 website/docs/language/expressions/strings.mdx delete mode 100644 website/docs/language/expressions/type-constraints.mdx delete mode 100644 website/docs/language/expressions/types.mdx delete mode 100644 website/docs/language/expressions/version-constraints.mdx delete mode 100644 website/docs/language/files/dependency-lock.mdx delete mode 100644 website/docs/language/files/index.mdx delete mode 100644 website/docs/language/files/override.mdx delete mode 100644 website/docs/language/files/tests.mdx delete mode 100644 website/docs/language/functions/abs.mdx delete mode 100644 website/docs/language/functions/abspath.mdx delete mode 100644 website/docs/language/functions/alltrue.mdx delete mode 100644 website/docs/language/functions/anytrue.mdx delete mode 100644 website/docs/language/functions/base64decode.mdx delete mode 100644 website/docs/language/functions/base64encode.mdx delete mode 100644 website/docs/language/functions/base64gzip.mdx delete mode 100644 website/docs/language/functions/base64sha256.mdx delete mode 100644 website/docs/language/functions/base64sha512.mdx delete mode 100644 website/docs/language/functions/basename.mdx delete mode 100644 website/docs/language/functions/bcrypt.mdx delete mode 100644 website/docs/language/functions/can.mdx delete mode 100644 website/docs/language/functions/ceil.mdx delete mode 100644 website/docs/language/functions/chomp.mdx delete mode 100644 website/docs/language/functions/chunklist.mdx delete mode 100644 website/docs/language/functions/cidrhost.mdx delete mode 100644 website/docs/language/functions/cidrnetmask.mdx delete mode 100644 website/docs/language/functions/cidrsubnet.mdx delete mode 100644 website/docs/language/functions/cidrsubnets.mdx delete mode 100644 website/docs/language/functions/coalesce.mdx delete mode 100644 website/docs/language/functions/coalescelist.mdx delete mode 100644 website/docs/language/functions/compact.mdx delete mode 100644 website/docs/language/functions/concat.mdx delete mode 100644 website/docs/language/functions/contains.mdx delete mode 100644 website/docs/language/functions/csvdecode.mdx delete mode 100644 website/docs/language/functions/dirname.mdx delete mode 100644 website/docs/language/functions/distinct.mdx delete mode 100644 website/docs/language/functions/element.mdx delete mode 100644 website/docs/language/functions/endswith.mdx delete mode 100644 website/docs/language/functions/ephemeralasnull.mdx delete mode 100644 website/docs/language/functions/file.mdx delete mode 100644 website/docs/language/functions/filebase64.mdx delete mode 100644 website/docs/language/functions/filebase64sha256.mdx delete mode 100644 website/docs/language/functions/filebase64sha512.mdx delete mode 100644 website/docs/language/functions/fileexists.mdx delete mode 100644 website/docs/language/functions/filemd5.mdx delete mode 100644 website/docs/language/functions/fileset.mdx delete mode 100644 website/docs/language/functions/filesha1.mdx delete mode 100644 website/docs/language/functions/filesha256.mdx delete mode 100644 website/docs/language/functions/filesha512.mdx delete mode 100644 website/docs/language/functions/flatten.mdx delete mode 100644 website/docs/language/functions/floor.mdx delete mode 100644 website/docs/language/functions/format.mdx delete mode 100644 website/docs/language/functions/formatdate.mdx delete mode 100644 website/docs/language/functions/formatlist.mdx delete mode 100644 website/docs/language/functions/indent.mdx delete mode 100644 website/docs/language/functions/index.mdx delete mode 100644 website/docs/language/functions/index_function.mdx delete mode 100644 website/docs/language/functions/issensitive.mdx delete mode 100644 website/docs/language/functions/join.mdx delete mode 100644 website/docs/language/functions/jsondecode.mdx delete mode 100644 website/docs/language/functions/jsonencode.mdx delete mode 100644 website/docs/language/functions/keys.mdx delete mode 100644 website/docs/language/functions/length.mdx delete mode 100644 website/docs/language/functions/list.mdx delete mode 100644 website/docs/language/functions/log.mdx delete mode 100644 website/docs/language/functions/lookup.mdx delete mode 100644 website/docs/language/functions/lower.mdx delete mode 100644 website/docs/language/functions/map.mdx delete mode 100644 website/docs/language/functions/matchkeys.mdx delete mode 100644 website/docs/language/functions/max.mdx delete mode 100644 website/docs/language/functions/md5.mdx delete mode 100644 website/docs/language/functions/merge.mdx delete mode 100644 website/docs/language/functions/min.mdx delete mode 100644 website/docs/language/functions/nonsensitive.mdx delete mode 100644 website/docs/language/functions/one.mdx delete mode 100644 website/docs/language/functions/parseint.mdx delete mode 100644 website/docs/language/functions/pathexpand.mdx delete mode 100644 website/docs/language/functions/plantimestamp.mdx delete mode 100644 website/docs/language/functions/pow.mdx delete mode 100644 website/docs/language/functions/range.mdx delete mode 100644 website/docs/language/functions/regex.mdx delete mode 100644 website/docs/language/functions/regexall.mdx delete mode 100644 website/docs/language/functions/replace.mdx delete mode 100644 website/docs/language/functions/reverse.mdx delete mode 100644 website/docs/language/functions/rsadecrypt.mdx delete mode 100644 website/docs/language/functions/sensitive.mdx delete mode 100644 website/docs/language/functions/setintersection.mdx delete mode 100644 website/docs/language/functions/setproduct.mdx delete mode 100644 website/docs/language/functions/setsubtract.mdx delete mode 100644 website/docs/language/functions/setunion.mdx delete mode 100644 website/docs/language/functions/sha1.mdx delete mode 100644 website/docs/language/functions/sha256.mdx delete mode 100644 website/docs/language/functions/sha512.mdx delete mode 100644 website/docs/language/functions/signum.mdx delete mode 100644 website/docs/language/functions/slice.mdx delete mode 100644 website/docs/language/functions/sort.mdx delete mode 100644 website/docs/language/functions/split.mdx delete mode 100644 website/docs/language/functions/startswith.mdx delete mode 100644 website/docs/language/functions/strcontains.mdx delete mode 100644 website/docs/language/functions/strrev.mdx delete mode 100644 website/docs/language/functions/substr.mdx delete mode 100644 website/docs/language/functions/sum.mdx delete mode 100644 website/docs/language/functions/templatefile.mdx delete mode 100644 website/docs/language/functions/templatestring.mdx delete mode 100644 website/docs/language/functions/terraform-applying.mdx delete mode 100644 website/docs/language/functions/terraform-decode_tfvars.mdx delete mode 100644 website/docs/language/functions/terraform-encode_expr.mdx delete mode 100644 website/docs/language/functions/terraform-encode_tfvars.mdx delete mode 100644 website/docs/language/functions/textdecodebase64.mdx delete mode 100644 website/docs/language/functions/textencodebase64.mdx delete mode 100644 website/docs/language/functions/timeadd.mdx delete mode 100644 website/docs/language/functions/timecmp.mdx delete mode 100644 website/docs/language/functions/timestamp.mdx delete mode 100644 website/docs/language/functions/title.mdx delete mode 100644 website/docs/language/functions/tobool.mdx delete mode 100644 website/docs/language/functions/tolist.mdx delete mode 100644 website/docs/language/functions/tomap.mdx delete mode 100644 website/docs/language/functions/tonumber.mdx delete mode 100644 website/docs/language/functions/toset.mdx delete mode 100644 website/docs/language/functions/tostring.mdx delete mode 100644 website/docs/language/functions/transpose.mdx delete mode 100644 website/docs/language/functions/trim.mdx delete mode 100644 website/docs/language/functions/trimprefix.mdx delete mode 100644 website/docs/language/functions/trimspace.mdx delete mode 100644 website/docs/language/functions/trimsuffix.mdx delete mode 100644 website/docs/language/functions/try.mdx delete mode 100644 website/docs/language/functions/type.mdx delete mode 100644 website/docs/language/functions/upper.mdx delete mode 100644 website/docs/language/functions/urlencode.mdx delete mode 100644 website/docs/language/functions/uuid.mdx delete mode 100644 website/docs/language/functions/uuidv5.mdx delete mode 100644 website/docs/language/functions/values.mdx delete mode 100644 website/docs/language/functions/yamldecode.mdx delete mode 100644 website/docs/language/functions/yamlencode.mdx delete mode 100644 website/docs/language/functions/zipmap.mdx delete mode 100644 website/docs/language/import/generating-configuration.mdx delete mode 100644 website/docs/language/import/index.mdx delete mode 100644 website/docs/language/index.mdx delete mode 100644 website/docs/language/meta-arguments/count.mdx delete mode 100644 website/docs/language/meta-arguments/depends_on.mdx delete mode 100644 website/docs/language/meta-arguments/for_each.mdx delete mode 100644 website/docs/language/meta-arguments/lifecycle.mdx delete mode 100644 website/docs/language/meta-arguments/module-providers.mdx delete mode 100644 website/docs/language/meta-arguments/resource-provider.mdx delete mode 100644 website/docs/language/modules/develop/composition.mdx delete mode 100644 website/docs/language/modules/develop/index.mdx delete mode 100644 website/docs/language/modules/develop/providers.mdx delete mode 100644 website/docs/language/modules/develop/publish.mdx delete mode 100644 website/docs/language/modules/develop/refactoring.mdx delete mode 100644 website/docs/language/modules/develop/structure.mdx delete mode 100644 website/docs/language/modules/index.mdx delete mode 100644 website/docs/language/modules/sources.mdx delete mode 100644 website/docs/language/modules/syntax.mdx delete mode 100644 website/docs/language/moved.mdx delete mode 100644 website/docs/language/providers/configuration.mdx delete mode 100644 website/docs/language/providers/index.mdx delete mode 100644 website/docs/language/providers/requirements.mdx delete mode 100644 website/docs/language/resources/behavior.mdx delete mode 100644 website/docs/language/resources/ephemeral/index.mdx delete mode 100644 website/docs/language/resources/ephemeral/reference.mdx delete mode 100644 website/docs/language/resources/ephemeral/write-only.mdx delete mode 100644 website/docs/language/resources/index.mdx delete mode 100644 website/docs/language/resources/provisioners/connection.mdx delete mode 100644 website/docs/language/resources/provisioners/file.mdx delete mode 100644 website/docs/language/resources/provisioners/local-exec.mdx delete mode 100644 website/docs/language/resources/provisioners/null_resource.mdx delete mode 100644 website/docs/language/resources/provisioners/remote-exec.mdx delete mode 100644 website/docs/language/resources/provisioners/syntax.mdx delete mode 100644 website/docs/language/resources/syntax.mdx delete mode 100644 website/docs/language/resources/terraform-data.mdx delete mode 100644 website/docs/language/stacks/create/config.mdx delete mode 100644 website/docs/language/stacks/create/declare-providers.mdx delete mode 100644 website/docs/language/stacks/deploy/authenticate.mdx delete mode 100644 website/docs/language/stacks/deploy/conditions.mdx delete mode 100644 website/docs/language/stacks/deploy/config.mdx delete mode 100644 website/docs/language/stacks/deploy/pass-data.mdx delete mode 100644 website/docs/language/stacks/design.mdx delete mode 100644 website/docs/language/stacks/index.mdx delete mode 100644 website/docs/language/stacks/reference/tfdeploy.mdx delete mode 100644 website/docs/language/stacks/reference/tfstack.mdx delete mode 100644 website/docs/language/stacks/reference/tfstacks-cli.mdx delete mode 100644 website/docs/language/stacks/use-cases.mdx delete mode 100644 website/docs/language/state/backends.mdx delete mode 100644 website/docs/language/state/import.mdx delete mode 100644 website/docs/language/state/index.mdx delete mode 100644 website/docs/language/state/locking.mdx delete mode 100644 website/docs/language/state/purpose.mdx delete mode 100644 website/docs/language/state/refactor.mdx delete mode 100644 website/docs/language/state/remote-state-data.mdx delete mode 100644 website/docs/language/state/remote.mdx delete mode 100644 website/docs/language/state/sensitive-data.mdx delete mode 100644 website/docs/language/state/workspaces.mdx delete mode 100644 website/docs/language/style.mdx delete mode 100644 website/docs/language/syntax/configuration.mdx delete mode 100644 website/docs/language/syntax/index.mdx delete mode 100644 website/docs/language/syntax/json.mdx delete mode 100644 website/docs/language/terraform.mdx delete mode 100644 website/docs/language/tests/index.mdx delete mode 100644 website/docs/language/tests/mocking.mdx delete mode 100644 website/docs/language/upgrade-guides/index.mdx delete mode 100644 website/docs/language/v1-compatibility-promises.mdx delete mode 100644 website/docs/language/values/index.mdx delete mode 100644 website/docs/language/values/locals.mdx delete mode 100644 website/docs/language/values/outputs.mdx delete mode 100644 website/docs/language/values/variables.mdx delete mode 100644 website/img/docs/concrete-plan.png delete mode 100644 website/img/docs/graph-example.png delete mode 100644 website/img/docs/in-progress-apply.png delete mode 100644 website/img/docs/intro-terraform-apis.png delete mode 100644 website/img/docs/intro-terraform-workflow.png delete mode 100644 website/img/docs/manually-pasted-plan-output.png delete mode 100644 website/img/docs/plan-comments.png delete mode 100644 website/img/docs/pr-plan.png delete mode 100644 website/img/docs/pull-request.png delete mode 100644 website/img/docs/stacks-example.png delete mode 100644 website/package-lock.json delete mode 100644 website/package.json delete mode 100644 website/scripts/should-build.sh delete mode 100755 website/scripts/website-build.sh delete mode 100644 website/scripts/website-start.sh delete mode 100644 website/vercel.json diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index bb6b8e81fd..692856dcc2 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -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. diff --git a/.github/ISSUE_TEMPLATE/documentation_issue.yml b/.github/ISSUE_TEMPLATE/documentation_issue.yml deleted file mode 100644 index 44da6b2888..0000000000 --- a/.github/ISSUE_TEMPLATE/documentation_issue.yml +++ /dev/null @@ -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. diff --git a/.gitignore b/.gitignore index 30fd56c026..cadfbdd062 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/CODEOWNERS b/CODEOWNERS index 7d1c1fb167..d0ca00eb85 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -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 diff --git a/Makefile b/Makefile index 3253d8f23a..6863c3b41a 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index ff9e27d11d..ab40c4ef40 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/commands.go b/commands.go index 9d08f9f09d..b202d34460 100644 --- a/commands.go +++ b/commands.go @@ -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. diff --git a/help.go b/help.go index 0a7fdbac2a..b0de2c37fe 100644 --- a/help.go +++ b/help.go @@ -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] [args] diff --git a/website/Makefile b/website/Makefile deleted file mode 100644 index fe76940c45..0000000000 --- a/website/Makefile +++ /dev/null @@ -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) - diff --git a/website/README.md b/website/README.md index de9c4503f6..789e61c397 100644 --- a/website/README.md +++ b/website/README.md @@ -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. - - Screen Shot 2022-08-09 at 11 06 17 AM - -1. Merge the pull request. GitHub Actions autogenerates a backport pull request, linked to the original. - - Screen Shot 2022-08-09 at 11 08 52 AM - -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. diff --git a/website/data/cli-nav-data.json b/website/data/cli-nav-data.json deleted file mode 100644 index ab233710c0..0000000000 --- a/website/data/cli-nav-data.json +++ /dev/null @@ -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": "init", "href": "/cli/commands/init" }, - { "title": "get", "href": "/cli/commands/get" } - ] - }, - { - "title": "Provisioning Infrastructure", - "routes": [ - { "title": "Overview", "path": "run" }, - { "title": "plan", "href": "/cli/commands/plan" }, - { "title": "apply", "href": "/cli/commands/apply" }, - { "title": "destroy", "href": "/cli/commands/destroy" } - ] - }, - { - "title": "Authenticating", - "routes": [ - { "title": "Overview", "path": "auth" }, - { "title": "login", "href": "/cli/commands/login" }, - { "title": "logout", "href": "/cli/commands/logout" } - ] - }, - { - "title": "Writing and Modifying Code", - "routes": [ - { "title": "Overview", "path": "code" }, - { "title": "console", "href": "/cli/commands/console" }, - { "title": "fmt", "href": "/cli/commands/fmt" }, - { "title": "validate", "href": "/cli/commands/validate" } - ] - }, - { - "title": "Inspecting Infrastructure", - "routes": [ - { "title": "Overview", "path": "inspect" }, - { "title": "graph", "href": "/cli/commands/graph" }, - { "title": "output", "href": "/cli/commands/output" }, - { "title": "show", "href": "/cli/commands/show" }, - { - "title": "state list", - "href": "/cli/commands/state/list" - }, - { - "title": "state show", - "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": "state", "href": "/cli/commands/state" }, - { - "title": "Inspecting State", - "routes": [ - { "title": "Overview", "path": "state/inspect" }, - { - "title": "state list", - "href": "/cli/commands/state/list" - }, - { - "title": "state show", - "href": "/cli/commands/state/show" - }, - { - "title": "refresh", - "href": "/cli/commands/refresh" - } - ] - }, - { - "title": "Forcing Re-creation (Tainting)", - "routes": [ - { "title": "Overview", "path": "state/taint" }, - { - "title": "taint", - "href": "/cli/commands/taint" - }, - { - "title": "untaint", - "href": "/cli/commands/untaint" - } - ] - }, - { - "title": "Moving Resources", - "routes": [ - { "title": "Overview", "path": "state/move" }, - { - "title": "state mv", - "href": "/cli/commands/state/mv" - }, - { - "title": "state rm", - "href": "/cli/commands/state/rm" - }, - { - "title": "state replace-provider", - "href": "/cli/commands/state/replace-provider" - } - ] - }, - { - "title": "Disaster Recovery", - "routes": [ - { - "title": "Overview", - "path": "state/recover" - }, - { - "title": "state pull", - "href": "/cli/commands/state/pull" - }, - { - "title": "state push", - "href": "/cli/commands/state/push" - }, - { - "title": "force-unlock", - "href": "/cli/commands/force-unlock" - } - ] - } - ] - }, - { - "title": "Managing Workspaces", - "routes": [ - { "title": "Overview", "path": "workspaces" }, - { - "title": "workspace", - "routes": [ - { "title": "Overview", "href": "/cli/commands/workspace" }, - { - "title": "workspace list", - "href": "/cli/commands/workspace/list" - }, - { - "title": "workspace select", - "href": "/cli/commands/workspace/select" - }, - { - "title": "workspace new", - "href": "/cli/commands/workspace/new" - }, - { - "title": "workspace delete", - "href": "/cli/commands/workspace/delete" - }, - { - "title": "workspace show", - "href": "/cli/commands/workspace/show" - } - ] - } - ] - }, - { - "title": "Managing Plugins", - "routes": [ - { "title": "Overview", "path": "plugins" }, - { "title": "Plugin Signing", "path": "plugins/signing" }, - { - "title": "providers", - "href": "/cli/commands/providers" - }, - { - "title": "version", - "href": "/cli/commands/version" - }, - { - "title": "providers lock", - "href": "/cli/commands/providers/lock" - }, - { - "title": "providers mirror", - "href": "/cli/commands/providers/mirror" - }, - { - "title": "providers schema", - "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": "test", "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": "apply", "href": "/cli/commands/apply" }, - { "title": "console", "href": "/cli/commands/console" }, - { "title": "destroy", "href": "/cli/commands/destroy" }, - { "title": "fmt", "href": "/cli/commands/fmt" }, - { - "title": "force-unlock", - "href": "/cli/commands/force-unlock" - }, - { "title": "get", "href": "/cli/commands/get" }, - { "title": "graph", "href": "/cli/commands/graph" }, - { "title": "import", "href": "/cli/commands/import" }, - { "title": "init", "href": "/cli/commands/init" }, - { "title": "login", "href": "/cli/commands/login" }, - { "title": "logout", "href": "/cli/commands/logout" }, - { "title": "modules", "href": "/cli/commands/modules" }, - { "title": "output", "href": "/cli/commands/output" }, - { "title": "plan", "href": "/cli/commands/plan" }, - { "title": "providers", "href": "/cli/commands/providers" }, - { - "title": "providers lock", - "href": "/cli/commands/providers/lock" - }, - { - "title": "providers mirror", - "href": "/cli/commands/providers/mirror" - }, - { - "title": "providers schema", - "href": "/cli/commands/providers/schema" - }, - { "title": "refresh", "href": "/cli/commands/refresh" }, - { "title": "show", "href": "/cli/commands/show" }, - { "title": "state", "href": "/cli/commands/state" }, - { - "title": "state list", - "href": "/cli/commands/state/list" - }, - { "title": "state mv", "href": "/cli/commands/state/mv" }, - { - "title": "state pull", - "href": "/cli/commands/state/pull" - }, - { - "title": "state push", - "href": "/cli/commands/state/push" - }, - { - "title": "state replace-provider", - "href": "/cli/commands/state/replace-provider" - }, - { "title": "state rm", "href": "/cli/commands/state/rm" }, - { - "title": "state show", - "href": "/cli/commands/state/show" - }, - { "title": "taint", "href": "/cli/commands/taint" }, - { "title": "test", "href": "/cli/commands/test" }, - { "title": "untaint", "href": "/cli/commands/untaint" }, - { "title": "validate", "href": "/cli/commands/validate" }, - { "title": "version", "href": "/cli/commands/version" }, - { "title": "workspace", "href": "/cli/commands/workspace" }, - { - "title": "workspace list", - "href": "/cli/commands/workspace/list" - }, - { - "title": "workspace select", - "href": "/cli/commands/workspace/select" - }, - { - "title": "workspace new", - "href": "/cli/commands/workspace/new" - }, - { - "title": "workspace delete", - "href": "/cli/commands/workspace/delete" - }, - { - "title": "workspace show", - "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" } -] diff --git a/website/data/internals-nav-data.json b/website/data/internals-nav-data.json deleted file mode 100644 index f9291d8991..0000000000 --- a/website/data/internals-nav-data.json +++ /dev/null @@ -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" } -] diff --git a/website/data/intro-nav-data.json b/website/data/intro-nav-data.json deleted file mode 100644 index 4d0da480af..0000000000 --- a/website/data/intro-nav-data.json +++ /dev/null @@ -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" } - ] - } -] diff --git a/website/data/language-nav-data.json b/website/data/language-nav-data.json deleted file mode 100644 index 7a4164f687..0000000000 --- a/website/data/language-nav-data.json +++ /dev/null @@ -1,1121 +0,0 @@ -[ - { "heading": "Terraform Language" }, - { "title": "Overview", "path": "" }, - { - "title": "Attributes as Blocks - Configuration Language", - "path": "attr-as-blocks", - "hidden": true - }, - { - "title": "Style Guide", - "path": "style" - }, - { - "title": "Stacks", - "badge": { - "text": "BETA", - "type": "outlined", - "color": "neutral" - }, - "routes": [ - { "title": "Overview", "path": "stacks" }, - { "title": "Use cases", "path": "stacks/use-cases" }, - { "title": "Design a Stack", "path": "stacks/design" }, - { - "title": "Create a Stack", - "routes": [ - { "title": "Define configuration", "path": "stacks/create/config" }, - { "title": "Declare providers", "path": "stacks/create/declare-providers" } - ] - }, - { - "title": "Define deployments", - "routes": [ - { "title": "Define configuration", "path": "stacks/deploy/config" }, - { "title": "Set conditions for deployment plans", "path": "stacks/deploy/conditions" }, - { "title": "Authenticate a Stack", "path": "stacks/deploy/authenticate" }, - { "title": "Pass data from one Stack to another", "path": "stacks/deploy/pass-data" } - ] - }, - { - "title": "Reference", - "routes": [ - { "title": "Stack configuration file", "path": "stacks/reference/tfstack" }, - { "title": "Deployment configuration file", "path": "stacks/reference/tfdeploy" }, - { "title": "Tfstacks CLI", "path": "stacks/reference/tfstacks-cli" } - ] - } - ] - }, - { - "title": "Files and Directories", - "routes": [ - { "title": "Overview", "path": "files" }, - { "title": "Override Files", "path": "files/override" }, - { "title": "Dependency Lock File", "path": "files/dependency-lock" }, - { "title": "Test Files", "path": "files/tests" } - ] - }, - { - "title": "Syntax", - "routes": [ - { "title": "Overview", "path": "syntax" }, - { - "title": "Configuration Syntax", - "path": "syntax/configuration" - }, - { - "title": "JSON Configuration Syntax", - "path": "syntax/json" - } - ] - }, - { - "title": "Resources", - "routes": [ - { "title": "Overview", "path": "resources" }, - { "title": "Resource Blocks", "path": "resources/syntax" }, - { - "title": "Resource Behavior", - "path": "resources/behavior" - }, - { - "title": "Meta-Arguments", - "routes": [ - { - "title": "depends_on", - "href": "/language/meta-arguments/depends_on" - }, - { - "title": "count", - "href": "/language/meta-arguments/count" - }, - { - "title": "for_each", - "href": "/language/meta-arguments/for_each" - }, - { - "title": "provider", - "href": "/language/meta-arguments/resource-provider" - }, - { - "title": "lifecycle", - "href": "/language/meta-arguments/lifecycle" - } - ] - }, - { - "title": "Provisioners", - "routes": [ - { - "title": "Declaring Provisioners", - "path": "resources/provisioners/syntax" - }, - { - "title": "Provisioner Connections", - "path": "resources/provisioners/connection" - }, - { - "title": "Provisioners Without a Resource", - "path": "resources/provisioners/null_resource" - }, - { - "title": "file", - "path": "resources/provisioners/file" - }, - { - "title": "local-exec", - "path": "resources/provisioners/local-exec" - }, - { - "title": "remote-exec", - "path": "resources/provisioners/remote-exec" - } - ] - }, - { - "title": "The terraform_data Resource Type", - "path": "resources/terraform-data" - }, - { - "title": "Ephemerality in Resources", - "routes": [ - { - "title": "Overview", - "path": "resources/ephemeral" - }, - { - "title": "Ephemeral block", - "path": "resources/ephemeral/reference" - }, - { - "title": "Use write-only arguments", - "path": "resources/ephemeral/write-only" - } - ] - } - ] - }, - { "title": "Data Sources", "path": "data-sources" }, - { - "title": "Meta-Arguments", - "hidden": true, - "routes": [ - { - "title": "count", - "path": "meta-arguments/count" - }, - { - "title": "depends_on", - "path": "meta-arguments/depends_on" - }, - { - "title": "for_each", - "path": "meta-arguments/for_each" - }, - { - "title": "lifecycle", - "path": "meta-arguments/lifecycle" - }, - { - "title": "providers", - "path": "meta-arguments/module-providers" - }, - { - "title": "provider", - "path": "meta-arguments/resource-provider" - } - ] - }, - - { - "title": "Providers", - "routes": [ - { "title": "Overview", "path": "providers" }, - { - "title": "Provider Configuration", - "path": "providers/configuration" - }, - { - "title": "Provider Requirements", - "path": "providers/requirements" - }, - { - "title": "Dependency Lock File", - "href": "/language/files/dependency-lock" - } - ] - }, - { - "title": "Variables and Outputs", - "routes": [ - { "title": "Overview", "path": "values" }, - { "title": "Input Variables", "path": "values/variables" }, - { "title": "Output Values", "path": "values/outputs" }, - { "title": "Local Values", "path": "values/locals" } - ] - }, - { - "title": "Modules", - "routes": [ - { "title": "Overview", "path": "modules" }, - - { "title": "Module Blocks", "path": "modules/syntax" }, - { "title": "Module Sources", "path": "modules/sources" }, - { - "title": "Meta-Arguments", - "routes": [ - { - "title": "providers", - "href": "/language/meta-arguments/module-providers" - }, - { - "title": "depends_on", - "href": "/language/meta-arguments/depends_on" - }, - { - "title": "count", - "href": "/language/meta-arguments/count" - }, - { - "title": "for_each", - "href": "/language/meta-arguments/for_each" - } - ] - }, - { - "title": "Module Development", - "routes": [ - { "title": "Overview", "path": "modules/develop" }, - { - "title": "Standard Module Structure", - "path": "modules/develop/structure" - }, - { - "title": "Providers Within Modules", - "path": "modules/develop/providers" - }, - { - "title": "Best Practices: Module Composition", - "path": "modules/develop/composition" - }, - { - "title": "Publishing Modules", - "path": "modules/develop/publish" - }, - { - "title": "Refactoring Modules", - "path": "modules/develop/refactoring" - } - ] - } - ] - }, - { - "title": "Moved block", - "path": "moved" - }, - { - "title": "Terraform block", - "path": "terraform" - }, - { - "title": "Backend block", - "routes": [ - { - "title": "Overview", - "path": "backend" - }, - { - "title": "local", - "path": "backend/local" - }, - { - "title": "remote", - "path": "backend/remote" - }, - { - "title": "azurerm", - "path": "backend/azurerm" - }, - { - "title": "consul", - "path": "backend/consul" - }, - { - "title": "cos", - "path": "backend/cos" - }, - { - "title": "gcs", - "path": "backend/gcs" - }, - { - "title": "http", - "path": "backend/http" - }, - { - "title": "Kubernetes", - "path": "backend/kubernetes" - }, - { - "title": "oci", - "path": "backend/oci" - }, - { - "title": "oss", - "path": "backend/oss" - }, - { - "title": "pg", - "path": "backend/pg" - }, - { - "title": "s3", - "path": "backend/s3" - } - ] - }, - { "title": "Checks", "path": "checks" }, - { - "title": "Import", - "routes": [ - { "title": "Overview", "path": "import" }, - { - "title": "Generating Configuration", - "path": "import/generating-configuration" - } - ] - }, - { - "title": "Expressions", - "routes": [ - { "title": "Overview", "path": "expressions" }, - { "title": "Types and Values", "path": "expressions/types" }, - { - "title": "Strings and Templates", - "path": "expressions/strings" - }, - { - "title": "References to Values", - "path": "expressions/references" - }, - { "title": "Operators", "path": "expressions/operators" }, - { - "title": "Function Calls", - "path": "expressions/function-calls" - }, - { - "title": "Conditional Expressions", - "path": "expressions/conditionals" - }, - { "title": "For Expressions", "path": "expressions/for" }, - { - "title": "Splat Expressions", - "path": "expressions/splat" - }, - - { - "title": "Dynamic Blocks", - "path": "expressions/dynamic-blocks" - }, - { - "title": "Custom Conditions", - "path": "expressions/custom-conditions" - }, - { - "title": "Type Constraints", - "path": "expressions/type-constraints" - }, - { - "title": "Version Constraints", - "path": "expressions/version-constraints" - } - ] - }, - { - "title": "Functions", - "routes": [ - { "title": "Overview", "path": "functions" }, - { - "title": "Numeric Functions", - "routes": [ - { "title": "abs", "href": "/language/functions/abs" }, - { "title": "ceil", "href": "/language/functions/ceil" }, - { - "title": "floor", - "href": "/language/functions/floor" - }, - { "title": "log", "href": "/language/functions/log" }, - { "title": "max", "href": "/language/functions/max" }, - { "title": "min", "href": "/language/functions/min" }, - { - "title": "parseint", - "href": "/language/functions/parseint" - }, - { "title": "pow", "href": "/language/functions/pow" }, - { - "title": "signum", - "href": "/language/functions/signum" - } - ] - }, - { - "title": "String Functions", - "routes": [ - { - "title": "chomp", - "href": "/language/functions/chomp" - }, - { - "title": "endswith", - "href": "/language/functions/endswith" - }, - { - "title": "format", - "href": "/language/functions/format" - }, - { - "title": "formatlist", - "href": "/language/functions/formatlist" - }, - { - "title": "indent", - "href": "/language/functions/indent" - }, - { "title": "join", "href": "/language/functions/join" }, - { - "title": "lower", - "href": "/language/functions/lower" - }, - { - "title": "regex", - "href": "/language/functions/regex" - }, - { - "title": "regexall", - "href": "/language/functions/regexall" - }, - { - "title": "replace", - "href": "/language/functions/replace" - }, - { - "title": "split", - "href": "/language/functions/split" - }, - { - "title": "startswith", - "href": "/language/functions/startswith" - }, - { - "title": "strcontains", - "href": "/language/functions/strcontains" - }, - { - "title": "strrev", - "href": "/language/functions/strrev" - }, - { - "title": "substr", - "href": "/language/functions/substr" - }, - { - "title": "templatestring", - "href": "/language/functions/templatestring" - }, - { - "title": "title", - "href": "/language/functions/title" - }, - { "title": "trim", "href": "/language/functions/trim" }, - { - "title": "trimprefix", - "href": "/language/functions/trimprefix" - }, - { - "title": "trimsuffix", - "href": "/language/functions/trimsuffix" - }, - { - "title": "trimspace", - "href": "/language/functions/trimspace" - }, - { "title": "upper", "href": "/language/functions/upper" } - ] - }, - { - "title": "Collection Functions", - "routes": [ - { - "title": "alltrue", - "href": "/language/functions/alltrue" - }, - { - "title": "anytrue", - "href": "/language/functions/anytrue" - }, - { - "title": "chunklist", - "href": "/language/functions/chunklist" - }, - { - "title": "coalesce", - "href": "/language/functions/coalesce" - }, - { - "title": "coalescelist", - "href": "/language/functions/coalescelist" - }, - { - "title": "compact", - "href": "/language/functions/compact" - }, - { - "title": "concat", - "href": "/language/functions/concat" - }, - { - "title": "contains", - "href": "/language/functions/contains" - }, - { - "title": "distinct", - "href": "/language/functions/distinct" - }, - { - "title": "element", - "href": "/language/functions/element" - }, - { - "title": "flatten", - "href": "/language/functions/flatten" - }, - { - "title": "index", - "href": "/language/functions/index_function" - }, - { "title": "keys", "href": "/language/functions/keys" }, - { - "title": "length", - "href": "/language/functions/length" - }, - { "title": "list", "href": "/language/functions/list" }, - { - "title": "lookup", - "href": "/language/functions/lookup" - }, - { "title": "map", "href": "/language/functions/map" }, - { - "title": "matchkeys", - "href": "/language/functions/matchkeys" - }, - { - "title": "merge", - "href": "/language/functions/merge" - }, - { "title": "one", "href": "/language/functions/one" }, - { - "title": "range", - "href": "/language/functions/range" - }, - { - "title": "reverse", - "href": "/language/functions/reverse" - }, - { - "title": "setintersection", - "href": "/language/functions/setintersection" - }, - { - "title": "setproduct", - "href": "/language/functions/setproduct" - }, - { - "title": "setsubtract", - "href": "/language/functions/setsubtract" - }, - { - "title": "setunion", - "href": "/language/functions/setunion" - }, - { - "title": "slice", - "href": "/language/functions/slice" - }, - { "title": "sort", "href": "/language/functions/sort" }, - { "title": "sum", "href": "/language/functions/sum" }, - { - "title": "transpose", - "href": "/language/functions/transpose" - }, - { - "title": "values", - "href": "/language/functions/values" - }, - { - "title": "zipmap", - "href": "/language/functions/zipmap" - } - ] - }, - { - "title": "Encoding Functions", - "routes": [ - { - "title": "base64decode", - "href": "/language/functions/base64decode" - }, - { - "title": "base64encode", - "href": "/language/functions/base64encode" - }, - { - "title": "base64gzip", - "href": "/language/functions/base64gzip" - }, - { - "title": "csvdecode", - "href": "/language/functions/csvdecode" - }, - { - "title": "jsondecode", - "href": "/language/functions/jsondecode" - }, - { - "title": "jsonencode", - "href": "/language/functions/jsonencode" - }, - { - "title": "textdecodebase64", - "href": "/language/functions/textdecodebase64" - }, - { - "title": "textencodebase64", - "href": "/language/functions/textencodebase64" - }, - { - "title": "urlencode", - "href": "/language/functions/urlencode" - }, - { - "title": "yamldecode", - "href": "/language/functions/yamldecode" - }, - { - "title": "yamlencode", - "href": "/language/functions/yamlencode" - } - ] - }, - { - "title": "Filesystem Functions", - "routes": [ - { - "title": "abspath", - "href": "/language/functions/abspath" - }, - { - "title": "dirname", - "href": "/language/functions/dirname" - }, - { - "title": "pathexpand", - "href": "/language/functions/pathexpand" - }, - { - "title": "basename", - "href": "/language/functions/basename" - }, - { "title": "file", "href": "/language/functions/file" }, - { - "title": "fileexists", - "href": "/language/functions/fileexists" - }, - { - "title": "fileset", - "href": "/language/functions/fileset" - }, - { - "title": "filebase64", - "href": "/language/functions/filebase64" - }, - { - "title": "templatefile", - "href": "/language/functions/templatefile" - } - ] - }, - { - "title": "Date and Time Functions", - "routes": [ - { - "title": "formatdate", - "href": "/language/functions/formatdate" - }, - { - "title": "plantimestamp", - "href": "/language/functions/plantimestamp" - }, - { - "title": "timeadd", - "href": "/language/functions/timeadd" - }, - { - "title": "timecmp", - "href": "/language/functions/timecmp" - }, - { - "title": "timestamp", - "href": "/language/functions/timestamp" - } - ] - }, - { - "title": "Hash and Crypto Functions", - "routes": [ - { - "title": "base64sha256", - "href": "/language/functions/base64sha256" - }, - { - "title": "base64sha512", - "href": "/language/functions/base64sha512" - }, - { - "title": "bcrypt", - "href": "/language/functions/bcrypt" - }, - { - "title": "filebase64sha256", - "href": "/language/functions/filebase64sha256" - }, - { - "title": "filebase64sha512", - "href": "/language/functions/filebase64sha512" - }, - { - "title": "filemd5", - "href": "/language/functions/filemd5" - }, - { - "title": "filesha1", - "href": "/language/functions/filesha1" - }, - { - "title": "filesha256", - "href": "/language/functions/filesha256" - }, - { - "title": "filesha512", - "href": "/language/functions/filesha512" - }, - { "title": "md5", "href": "/language/functions/md5" }, - { - "title": "rsadecrypt", - "href": "/language/functions/rsadecrypt" - }, - { "title": "sha1", "href": "/language/functions/sha1" }, - { - "title": "sha256", - "href": "/language/functions/sha256" - }, - { - "title": "sha512", - "href": "/language/functions/sha512" - }, - { "title": "uuid", "href": "/language/functions/uuid" }, - { - "title": "uuidv5", - "href": "/language/functions/uuidv5" - } - ] - }, - { - "title": "IP Network Functions", - "routes": [ - { - "title": "cidrhost", - "href": "/language/functions/cidrhost" - }, - { - "title": "cidrnetmask", - "href": "/language/functions/cidrnetmask" - }, - { - "title": "cidrsubnet", - "href": "/language/functions/cidrsubnet" - }, - { - "title": "cidrsubnets", - "href": "/language/functions/cidrsubnets" - } - ] - }, - { - "title": "Type Conversion Functions", - "routes": [ - { "title": "can", "href": "/language/functions/can" }, - { "title": "ephemeralasnull", "href": "/language/functions/ephemeralasnull" }, - { - "title": "issensitive", - "href": "/language/functions/issensitive" - }, - { - "title": "nonsensitive", - "href": "/language/functions/nonsensitive" - }, - { - "title": "sensitive", - "href": "/language/functions/sensitive" - }, - { - "title": "tobool", - "href": "/language/functions/tobool" - }, - { - "title": "tolist", - "href": "/language/functions/tolist" - }, - { - "title": "tomap", - "href": "/language/functions/tomap" - }, - { - "title": "tonumber", - "href": "/language/functions/tonumber" - }, - { - "title": "toset", - "href": "/language/functions/toset" - }, - { - "title": "tostring", - "href": "/language/functions/tostring" - }, - { "title": "try", "href": "/language/functions/try" }, - { "title": "type", "href": "/language/functions/type" } - ] - }, - { - "title": "Terraform-specific Functions", - "routes": [ - { "title": "provider::terraform::encode_tfvars", "href": "/language/functions/terraform-encode_tfvars" }, - { "title": "provider::terraform::decode_tfvars", "href": "/language/functions/terraform-decode_tfvars" }, - { "title": "provider::terraform::encode_expr", "href": "/language/functions/terraform-encode_expr" }, - { "title": "terraform.applying", "href": "/language/functions/terraform-applying" } - ] - }, - { "title": "abs", "path": "functions/abs", "hidden": true }, - { "title": "abspath", "path": "functions/abspath", "hidden": true }, - { "title": "alltrue", "path": "functions/alltrue", "hidden": true }, - { "title": "anytrue", "path": "functions/anytrue", "hidden": true }, - { - "title": "base64decode", - "path": "functions/base64decode", - "hidden": true - }, - { - "title": "base64encode", - "path": "functions/base64encode", - "hidden": true - }, - { "title": "base64gzip", "path": "functions/base64gzip", "hidden": true }, - { - "title": "base64sha256", - "path": "functions/base64sha256", - "hidden": true - }, - { - "title": "base64sha512", - "path": "functions/base64sha512", - "hidden": true - }, - { "title": "basename", "path": "functions/basename", "hidden": true }, - { "title": "bcrypt", "path": "functions/bcrypt", "hidden": true }, - { "title": "can", "path": "functions/can", "hidden": true }, - { "title": "ceil", "path": "functions/ceil", "hidden": true }, - { "title": "chomp", "path": "functions/chomp", "hidden": true }, - { "title": "chunklist", "path": "functions/chunklist", "hidden": true }, - { "title": "cidrhost", "path": "functions/cidrhost", "hidden": true }, - { - "title": "cidrnetmask", - "path": "functions/cidrnetmask", - "hidden": true - }, - { "title": "cidrsubnet", "path": "functions/cidrsubnet", "hidden": true }, - { - "title": "cidrsubnets", - "path": "functions/cidrsubnets", - "hidden": true - }, - { "title": "coalesce", "path": "functions/coalesce", "hidden": true }, - { - "title": "coalescelist", - "path": "functions/coalescelist", - "hidden": true - }, - { "title": "compact", "path": "functions/compact", "hidden": true }, - { "title": "concat", "path": "functions/concat", "hidden": true }, - { "title": "contains", "path": "functions/contains", "hidden": true }, - { "title": "csvdecode", "path": "functions/csvdecode", "hidden": true }, - { "title": "dirname", "path": "functions/dirname", "hidden": true }, - { "title": "distinct", "path": "functions/distinct", "hidden": true }, - { "title": "element", "path": "functions/element", "hidden": true }, - { "title": "endswith", "path": "functions/endswith", "hidden": true }, - { "title": "ephemeralasnull", "path": "functions/ephemeralasnull", "hidden": true }, - { "title": "file", "path": "functions/file", "hidden": true }, - { "title": "filebase64", "path": "functions/filebase64", "hidden": true }, - { - "title": "filebase64sha256", - "path": "functions/filebase64sha256", - "hidden": true - }, - { - "title": "filebase64sha512", - "path": "functions/filebase64sha512", - "hidden": true - }, - { "title": "fileexists", "path": "functions/fileexists", "hidden": true }, - { "title": "filemd5", "path": "functions/filemd5", "hidden": true }, - { "title": "fileset", "path": "functions/fileset", "hidden": true }, - { "title": "filesha1", "path": "functions/filesha1", "hidden": true }, - { "title": "filesha256", "path": "functions/filesha256", "hidden": true }, - { "title": "filesha512", "path": "functions/filesha512", "hidden": true }, - { "title": "flatten", "path": "functions/flatten", "hidden": true }, - { "title": "floor", "path": "functions/floor", "hidden": true }, - { "title": "format", "path": "functions/format", "hidden": true }, - { "title": "formatdate", "path": "functions/formatdate", "hidden": true }, - { "title": "formatlist", "path": "functions/formatlist", "hidden": true }, - { "title": "indent", "path": "functions/indent", "hidden": true }, - { "title": "index", "path": "functions/index_function", "hidden": true }, - { - "title": "issensitive", - "path": "functions/issensitive", - "hidden": true - }, - { "title": "join", "path": "functions/join", "hidden": true }, - { "title": "jsondecode", "path": "functions/jsondecode", "hidden": true }, - { "title": "jsonencode", "path": "functions/jsonencode", "hidden": true }, - { "title": "keys", "path": "functions/keys", "hidden": true }, - { "title": "length", "path": "functions/length", "hidden": true }, - { "title": "list", "path": "functions/list", "hidden": true }, - { "title": "log", "path": "functions/log", "hidden": true }, - { "title": "lookup", "path": "functions/lookup", "hidden": true }, - { "title": "lower", "path": "functions/lower", "hidden": true }, - { "title": "map", "path": "functions/map", "hidden": true }, - { "title": "matchkeys", "path": "functions/matchkeys", "hidden": true }, - { "title": "max", "path": "functions/max", "hidden": true }, - { "title": "md5", "path": "functions/md5", "hidden": true }, - { "title": "merge", "path": "functions/merge", "hidden": true }, - { "title": "min", "path": "functions/min", "hidden": true }, - { - "title": "nonsensitive", - "path": "functions/nonsensitive", - "hidden": true - }, - { "title": "one", "path": "functions/one", "hidden": true }, - { "title": "parseint", "path": "functions/parseint", "hidden": true }, - { "title": "pathexpand", "path": "functions/pathexpand", "hidden": true }, - { "title": "plantimestamp", "path": "functions/plantimestamp", "hidden": true }, - { "title": "pow", "path": "functions/pow", "hidden": true }, - { "title": "range", "path": "functions/range", "hidden": true }, - { "title": "regex", "path": "functions/regex", "hidden": true }, - { "title": "regexall", "path": "functions/regexall", "hidden": true }, - { "title": "replace", "path": "functions/replace", "hidden": true }, - { "title": "reverse", "path": "functions/reverse", "hidden": true }, - { "title": "rsadecrypt", "path": "functions/rsadecrypt", "hidden": true }, - { "title": "sensitive", "path": "functions/sensitive", "hidden": true }, - { - "title": "setintersection", - "path": "functions/setintersection", - "hidden": true - }, - { "title": "setproduct", "path": "functions/setproduct", "hidden": true }, - { - "title": "setsubtract", - "path": "functions/setsubtract", - "hidden": true - }, - { "title": "setunion", "path": "functions/setunion", "hidden": true }, - { "title": "sha1", "path": "functions/sha1", "hidden": true }, - { "title": "sha256", "path": "functions/sha256", "hidden": true }, - { "title": "sha512", "path": "functions/sha512", "hidden": true }, - { "title": "signum", "path": "functions/signum", "hidden": true }, - { "title": "slice", "path": "functions/slice", "hidden": true }, - { "title": "sort", "path": "functions/sort", "hidden": true }, - { "title": "split", "path": "functions/split", "hidden": true }, - { "title": "startswith", "path": "functions/startswith", "hidden": true }, - { "title": "strcontains", "path": "functions/strcontains", "hidden": true}, - { "title": "strrev", "path": "functions/strrev", "hidden": true }, - { "title": "substr", "path": "functions/substr", "hidden": true }, - { "title": "sum", "path": "functions/sum", "hidden": true }, - { - "title": "templatefile", - "path": "functions/templatefile", - "hidden": true - }, - { - "title": "templatestring", - "path": "functions/templatestring", - "hidden": true - }, - { - "title": "terraform.applying", - "path": "functions/terraform-applying", - "hidden": true - }, - { "title": "terraform-encode_tfvars", "path": "functions/terraform-encode_tfvars", "hidden": true }, - { "title": "terraform-decode_tfvars", "path": "functions/terraform-decode_tfvars", "hidden": true }, - { "title": "terraform-encode_expr", "path": "functions/terraform-encode_expr", "hidden": true }, - { - "title": "textdecodebase64", - "path": "functions/textdecodebase64", - "hidden": true - }, - { - "title": "textencodebase64", - "path": "functions/textencodebase64", - "hidden": true - }, - { "title": "timeadd", "path": "functions/timeadd", "hidden": true }, - { "title": "timecmp", "path": "functions/timecmp", "hidden": true }, - { "title": "timestamp", "path": "functions/timestamp", "hidden": true }, - { "title": "title", "path": "functions/title", "hidden": true }, - { "title": "tobool", "path": "functions/tobool", "hidden": true }, - { "title": "tolist", "path": "functions/tolist", "hidden": true }, - { "title": "tomap", "path": "functions/tomap", "hidden": true }, - { "title": "tonumber", "path": "functions/tonumber", "hidden": true }, - { "title": "toset", "path": "functions/toset", "hidden": true }, - { "title": "tostring", "path": "functions/tostring", "hidden": true }, - { "title": "transpose", "path": "functions/transpose", "hidden": true }, - { "title": "trim", "path": "functions/trim", "hidden": true }, - { "title": "trimprefix", "path": "functions/trimprefix", "hidden": true }, - { "title": "trimspace", "path": "functions/trimspace", "hidden": true }, - { "title": "trimsuffix", "path": "functions/trimsuffix", "hidden": true }, - { "title": "try", "path": "functions/try", "hidden": true }, - { "title": "type", "path": "functions/type", "hidden": true }, - { "title": "upper", "path": "functions/upper", "hidden": true }, - { "title": "urlencode", "path": "functions/urlencode", "hidden": true }, - { "title": "uuid", "path": "functions/uuid", "hidden": true }, - { "title": "uuidv5", "path": "functions/uuidv5", "hidden": true }, - { "title": "values", "path": "functions/values", "hidden": true }, - { "title": "yamldecode", "path": "functions/yamldecode", "hidden": true }, - { "title": "yamlencode", "path": "functions/yamlencode", "hidden": true }, - { "title": "zipmap", "path": "functions/zipmap", "hidden": true } - ] - }, - { - "title": "State", - "routes": [ - { "title": "Overview", "path": "state" }, - { "title": "Purpose", "path": "state/purpose" }, - { - "title": "The terraform_remote_state Data Source", - "path": "state/remote-state-data" - }, - { - "title": "Backends: State Storage and Locking", - "path": "state/backends" - }, - { - "title": "Import Existing Resources", - "path": "state/import" - }, - { - "title": "Refactor state", - "path": "state/refactor" - }, - { "title": "Locking", "path": "state/locking" }, - { "title": "Workspaces", "path": "state/workspaces" }, - { "title": "Remote State", "path": "state/remote" }, - { - "title": "Sensitive Data", - "path": "state/sensitive-data" - } - ] - }, - { - "title": "Tests", - "routes": [ - { - "title": "Overview", - "path": "tests" - }, - { - "title": "Mocks", - "path": "tests/mocking" - } - ] - }, - { - "title": "Upgrading to Terraform v1.10", - "path": "upgrade-guides" - }, - { - "title": "v1.x Compatibility Promises", - "path": "v1-compatibility-promises" - }, - { "divider": true }, - { "title": "Terraform Internals", "href": "/internals" } -] diff --git a/website/docs/cli/auth/index.mdx b/website/docs/cli/auth/index.mdx deleted file mode 100644 index 5d7816358e..0000000000 --- a/website/docs/cli/auth/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/cloud/command-line-arguments.mdx b/website/docs/cli/cloud/command-line-arguments.mdx deleted file mode 100644 index d9b5db7b9b..0000000000 --- a/website/docs/cli/cloud/command-line-arguments.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/cloud/index.mdx b/website/docs/cli/cloud/index.mdx deleted file mode 100644 index 75eac5e885..0000000000 --- a/website/docs/cli/cloud/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/cloud/settings.mdx b/website/docs/cli/cloud/settings.mdx deleted file mode 100644 index 244f045783..0000000000 --- a/website/docs/cli/cloud/settings.mdx +++ /dev/null @@ -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 `--`, 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. diff --git a/website/docs/cli/code/index.mdx b/website/docs/cli/code/index.mdx deleted file mode 100644 index fa768ff2a9..0000000000 --- a/website/docs/cli/code/index.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/commands/0.12upgrade.mdx b/website/docs/cli/commands/0.12upgrade.mdx deleted file mode 100644 index 51e84a3dee..0000000000 --- a/website/docs/cli/commands/0.12upgrade.mdx +++ /dev/null @@ -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. \ No newline at end of file diff --git a/website/docs/cli/commands/0.13upgrade.mdx b/website/docs/cli/commands/0.13upgrade.mdx deleted file mode 100644 index 33802ae4f7..0000000000 --- a/website/docs/cli/commands/0.13upgrade.mdx +++ /dev/null @@ -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. \ No newline at end of file diff --git a/website/docs/cli/commands/apply.mdx b/website/docs/cli/commands/apply.mdx deleted file mode 100644 index e62b57d887..0000000000 --- a/website/docs/cli/commands/apply.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/console.mdx b/website/docs/cli/commands/console.mdx deleted file mode 100644 index f60680ec1b..0000000000 --- a/website/docs/cli/commands/console.mdx +++ /dev/null @@ -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" -``` diff --git a/website/docs/cli/commands/destroy.mdx b/website/docs/cli/commands/destroy.mdx deleted file mode 100644 index 5ba69c978f..0000000000 --- a/website/docs/cli/commands/destroy.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/commands/fmt.mdx b/website/docs/cli/commands/fmt.mdx deleted file mode 100644 index 73312159ad..0000000000 --- a/website/docs/cli/commands/fmt.mdx +++ /dev/null @@ -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 | diff --git a/website/docs/cli/commands/force-unlock.mdx b/website/docs/cli/commands/force-unlock.mdx deleted file mode 100644 index af57aa4cde..0000000000 --- a/website/docs/cli/commands/force-unlock.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/get.mdx b/website/docs/cli/commands/get.mdx deleted file mode 100644 index a6c51952ef..0000000000 --- a/website/docs/cli/commands/get.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/graph.mdx b/website/docs/cli/commands/graph.mdx deleted file mode 100644 index f3ca085bab..0000000000 --- a/website/docs/cli/commands/graph.mdx +++ /dev/null @@ -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) diff --git a/website/docs/cli/commands/import.mdx b/website/docs/cli/commands/import.mdx deleted file mode 100644 index 4db527b150..0000000000 --- a/website/docs/cli/commands/import.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/commands/index.mdx b/website/docs/cli/commands/index.mdx deleted file mode 100644 index dbcd1eafb5..0000000000 --- a/website/docs/cli/commands/index.mdx +++ /dev/null @@ -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] [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. diff --git a/website/docs/cli/commands/init.mdx b/website/docs/cli/commands/init.mdx deleted file mode 100644 index 635ef5d17c..0000000000 --- a/website/docs/cli/commands/init.mdx +++ /dev/null @@ -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=` 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. diff --git a/website/docs/cli/commands/login.mdx b/website/docs/cli/commands/login.mdx deleted file mode 100644 index ffea1f5b0b..0000000000 --- a/website/docs/cli/commands/login.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/logout.mdx b/website/docs/cli/commands/logout.mdx deleted file mode 100644 index 3e3f0b4274..0000000000 --- a/website/docs/cli/commands/logout.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/modules.mdx b/website/docs/cli/commands/modules.mdx deleted file mode 100644 index 2ab2524e99..0000000000 --- a/website/docs/cli/commands/modules.mdx +++ /dev/null @@ -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": "" - }, - ] -} -``` - - diff --git a/website/docs/cli/commands/output.mdx b/website/docs/cli/commands/output.mdx deleted file mode 100644 index 2020f0be71..0000000000 --- a/website/docs/cli/commands/output.mdx +++ /dev/null @@ -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 = -``` - -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. diff --git a/website/docs/cli/commands/plan.mdx b/website/docs/cli/commands/plan.mdx deleted file mode 100644 index 0b1735ebe6..0000000000 --- a/website/docs/cli/commands/plan.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/providers.mdx b/website/docs/cli/commands/providers.mdx deleted file mode 100644 index 62ebd22088..0000000000 --- a/website/docs/cli/commands/providers.mdx +++ /dev/null @@ -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` diff --git a/website/docs/cli/commands/providers/lock.mdx b/website/docs/cli/commands/providers/lock.mdx deleted file mode 100644 index e45be8855b..0000000000 --- a/website/docs/cli/commands/providers/lock.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/commands/providers/mirror.mdx b/website/docs/cli/commands/providers/mirror.mdx deleted file mode 100644 index 37cc893c7b..0000000000 --- a/website/docs/cli/commands/providers/mirror.mdx +++ /dev/null @@ -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] ` - -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. diff --git a/website/docs/cli/commands/providers/schema.mdx b/website/docs/cli/commands/providers/schema.mdx deleted file mode 100644 index 891293e8df..0000000000 --- a/website/docs/cli/commands/providers/schema.mdx +++ /dev/null @@ -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 ``) 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": , - - // "resource_schemas" map the resource type name to the resource's schema - "resource_schemas": { - "example_resource_name": - }, - - // "data_source_schemas" map the data source type name to the - // data source's schema - "data_source_schemas": { - "example_datasource_name": , - }, - - // "ephemeral_resource_schemas" map the resource type name to the - // resource's schema - "ephemeral_resource_schemas": { - "example_resource_name": , - }, - - // "functions" map the provider function name to the function definition - "functions": { - "example_function": - } - }, - "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 - -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": , - - // "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": [ - , - // ... - ], - - // "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 - -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" -} -``` diff --git a/website/docs/cli/commands/refresh.mdx b/website/docs/cli/commands/refresh.mdx deleted file mode 100644 index 5c47b0e88c..0000000000 --- a/website/docs/cli/commands/refresh.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/show.mdx b/website/docs/cli/commands/show.mdx deleted file mode 100644 index bed79a52a7..0000000000 --- a/website/docs/cli/commands/show.mdx +++ /dev/null @@ -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**. diff --git a/website/docs/cli/commands/state/index.mdx b/website/docs/cli/commands/state/index.mdx deleted file mode 100644 index e1d0f96d08..0000000000 --- a/website/docs/cli/commands/state/index.mdx +++ /dev/null @@ -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 [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. diff --git a/website/docs/cli/commands/state/list.mdx b/website/docs/cli/commands/state/list.mdx deleted file mode 100644 index 8956ed66e9..0000000000 --- a/website/docs/cli/commands/state/list.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/commands/state/mv.mdx b/website/docs/cli/commands/state/mv.mdx deleted file mode 100644 index 3259d64c2e..0000000000 --- a/website/docs/cli/commands/state/mv.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/state/pull.mdx b/website/docs/cli/commands/state/pull.mdx deleted file mode 100644 index bf54c6d1f7..0000000000 --- a/website/docs/cli/commands/state/pull.mdx +++ /dev/null @@ -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`. diff --git a/website/docs/cli/commands/state/push.mdx b/website/docs/cli/commands/state/push.mdx deleted file mode 100644 index 7e5899c8cb..0000000000 --- a/website/docs/cli/commands/state/push.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/commands/state/replace-provider.mdx b/website/docs/cli/commands/state/replace-provider.mdx deleted file mode 100644 index dcd720e810..0000000000 --- a/website/docs/cli/commands/state/replace-provider.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/commands/state/rm.mdx b/website/docs/cli/commands/state/rm.mdx deleted file mode 100644 index ab3f1aedf7..0000000000 --- a/website/docs/cli/commands/state/rm.mdx +++ /dev/null @@ -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\"]' -``` diff --git a/website/docs/cli/commands/state/show.mdx b/website/docs/cli/commands/state/show.mdx deleted file mode 100644 index 7268fc42fa..0000000000 --- a/website/docs/cli/commands/state/show.mdx +++ /dev/null @@ -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\"] -``` diff --git a/website/docs/cli/commands/taint.mdx b/website/docs/cli/commands/taint.mdx deleted file mode 100644 index 8eb7724676..0000000000 --- a/website/docs/cli/commands/taint.mdx +++ /dev/null @@ -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]
-``` - -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). diff --git a/website/docs/cli/commands/test.mdx b/website/docs/cli/commands/test.mdx deleted file mode 100644 index fb1e859400..0000000000 --- a/website/docs/cli/commands/test.mdx +++ /dev/null @@ -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=` - 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=` - 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=` - 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=` - 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 - - - - - - - - - - -``` - -If a run block contains a failing assertion, the `` element will contain a `` element that includes the error message and further details. - -A `` element could contain a `` 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 | `` | -| Test file | `` | -| Run block | `` | -| Run block assertion | None; details are included only on failure | -| Test failure | `` | -| Test was skipped | `` | -| Test stopped due to error | `` | -| Any unhandled warnings or errors | `` | \ No newline at end of file diff --git a/website/docs/cli/commands/untaint.mdx b/website/docs/cli/commands/untaint.mdx deleted file mode 100644 index 632768f216..0000000000 --- a/website/docs/cli/commands/untaint.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/commands/validate.mdx b/website/docs/cli/commands/validate.mdx deleted file mode 100644 index 8cfd47abf1..0000000000 --- a/website/docs/cli/commands/validate.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/commands/version.mdx b/website/docs/cli/commands/version.mdx deleted file mode 100644 index e98c7e389f..0000000000 --- a/website/docs/cli/commands/version.mdx +++ /dev/null @@ -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 -} -``` diff --git a/website/docs/cli/commands/workspace/delete.mdx b/website/docs/cli/commands/workspace/delete.mdx deleted file mode 100644 index 06c690e399..0000000000 --- a/website/docs/cli/commands/workspace/delete.mdx +++ /dev/null @@ -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". -``` diff --git a/website/docs/cli/commands/workspace/index.mdx b/website/docs/cli/commands/workspace/index.mdx deleted file mode 100644 index 164a3c1bff..0000000000 --- a/website/docs/cli/commands/workspace/index.mdx +++ /dev/null @@ -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 [options] [args]` - -Choose a subcommand page for more information. diff --git a/website/docs/cli/commands/workspace/list.mdx b/website/docs/cli/commands/workspace/list.mdx deleted file mode 100644 index 371e71599d..0000000000 --- a/website/docs/cli/commands/workspace/list.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/commands/workspace/new.mdx b/website/docs/cli/commands/workspace/new.mdx deleted file mode 100644 index a9d2046e57..0000000000 --- a/website/docs/cli/commands/workspace/new.mdx +++ /dev/null @@ -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. -``` diff --git a/website/docs/cli/commands/workspace/select.mdx b/website/docs/cli/commands/workspace/select.mdx deleted file mode 100644 index 1a94d4d3b9..0000000000 --- a/website/docs/cli/commands/workspace/select.mdx +++ /dev/null @@ -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". -``` diff --git a/website/docs/cli/commands/workspace/show.mdx b/website/docs/cli/commands/workspace/show.mdx deleted file mode 100644 index 474267b0de..0000000000 --- a/website/docs/cli/commands/workspace/show.mdx +++ /dev/null @@ -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 -``` diff --git a/website/docs/cli/config/config-file.mdx b/website/docs/cli/config/config-file.mdx deleted file mode 100644 index 2b57c63f05..0000000000 --- a/website/docs/cli/config/config-file.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/config/environment-variables.mdx b/website/docs/cli/config/environment-variables.mdx deleted file mode 100644 index fea2737921..0000000000 --- a/website/docs/cli/config/environment-variables.mdx +++ /dev/null @@ -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 - - - -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. diff --git a/website/docs/cli/config/index.mdx b/website/docs/cli/config/index.mdx deleted file mode 100644 index d045d43fe2..0000000000 --- a/website/docs/cli/config/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/import/index.mdx b/website/docs/cli/import/index.mdx deleted file mode 100644 index 08d259693b..0000000000 --- a/website/docs/cli/import/index.mdx +++ /dev/null @@ -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). \ No newline at end of file diff --git a/website/docs/cli/import/usage.mdx b/website/docs/cli/import/usage.mdx deleted file mode 100644 index 5c10578150..0000000000 --- a/website/docs/cli/import/usage.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/index.mdx b/website/docs/cli/index.mdx deleted file mode 100644 index f9bda3b6d1..0000000000 --- a/website/docs/cli/index.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/init/index.mdx b/website/docs/cli/init/index.mdx deleted file mode 100644 index 4f6b7773d7..0000000000 --- a/website/docs/cli/init/index.mdx +++ /dev/null @@ -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`. diff --git a/website/docs/cli/inspect/index.mdx b/website/docs/cli/inspect/index.mdx deleted file mode 100644 index 14733e24aa..0000000000 --- a/website/docs/cli/inspect/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/plugins/index.mdx b/website/docs/cli/plugins/index.mdx deleted file mode 100644 index 7d47bc1c76..0000000000 --- a/website/docs/cli/plugins/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/plugins/signing.mdx b/website/docs/cli/plugins/signing.mdx deleted file mode 100644 index ca3c4f09ac..0000000000 --- a/website/docs/cli/plugins/signing.mdx +++ /dev/null @@ -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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - - - -# 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). diff --git a/website/docs/cli/run/index.mdx b/website/docs/cli/run/index.mdx deleted file mode 100644 index 52a752b375..0000000000 --- a/website/docs/cli/run/index.mdx +++ /dev/null @@ -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). diff --git a/website/docs/cli/state/index.mdx b/website/docs/cli/state/index.mdx deleted file mode 100644 index dd9c66aa44..0000000000 --- a/website/docs/cli/state/index.mdx +++ /dev/null @@ -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) - - diff --git a/website/docs/cli/state/inspect.mdx b/website/docs/cli/state/inspect.mdx deleted file mode 100644 index 6a13582423..0000000000 --- a/website/docs/cli/state/inspect.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/state/move.mdx b/website/docs/cli/state/move.mdx deleted file mode 100644 index 9cc3df4f07..0000000000 --- a/website/docs/cli/state/move.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/state/recover.mdx b/website/docs/cli/state/recover.mdx deleted file mode 100644 index 676d5986c9..0000000000 --- a/website/docs/cli/state/recover.mdx +++ /dev/null @@ -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. \ No newline at end of file diff --git a/website/docs/cli/state/resource-addressing.mdx b/website/docs/cli/state/resource-addressing.mdx deleted file mode 100644 index 2d0b3a61c8..0000000000 --- a/website/docs/cli/state/resource-addressing.mdx +++ /dev/null @@ -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". diff --git a/website/docs/cli/state/taint.mdx b/website/docs/cli/state/taint.mdx deleted file mode 100644 index 00e6ebe81d..0000000000 --- a/website/docs/cli/state/taint.mdx +++ /dev/null @@ -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. diff --git a/website/docs/cli/test/index.mdx b/website/docs/cli/test/index.mdx deleted file mode 100644 index 17af884f66..0000000000 --- a/website/docs/cli/test/index.mdx +++ /dev/null @@ -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. \ No newline at end of file diff --git a/website/docs/cli/workspaces/index.mdx b/website/docs/cli/workspaces/index.mdx deleted file mode 100644 index 1f120f73a9..0000000000 --- a/website/docs/cli/workspaces/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/archiving.mdx b/website/docs/internals/archiving.mdx deleted file mode 100644 index 7d95182562..0000000000 --- a/website/docs/internals/archiving.mdx +++ /dev/null @@ -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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - - - -# 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 __. diff --git a/website/docs/internals/credentials-helpers.mdx b/website/docs/internals/credentials-helpers.mdx deleted file mode 100644 index 07e212af7d..0000000000 --- a/website/docs/internals/credentials-helpers.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/debugging.mdx b/website/docs/internals/debugging.mdx deleted file mode 100644 index 2558f6474c..0000000000 --- a/website/docs/internals/debugging.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/functions-meta.mdx b/website/docs/internals/functions-meta.mdx deleted file mode 100644 index 81e946126a..0000000000 --- a/website/docs/internals/functions-meta.mdx +++ /dev/null @@ -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 ``) 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": [ - , - … - ], - - // "variadic_parameter" is an optional representation of the - // additional arguments that the function accepts after those - // matching with the fixed parameters. - "variadic_parameter": - }, - "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" -} -``` diff --git a/website/docs/internals/graph.mdx b/website/docs/internals/graph.mdx deleted file mode 100644 index 24bea75f75..0000000000 --- a/website/docs/internals/graph.mdx +++ /dev/null @@ -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 - - - -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. diff --git a/website/docs/internals/index.mdx b/website/docs/internals/index.mdx deleted file mode 100644 index 4221120ae5..0000000000 --- a/website/docs/internals/index.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/json-format.mdx b/website/docs/internals/json-format.mdx deleted file mode 100644 index 80d32a0a06..0000000000 --- a/website/docs/internals/json-format.mdx +++ /dev/null @@ -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=`, 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 ` 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 ``) 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 `. -- [Plan Representation](#plan-representation) — The complete top-level object returned by `terraform show -json `. -- [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 `` 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": - - "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": , - - // "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": , - - // "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": , - - // "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": , - - // "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 is detailed in a section below. - "change": , - - // "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": , - } - }, - - // "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" -} -``` - -This overall plan structure, fully expanded, is what will be printed by the `terraform show -json ` 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 ``: - -```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": - } - }, - - // "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": , - "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": - }, - ], - - // "expressions" describes the resource-type-specific content of the - // configuration block. - "expressions": , - - // "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": , - "for_each_expression": - }, - ], - - // "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": , - - // "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": , - "for_each_expression": , - - // "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": - } - } - } -} -``` - -### Expression Representation - -Each unevaluated expression in the configuration is represented with an `` 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 `` structure: - -```javascript -{ - // Attribute arguments are mapped directly with the attribute name as key and - // an as value. - "ami": , - "instance_type": , - - // Nested block arguments are mapped as either a single nested - // or an array object of these, depending on the - // block nesting mode chosen in the schema. - // - "single" nesting is a direct - // - "list" and "set" produce arrays - // - "map" produces an object - "root_block_device": , - "ebs_block_device": [ - - ] -} -``` - -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 `` 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": , - "after": , - - // "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 `` 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. diff --git a/website/docs/internals/login-protocol.mdx b/website/docs/internals/login-protocol.mdx deleted file mode 100644 index 8798c85edd..0000000000 --- a/website/docs/internals/login-protocol.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/machine-readable-ui.mdx b/website/docs/internals/machine-readable-ui.mdx deleted file mode 100644 index a58d17ee94..0000000000 --- a/website/docs/internals/machine-readable-ui.mdx +++ /dev/null @@ -1,1072 +0,0 @@ ---- -page_title: Machine-readable output reference -description: >- - Terraform streams machine-readable output in JSON format, letting you use third-party tools to monitor 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Machine-readable UI Output Reference - -This topic provides reference information about the machine-readable output Terraform prints. - -## Introduction - -By default, many Terraform commands display UI output as unstructured text that is intended to be read in a terminal emulator. This text stream is not a stable interface for integrations. Some commands support a `-json` flag, which enables a structured JSON output mode with a defined interface. - -For long-running commands such as `plan`, `apply`, `refresh`, and `test`, the `-json` flag outputs a stream of JSON UI messages. The ouptut messages appear one per line so that you can process the messages by integrating software filtering, combining, or modifying the output as desired. - -The first message output has type `version`, and includes a `ui` 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. - -Refer to -[Terraform 1.0 Compatibility Promises](/terraform/language/v1-compatibility-promises) for additional information. - -## Sample JSON Output - -Below is sample output from running `terraform apply -json`: - -```javascript -{"@level":"info","@message":"Terraform 0.15.4","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.275359-04:00","terraform":"0.15.4","type":"version","ui":"0.1.0"} -{"@level":"info","@message":"random_pet.animal: Plan to create","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.705503-04:00","change":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"planned_change"} -{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.705638-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"} -{"@level":"info","@message":"random_pet.animal: Creating...","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.825308-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"apply_start"} -{"@level":"info","@message":"random_pet.animal: Creation complete after 0s [id=smart-lizard]","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.826179-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create","id_key":"id","id_value":"smart-lizard","elapsed_seconds":0},"type":"apply_complete"} -{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 0 destroyed.","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.869168-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"apply"},"type":"change_summary"} -{"@level":"info","@message":"Outputs: 1","@module":"terraform.ui","@timestamp":"2021-05-25T13:32:41.869280-04:00","outputs":{"pets":{"sensitive":false,"type":"string","value":"smart-lizard"}},"type":"outputs"} -``` - -Each line consists of a JSON object with several keys common to all messages. These are: - -- `@level`: this is normally "info", but can be "error" or "warn" when showing diagnostics -- `@message`: a human-readable summary of the contents of this message -- `@module`: always "terraform.ui" when rendering UI output -- `@timestamp`: an RFC3339 timestamp of when the message was output -- `type`: defines which kind of message this is and determines how to interpret other keys which may be present - -Clients presenting the logs as a user interface should handle unexpected message types by presenting at least the `@message` field to the user. - -Messages will be emitted as events occur to trigger them. This means that messages related to several resources may be interleaved (if Terraform is running with concurrency above 1). The [`resource` object value](#resource-object) can be used to link multiple messages about a single resource. - -## Message Types - -The following message types are supported: - -### Generic Messages - -- `version`: information about the Terraform version and the version of the schema used for the following messages -- `log`: unstructured human-readable log lines -- `diagnostic`: diagnostic warning or error messages; [see the `terraform validate` docs for more details on the format](/terraform/cli/commands/validate#json) - -### Operation Results - -- `resource_drift`: describes a detected change to a single resource made outside of Terraform -- `planned_change`: describes a planned change to a single resource -- `change_summary`: summary of all planned or applied changes -- `outputs`: list of all root module outputs - -### Resource Progress - -- `apply_start`, `apply_progress`, `apply_complete`, `apply_errored`: sequence of messages indicating progress of a single resource through apply -- `provision_start`, `provision_progress`, `provision_complete`, `provision_errored`: sequence of messages indicating progress of a single provisioner step -- `refresh_start`, `refresh_complete`: sequence of messages indicating progress of a single resource through refresh - -### Test Results - -- `test_abstract`: describes the test operation that Terraform executes -- `test_file`: describes the status of a completed test file -- `test_run`: describes the status of a completed `run` block within a test file -- `test_cleanup`: describes the result of the test cleanup after a completed test file -- `test_summary`: describes the overall status of the completed test operation -- `test_plan`: describes the output of a given `run` block when `command = plan` -- `test_state`: describes the output of a given `run` block when `command = apply` -- `test_interrupt`: describes the result of an interrupted test operation - -## Version Message - -A machine-readable UI command output will always begin with a `version` message. The following message-specific keys are defined: - -- `terraform`: the Terraform version which emitted this message -- `ui`: the machine-readable UI schema version defining the meaning of the following messages - -### Example - -```json -{ - "@level": "info", - "@message": "Terraform 0.15.4", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.275359-04:00", - "terraform": "0.15.4", - "type": "version", - "ui": "0.1.0" -} -``` - -## Resource Drift - -If drift is detected during planning, Terraform will emit a `resource_drift` message for each resource which has changed outside of Terraform. This message has an embedded `change` object with the following keys: - -- `resource`: object describing the address of the resource to be changed; see [resource object](#resource-object) below for details -- `action`: the action planned to be taken for the resource. Values: `update`, `delete`. - -This message does not include details about the exact changes which caused the change to be planned. That information is available in [the JSON plan output](/terraform/internals/json-format). - -### Example - -```json -{ - "@level": "info", - "@message": "random_pet.animal: Drift detected (update)", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.705503-04:00", - "change": { - "resource": { - "addr": "random_pet.animal", - "module": "", - "resource": "random_pet.animal", - "implied_provider": "random", - "resource_type": "random_pet", - "resource_name": "animal", - "resource_key": null - }, - "action": "update" - }, - "type": "resource_drift" -} -``` - -## Planned Change - -At the end of a plan or before an apply, Terraform will emit a `planned_change` message for each resource which has changes to apply. This message has an embedded `change` object with the following keys: - -- `resource`: object describing the address of the resource to be changed; see [resource object](#resource-object) below for details -- `previous_resource`: object describing the previous address of the resource, if this change includes a configuration-driven move -- `action`: the action planned to be taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete`, `move`, `import`. -- `reason`: an optional reason for the change, only used when the action is `replace` or `delete`. Values: - - `tainted`: resource was marked as tainted - - `requested`: user requested that the resource be replaced, for example via the `-replace` plan flag - - `cannot_update`: changes to configuration force the resource to be deleted and created rather than updated - - `delete_because_no_resource_config`: no matching resource in configuration - - `delete_because_wrong_repetition`: resource instance key has no corresponding `count` or `for_each` in configuration - - `delete_because_count_index`: resource instance key is outside the range of the `count` argument - - `delete_because_each_key`: resource instance key is not included in the `for_each` argument - - `delete_because_no_module`: enclosing module instance is not in configuration - -This message does not include details about the exact changes which caused the change to be planned. That information is available in [the JSON plan output](/terraform/internals/json-format). - -### Example - -```json -{ - "@level": "info", - "@message": "random_pet.animal: Plan to create", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.705503-04:00", - "change": { - "resource": { - "addr": "random_pet.animal", - "module": "", - "resource": "random_pet.animal", - "implied_provider": "random", - "resource_type": "random_pet", - "resource_name": "animal", - "resource_key": null - }, - "action": "create" - }, - "type": "planned_change" -} -``` - -## Change Summary - -Terraform outputs a change summary when a plan or apply operation completes. Both message types include a `changes` object, which has the following keys: - -- `add`: count of resources to be created (including as part of replacement) -- `change`: count of resources to be changed in-place -- `remove`: count of resources to be destroyed (including as part of replacement) -- `operation`: one of `plan`, `apply`, or `destroy` - -### Example - -```json -{ - "@level": "info", - "@message": "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.869168-04:00", - "changes": { - "add": 1, - "change": 0, - "remove": 0, - "operation": "apply" - }, - "type": "change_summary" -} -``` - -## Outputs - -After a successful plan or apply, a message with type `outputs` contains the values of all root module output values. This message contains an `outputs` object, the keys of which are the output names. The outputs values are objects with the following keys: - -- `action`: for planned outputs, the action which will be taken for the output. Values: `noop`, `create`, `update`, `delete` -- `value`: for applied outputs, the value of the output, encoded in JSON -- `type`: for applied outputs, the detected HCL type of the output value -- `sensitive`: boolean value, `true` if the output is sensitive and should be hidden from UI by default - -Note that `sensitive` outputs still include the `value` field, and integrating software should respect the sensitivity value as appropriate for the given use case. - -### Example - -```json -{ - "@level": "info", - "@message": "Outputs: 1", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.869280-04:00", - "outputs": { - "pets": { - "sensitive": false, - "type": "string", - "value": "smart-lizard" - } - }, - "type": "outputs" -} -``` - -## Operation Messages - -Performing Terraform operations to a resource will often result in several messages being emitted. The message types include: - -- `apply_start`: when starting to apply changes for a resource -- `apply_progress`: periodically, showing elapsed time output -- `apply_complete`: on successful operation completion -- `apply_errored`: when an error is encountered during the operation -- `provision_start`: when starting a provisioner step -- `provision_progress`: on provisioner output -- `provision_complete`: on successful provisioning -- `provision_errored`: when an error is enountered during provisioning -- `refresh_start`: when reading a resource during refresh -- `refresh_complete`: on successful refresh -- `ephemeral_op_start`: when starting an ephemeral resource operation -- `ephemeral_op_progress`: periodically showing elapsed time output during ephemeral resource operation -- `ephemeral_op_complete`: on successful ephemeral resource operation completion -- `ephemeral_op_errored`: when an error is encountered during ephemeral resource operation - -Each of these messages has a `hook` object, which has different fields for each type. All hooks have a [`resource` object](#resource-object) which identifies which resource is the subject of the operation. - -## Apply Start - -The `apply_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action to be taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete` -- `id_key` and `id_value`: a key/value pair used to identify this instance of the resource, omitted when unknown - -### Example - -```json -{ - "@level": "info", - "@message": "random_pet.animal: Creating...", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.825308-04:00", - "hook": { - "resource": { - "addr": "random_pet.animal", - "module": "", - "resource": "random_pet.animal", - "implied_provider": "random", - "resource_type": "random_pet", - "resource_name": "animal", - "resource_key": null - }, - "action": "create" - }, - "type": "apply_start" -} -``` - -## Apply Progress - -The `apply_progress` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action being taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete` -- `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[4]: Still creating... [30s elapsed]", - "@module": "terraform.ui", - "@timestamp": "2021-03-17T09:34:26.222465-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[4]", - "module": "", - "resource": "null_resource.none[4]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 4 - }, - "action": "create", - "elapsed_seconds": 30 - }, - "type": "apply_progress" -} -``` - -## Apply Complete - -The `apply_complete` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete` -- `id_key` and `id_value`: a key/value pair used to identify this instance of the resource, omitted when unknown -- `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds - -### Example - -```json -{ - "@level": "info", - "@message": "random_pet.animal: Creation complete after 0s [id=smart-lizard]", - "@module": "terraform.ui", - "@timestamp": "2021-05-25T13:32:41.826179-04:00", - "hook": { - "resource": { - "addr": "random_pet.animal", - "module": "", - "resource": "random_pet.animal", - "implied_provider": "random", - "resource_type": "random_pet", - "resource_name": "animal", - "resource_key": null - }, - "action": "create", - "id_key": "id", - "id_value": "smart-lizard", - "elapsed_seconds": 0 - }, - "type": "apply_complete" -} -``` - -## Apply Errored - -The `apply_complete` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action taken for the resource. Values: `noop`, `create`, `read`, `update`, `replace`, `delete` -- `elapsed_seconds`: time elapsed since the apply operation started, expressed as an integer number of seconds - -The exact detail of the error will be rendered as a separate `diagnostic` message. - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: Creation errored after 10s", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T16:38:54.013910-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "action": "create", - "elapsed_seconds": 10 - }, - "type": "apply_errored" -} -``` - -## Provision Start - -The `provision_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `provisioner`: the type of provisioner - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: Provisioning with 'local-exec'...", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T16:38:43.997431-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "provisioner": "local-exec" - }, - "type": "provision_start" -} -``` - -## Provision Progress - -The `provision_progress` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `provisioner`: the type of provisioner -- `output`: the output log from the provisioner - -One `provision_progress` message is output for each log line received from the provisioner. - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T16:38:43.997869-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "provisioner": "local-exec", - "output": "Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]" - }, - "type": "provision_progress" -} -``` - -## Provision Complete - -The `provision_complete` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `provisioner`: the type of provisioner - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: (local-exec) Provisioning complete", - "@module": "terraform.ui", - "@timestamp": "2021-03-17T09:34:06.239043-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "provisioner": "local-exec" - }, - "type": "provision_complete" -} -``` - -## Provision Errored - -The `provision_errored` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `provisioner`: the type of provisioner - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: (local-exec) Provisioning errored", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T16:38:54.013572-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "provisioner": "local-exec" - }, - "type": "provision_errored" -} -``` - -## Refresh Start - -The `refresh_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `id_key` and `id_value`: a key/value pair used to identify this instance of the resource - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: Refreshing state... [id=1971614370559474622]", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T14:18:06.508915-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "id_key": "id", - "id_value": "1971614370559474622" - }, - "type": "refresh_start" -} -``` - -## Refresh Complete - -The `refresh_complete` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `id_key` and `id_value`: a key/value pair used to identify this instance of the resource - -### Example - -```json -{ - "@level": "info", - "@message": "null_resource.none[0]: Refresh complete [id=1971614370559474622]", - "@module": "terraform.ui", - "@timestamp": "2021-03-26T14:18:06.509371-04:00", - "hook": { - "resource": { - "addr": "null_resource.none[0]", - "module": "", - "resource": "null_resource.none[0]", - "implied_provider": "null", - "resource_type": "null_resource", - "resource_name": "none", - "resource_key": 0 - }, - "id_key": "id", - "id_value": "1971614370559474622" - }, - "type": "refresh_complete" -} -``` - -## Ephemeral Operation Start - -The `ephemeral_op_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action the ephemeral resource is going through. Values: `open`, `renew`, `close` - -### Example - -```json -{ - "@level": "info", - "@message": "ephemeral.random_password.example: Opening...", - "@module": "terraform.ui", - "@timestamp": "2024-10-30T10:34:26.222465-00:00", - "hook": { - "resource": { - "addr": "ephemeral.random_password.example", - "module": "", - "resource": "ephemeral.random_password.example", - "implied_provider": "random", - "resource_type": "random_password", - "resource_name": "example", - "resource_key": null - }, - "action": "open" - }, - "type": "ephemeral_op_start" -} -``` - -## Ephemeral Operation Progress - -The `ephemeral_op_progress` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action the ephemeral resource is going through. Values: `open`, `renew`, `close` -- `elapsed_seconds`: time elapsed since the operation started, expressed as an integer number of seconds - -### Example - -```json -{ - "@level": "info", - "@message": "ephemeral.random_password.example: Closing... [3s elapsed]", - "@module": "terraform.ui", - "@timestamp": "2024-10-30T10:34:26.222465-00:00", - "hook": { - "resource": { - "addr": "ephemeral.random_password.example", - "module": "", - "resource": "ephemeral.random_password.example", - "implied_provider": "random", - "resource_type": "random_password", - "resource_name": "example", - "resource_key": null - }, - "action": "close", - "elapsed_seconds": 3 - }, - "type": "ephemeral_op_progress" -} -``` - -## Ephemeral Operation Complete - -The `ephemeral_op_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action the ephemeral resource is going through. Values: `open`, `renew`, `close` -- `elapsed_seconds`: time elapsed since the operation started, expressed as an integer number of seconds - -### Example - -```json -{ - "@level": "info", - "@message": "ephemeral.random_password.example: Opening complete after 1s", - "@module": "terraform.ui", - "@timestamp": "2024-10-30T10:34:26.222465-00:00", - "hook": { - "resource": { - "addr": "ephemeral.random_password.example", - "module": "", - "resource": "ephemeral.random_password.example", - "implied_provider": "random", - "resource_type": "random_password", - "resource_name": "example", - "resource_key": null - }, - "action": "open", - "elapsed_seconds": 1 - }, - "type": "ephemeral_op_complete" -} -``` - -## Ephemeral Operation Errored - -The `ephemeral_op_start` message `hook` object has the following keys: - -- `resource`: a [`resource` object](#resource-object) identifying the resource -- `action`: the action the ephemeral resource is going through. Values: `open`, `renew`, `close` -- `elapsed_seconds`: time elapsed since the operation started, expressed as an integer number of seconds - -The exact detail of the error will be rendered as a separate `diagnostic` message. - -### Example - -```json -{ - "@level": "info", - "@message": "ephemeral.random_password.example: Opening errored after 2s", - "@module": "terraform.ui", - "@timestamp": "2024-10-30T10:34:26.222465-00:00", - "hook": { - "resource": { - "addr": "ephemeral.random_password.example", - "module": "", - "resource": "ephemeral.random_password.example", - "implied_provider": "random", - "resource_type": "random_password", - "resource_name": "example", - "resource_key": null - }, - "action": "open", - "elapsed_seconds": 2 - }, - "type": "ephemeral_op_errored" -} -``` - -## Resource Object - -The `resource` object is a decomposed structure representing a resource address in configuration, which is used to identify which resource a given message is associated with. The object has the following keys: - -- `addr`: the full unique address of the resource as a string -- `module`: the address of the module containing the resource, in the form `module.foo.module.bar`, or an empty string for a root module resource -- `resource`: the module-relative address, which is identical to `addr` for root module resources -- `resource_type`: the type of resource being addressed -- `resource_name`: the name label for the resource -- `resource_key`: the address key (`count` or `for_each` value), or `null` if the neither are used -- `implied_provider`: the provider type implied by the resource type; this may not reflect the resource's provider if provider aliases are used - -### Example - -```json -{ - "addr": "module.pets.random_pet.pet[\"friend\"]", - "module": "module.pets", - "resource": "random_pet.pet[\"friend\"]", - "implied_provider": "random", - "resource_type": "random_pet", - "resource_name": "pet", - "resource_key": "friend" -} -``` - -## Test Abstract - -The `terraform test` command emits a `test_abstract` message describing the test files and `run` blocks that Terraform executes during the upcoming operation. - -### Example - -```json -{ - "@level": "info", - "@message": "Found 1 file and 2 run blocks", - "@module": "terraform.ui", - "@timestamp": "2023-08-09T16:12:30.325582+02:00", - "test_abstract": { - "validation.tftest.hcl": [ - "passed_validation", - "failed_validatation" - ] - }, - "type": "test_abstract" -} -``` - -## Test File - -Throughout a `terraform test` execution, Terraform will produce several progress updates for each test file. The progress field can be `starting`, `teardown`, or `complete`. Each test file will emit each progress update exactly once. When a test file emits the `complete` progress update, it will also include a status field containing one of `pass`, `error`, `fail`, or `skip` denoting the overall status of the completed test file. - -### Example - -```json -{ - "@level": "info", - "@message": "main.tftest.hcl... pass", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@timestamp": "2023-08-09T16:12:30.724368+02:00", - "test_file": { - "path": "validation.tftest.hcl", - "progress": "complete", - "status": "pass" - }, - "type": "test_file" -} -``` - -## Test Run - -While executing `run` blocks within a test file, Terraform will also produce several status updates for each `run` block. The progress field for a `run` block progress update can be `starting`, `running`, `teardown`, and `complete`. The `starting` and `complete` progress updates will be emitted exactly once. While the `running` and `teardown` progress updates can be emitted multiple times. - -The `starting`, `running` and `teardown` updates will also include an `elapsed` field indicating the number of milliseconds the current test operation (for `starting` and `running`) or the current destroy operation (for `teardown`) has been in progress. - -The `complete` progress update will also include a `status` field containing one of `pass`, `error`, `fail`, or `skip` denoting the overall status of the completed `run` block`. - -Not every `run` block will emit `teardown` progress updates, as only the most recently executed `run` blocks reference the latest in-memory state files that need to be torn down. In addition, the `run` block tear down process is only initiated once the overall test file has already emitted its `teardown` status update. This means you can expect the `complete` progress update to be issued for a `run` block before any `teardown` updates are provided. There will always be a `complete` progress update issued by the enclosing test file when the tear down process for all `run` blocks is complete. - -### Examples - -```json -{ - "@level": "info", - "@message": " \"successful_validation\"... pass", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T16:12:30.724407+02:00", - "test_run": { - "path": "main.tftest.hcl", - "run": "successful_validation", - "progress": "complete", - "status": "pass" - }, - "type": "test_run" -} -``` - -```json -{ - "@level": "info", - "@message": " \"successful_validation\"... in progress", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T16:12:30.724407+02:00", - "test_run": { - "path": "main.tftest.hcl", - "run": "successful_validation", - "progress": "running", - "elapsed": 2024 - }, - "type": "test_run" -} -``` - -## Test Cleanup - -After Terraform completes the execution of each test file, `terraform test` may emit a series of `test_cleanup` messages detailing any state it could not destroy. You must locate and destroy the resources listed in these resources manually. - -As the test framework can manage multiple state files for each test file, you can see multiple versions of this message for each state file that holds resources that Terraform could not destroy. Using the `@testrun` field, you can pinpoint the run block that last updated the state file to locate the resources that Terraform could not destroy. - -### Example - -```json -{ - "@level": "info", - "@message": "Terraform left some resources in state after executing main.tftest.hcl, they need to be cleaned up manually.", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T16:12:30.724407+02:00", - "test_cleanup": { - "failed_resources": [ - { - "instance": "aws_instance.primary" - }, - { - "instance": "aws_instance.secondary" - } - ] - }, - "type": "test_cleanup" -} -``` - -## Test Summary - -After the test operation has completed all test files, `terraform test` emits a `test_summary` message with the status of the overall test operation. - -### Example - -```json -{ - "@level": "info", - "@message": "Success! 2 passed, 0 failed.", - "@module": "terraform.ui", - "@timestamp": "2023-08-09T16:26:45.482070+02:00", - "test_summary": { - "status": "pass", - "passed": 2, - "failed": 0, - "errored": 0, - "skipped": 0 - }, - "type": "test_summary" -} -``` - -## Test Plan - -In `-verbose` mode, `terraform test` emits a `test_plan` message for all `run` blocks that executed a plan operation. The `test_plan` message contains a subset of the attributes from the `terraform show -json ` command [output](/terraform/internals/json-format#plan-representation) and the `terraform providers schema -json` command [output](/terraform/cli/commands/providers/schema#providers-schema-representation). - -The message contains the following fields representing the plan: `plan_format_version`, `output_changes`, `resource_changes`, `resource_drift` and `relevant_attributes`. These match the respective fields in the [JSON Plan Representation](/terraform/internals/json-format#plan-representation). - -The message contains the following fields representing the provider schemas: `provider_format_version` and `provider_schemas`. These match the respective fields in the [JSON Providers Schema Representation](/terraform/cli/commands/providers/schema#providers-schema-representation). - -### Example - -```json -{ - "@level": "info", - "@message": "-verbose flag enabled, printing plan", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T17:10:06.211942+02:00", - "test_plan": { - "plan_format_version": "1.2", - "resource_changes": [ - { - "address": "aws_instance.primary", - "mode": "managed", - "type": "aws_instance", - "name": "primary", - "provider_name": "registry.terraform.io/hashicorp/aws", - "change": { - "actions": [ - "create" - ], - "before": null, - "after": { - "ami": "af84f887-e3eb-9e52-5f8b-8a2803734fd0" - }, - "after_unknown": {}, - "before_sensitive": false, - "after_sensitive": {} - } - } - ], - "provider_format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/aws": { - "provider": { - "version": 0 - }, - "resource_schemas": { - "aws_instance": { - "version": 0, - "block": { - "attributes": { - "ami": { - "type": "string", - "description_kind": "plain", - "required": true - } - }, - "description_kind": "plain" - } - } - } - } - } - }, - "type": "test_plan" -} -``` - -## Test State - -In `-verbose` mode, `terraform test` emits a `test_state` message for all `run` blocks that executed an apply operation. The `test_state` message contains a subset of the `terraform show -json` command [output](/terraform/internals/json-format#state-representation) and the `terraform providers schema -json` command [output](/terraform/cli/commands/providers/schema#providers-schema-representation). - -The message contains the following fields representing the state: `state_format_version`, `root_module`, and `outputs`. These match the respective fields in the [JSON Values Representation](/terraform/internals/json-format#values-representation) that are embedded in complete JSON state representation. - -The message contains the following fields representing the provider schemas: `provider_format_version` and `provider_schemas`. These match the respective fields in the [JSON Providers Schema Representation](/terraform/cli/commands/providers/schema#providers-schema-representation). - -### Example - -```json -{ - "@level": "info", - "@message": "-verbose flag enabled, printing state", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T17:18:21.173008+02:00", - "test_state": { - "state_format_version": "1.0", - "root_module": { - "resources": [ - { - "address": "aws_instance.primary", - "mode": "managed", - "type": "aws_instance", - "name": "primary", - "provider_name": "registry.terraform.io/hashicorp/aws", - "schema_version": 0, - "values": { - "ami": "af84f887-e3eb-9e52-5f8b-8a2803734fd0" - }, - "sensitive_values": {} - } - ] - }, - "provider_format_version": "1.0", - "provider_schemas": { - "registry.terraform.io/hashicorp/aws": { - "provider": { - "version": 0 - }, - "resource_schemas": { - "aws_instance": { - "version": 0, - "block": { - "attributes": { - "ami": { - "type": "string", - "description_kind": "plain", - "required": true - } - }, - "description_kind": "plain" - } - } - } - } - } - }, - "type": "test_state" -} -``` - -## Test Interrupt - -When `terraform test` is impeded or canceled, it emits a `test_interrupt` message that describes the interrupted operation. This message includes any state that Terraform could not destroy before exiting and any leftover resources that Terraform did not finish creating. - -As with the [Test Cleanup](#test-cleanup) message, Terraform might have been maintaining multiple state files. The `state` field contains the resources from the main state for the test configuration, while the `states` field contains a map of `run` block names to the resources that each `run` block created, which Terraform could not destroy. - -Finally, the `planned` field contains any resources that were in the process of being created by the interrupted `run` block, which you can identify using the `@testrun` field. - -### Example - -```json -{ - "@level": "info", - "@message": "-verbose flag enabled, printing state", - "@module": "terraform.ui", - "@testfile": "validation.tftest.hcl", - "@testrun": "successful_validation", - "@timestamp": "2023-08-09T17:18:21.173008+02:00", - "test_interrupt": { - "state": [ - { - "instance": "aws_instance.primary" - } - ], - "states": { - "unsuccessful_validation": [ - { - "instance": "aws_instance.secondary" - } - ] - }, - "planned": [ - "aws_instance.secondary" - ] - }, - "type": "test_interrupt" -} -``` diff --git a/website/docs/internals/module-registry-protocol.mdx b/website/docs/internals/module-registry-protocol.mdx deleted file mode 100644 index 9d092159ca..0000000000 --- a/website/docs/internals/module-registry-protocol.mdx +++ /dev/null @@ -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: )` - The user or organization the module is - owned by. This is required and is specified as part of the URL path. - -- `name` `(string: )` - The name of the module. - This is required and is specified as part of the URL path. - -- `system` `(string: )` - 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: )` - The user the module is owned by. - This is required and is specified as part of the URL path. - -- `name` `(string: )` - The name of the module. - This is required and is specified as part of the URL path. - -- `system` `(string: )` - The name of the target system. - This is required and is specified as part of the URL path. - -- `version` `(string: )` - 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). diff --git a/website/docs/internals/provider-meta.mdx b/website/docs/internals/provider-meta.mdx deleted file mode 100644 index 4622640ad6..0000000000 --- a/website/docs/internals/provider-meta.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/provider-network-mirror-protocol.mdx b/website/docs/internals/provider-network-mirror-protocol.mdx deleted file mode 100644 index 64183751a5..0000000000 --- a/website/docs/internals/provider-network-mirror-protocol.mdx +++ /dev/null @@ -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. diff --git a/website/docs/internals/provider-registry-protocol.mdx b/website/docs/internals/provider-registry-protocol.mdx deleted file mode 100644 index 94c895fe5c..0000000000 --- a/website/docs/internals/provider-registry-protocol.mdx +++ /dev/null @@ -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). diff --git a/website/docs/internals/remote-service-discovery.mdx b/website/docs/internals/remote-service-discovery.mdx deleted file mode 100644 index a4c2ff3031..0000000000 --- a/website/docs/internals/remote-service-discovery.mdx +++ /dev/null @@ -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. diff --git a/website/docs/intro/core-workflow.mdx b/website/docs/intro/core-workflow.mdx deleted file mode 100644 index 4cf996d924..0000000000 --- a/website/docs/intro/core-workflow.mdx +++ /dev/null @@ -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) - - - -## 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. diff --git a/website/docs/intro/index.mdx b/website/docs/intro/index.mdx deleted file mode 100644 index 2cfedb4df7..0000000000 --- a/website/docs/intro/index.mdx +++ /dev/null @@ -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. - - - -### 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. diff --git a/website/docs/intro/phases/adopt.mdx b/website/docs/intro/phases/adopt.mdx deleted file mode 100644 index 00844b7240..0000000000 --- a/website/docs/intro/phases/adopt.mdx +++ /dev/null @@ -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. - - - -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. - - - -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). \ No newline at end of file diff --git a/website/docs/intro/phases/collaborate.mdx b/website/docs/intro/phases/collaborate.mdx deleted file mode 100644 index ee257b1620..0000000000 --- a/website/docs/intro/phases/collaborate.mdx +++ /dev/null @@ -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). \ No newline at end of file diff --git a/website/docs/intro/phases/govern.mdx b/website/docs/intro/phases/govern.mdx deleted file mode 100644 index 03c6ac5bac..0000000000 --- a/website/docs/intro/phases/govern.mdx +++ /dev/null @@ -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. \ No newline at end of file diff --git a/website/docs/intro/phases/index.mdx b/website/docs/intro/phases/index.mdx deleted file mode 100644 index 434910bc99..0000000000 --- a/website/docs/intro/phases/index.mdx +++ /dev/null @@ -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). \ No newline at end of file diff --git a/website/docs/intro/phases/scale.mdx b/website/docs/intro/phases/scale.mdx deleted file mode 100644 index 196c3a2905..0000000000 --- a/website/docs/intro/phases/scale.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -page_title: Scale Terraform -description: Define boundaries of infrastructure ownership across your team with 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Scale Terraform - -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. - -## Adopt modules across your organization - -We recommend using modules early in your Terraform adoption process to support consistent infrastructure configuration. As your Terraform usage scales, a central module registry helps teams find and use your modules rather than rewriting the same code. - -Terraform supports [multiple module distribution options](/terraform/language/modules/sources), but we recommend that you use a native Terraform module registry such as HCP Terraform or Terraform Enterprise. These both use the [module registry protocol](/terraform/internals/module-registry-protocol), which is the Terraform-specific protocol to discover metadata about modules available for installation and to locate the distribution package for a selected module. - -If you cannot use a native module registry, there are other source options such as [Git repositories](/terraform/language/modules/sources#generic-git-repository) or [AWS S3](/terraform/language/modules/sources#s3-bucket). - -Modules also help teams establish infrastructure configuration standards. For example, you can write a module to create a database used by your application that includes all of the defaults that your architecture requires. The module can define the database size, type, and handle all of the required networking. This ensures that module consumers provision infrastructure in line with your organization standards and requirements. - -Since modules define their own inputs, you can decide which parameters are configurable by the user. For example, you might want to allow them to change the size of the cluster, but not let them change the engine type. - -Read the [recommended patterns for creating modules](/terraform/tutorials/modules/pattern-module-creation). - -## Divide infrastructure responsibility - -It is common for different teams to focus on different parts of your organization's infrastructure. For example, the networking team may manage the VPCs, while the application team only needs to know where to deploy their application and focuses on configuring servers and databases. In this scenario, there is a division of responsibilities but the application team still needs to access data about the networking resources for their own configuration. - -Terraform lets you [reference data about other resources](/terraform/language/state/remote#delegation-and-teamwork) in your configuration without having to manage them in the same state file, allowing you to maintain distinct areas of ownership and infrastructure decoupling. You can use data sources to query a provider for more data about a particular resource, or reference output values from another state file using the remote state data source. HCP Terraform lets you explicitly grant access to your workspace state file to only the workspaces that need it, reducing access to potentially sensitive data. You can also use the [tfe_outputs](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) data source to access the outputs of another HCP Terraform workspace. - -## Consider multiple IaaS accounts - -Many Terraform users start by deploying to a single account in their cloud provider. This makes sense when you are managing only a few resources. As your Terraform adoption matures, managing thousands of resources across several cloud providers can become very complex, slow, and hard to secure. One strategy is to split your managed resources into multiple accounts in a way that makes sense to your organization. For example, you may want an account per deployment environment, such as one for development and one for production. - -## Next steps - -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). \ No newline at end of file diff --git a/website/docs/intro/terraform-editions.mdx b/website/docs/intro/terraform-editions.mdx deleted file mode 100644 index 3752a6ce13..0000000000 --- a/website/docs/intro/terraform-editions.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -layout: "intro" -page_title: "Terraform Editions" -sidebar_current: "what" -description: |- - Learn how Terraform Community Edition, HCP Terraform, and Terraform Enterprise solve increasingly complex infrastructure and collaboration challenges. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Editions Overview - -As your organization adopts infrastructure as code (IaC), you will encounter increasingly complex technical and collaboration challenges. We offer three Terraform editions designed to help you solve them. - -## Terraform Community Edition - -Terraform Community Edition is a free, downloadable tool that you interact with on the command line. It lets you provision infrastructure on any cloud provider and manages configuration, plugins, infrastructure, and state. - -### Why Terraform Community Edition? - -Terraform Community Edition lets you: - -- Adopt infrastructure as code and use a common configuration language to provision thousands of different types of resources and services. -- Codify your infrastructure so that you can check configuration files into a version control system (VCS) to safely manage contributions. Manually pull the most up-to-date version to perform Terraform operations. -- Use and publish public infrastructure templates called modules to implement industry and organization best practices, group your infrastructure into logically-related components, and deploy infrastructure more quickly. - - -### Resources - -- Get Started tutorials for popular 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) -- [What is Terraform?](/terraform/intro) -- [Configuration Language Documentation](/terraform/language) -- [CLI Documentation](/terraform/cli) - -## HCP Terraform - -HCP Terraform is a SaaS application that runs Terraform in a stable, remote environment and securely stores state and secrets. It includes a rich user interface that helps you better understand your Terraform operations and resources, allows you to define role-based access controls, and offers a private registry for sharing modules and providers. HCP Terraform also integrates with the Terraform CLI and connects to common version control systems (VCS) like GitHub, GitLab, and Bitbucket. When you connect an HCP Terraform workspace to a VCS repository, new commits and changes can automatically trigger Terraform plans. HCP Terraform also offers an API, allowing you to integrate it into existing workflows. - -Many HCP Terraform features are free for small teams; we offer paid plans for larger organizations with additional collaboration and governance features. - -### Why HCP Terraform? - -HCP Terraform lets you: - -- Run Terraform from the local CLI or in a remote environment, trigger operations through your version control system, or use an API to integrate HCP Terraform into your existing workflows. -- Ensure that only approved teams can access, edit, and provision infrastructure with HCP Terraform workspaces, single sign-on, and role-based access controls. -- Securely store and version Terraform state remotely, with encryption at rest. Versioned state files allow you to access state file history. -- Publish configuration modules in the HCP Terraform private registry that define approved infrastructure patterns. For example, a module may allow users to choose the cloud provider on which to deploy their Java application. This allows consumers to implement your organization’s best practices without becoming infrastructure or cloud experts. -- Enforce best practices and security rules with the Sentinel embedded policy as code framework. For example, policies may restrict regions for production deployments. - -### Resources - -- [Create an HCP Terraform Account](https://app.terraform.io/public/signup/account) -- [HCP Terraform Documentation](/terraform/cloud-docs) -- [Sentinel Documentation](/terraform/cloud-docs/policy-enforcement) -- [Get Started - HCP Terraform](/terraform/tutorials/cloud-get-started) tutorials show you how to manage infrastructure using HCP Terraform's VCS integration - -## Terraform Enterprise - -Terraform Enterprise allows you to set up a self-hosted distribution of HCP Terraform. It offers customizable resource limits and is ideal for organizations with strict security and compliance requirements. - -### Why Terraform Enterprise? - -Terraform Enterprise lets you: - -- Set up a private instance of HCP Terraform with dedicated support from HashiCorp. -- Accommodate advanced security and compliance requirements. Terraform Enterprise supports several types of installations, including air gapped and active/active architecture, and allows private networking and job scaling for better performance. - -### Resources -- [Terraform Pricing](https://www.hashicorp.com/products/terraform/pricing) -- [Terraform Enterprise Documentation](/terraform/enterprise) -- [Recommended Enterprise Patterns](/terraform/tutorials/recommended-patterns) guides diff --git a/website/docs/intro/use-cases.mdx b/website/docs/intro/use-cases.mdx deleted file mode 100644 index e6468e78d7..0000000000 --- a/website/docs/intro/use-cases.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -layout: "intro" -page_title: "Use Cases" -sidebar_current: "use-cases" -description: |- - Learn about Terraform use cases, such as enabling multi-cloud deployments, application management, policy compliance, and self-service 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 Use Cases - -[HashiCorp Terraform](/terraform/intro) is an infrastructure as code (IaC) tool that lets you define infrastructure resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to safely and efficiently provision and manage your infrastructure throughout its lifecycle. - -This page describes popular Terraform use cases and provides related resources that you can use to create Terraform configurations and workflows. - -## Codify your infrastructure - -By capturing and building your infrastructure as code, you make your deployments faster, repeatable, and easier to collaborate on. Terraform codifies cloud APIs into declarative configuration files using HashiCorp Configuration Language (HCL). You define the desired state of your infrastructure in HCL, and Terraform deploys and configures resources to match your configuration. - -You can use Terraform to configure your networks, servers, and databases, as well as manage other your resources such as containers, machine images, web services, and observability services. - -- Get started with Terraform on [AWS](/terraform/tutorials/aws-get-started), [Azure](/terraform/tutorials/azure-get-started), [Google Cloud](/terraform/tutorials/gcp-get-started), or [Docker](/terraform/tutorials/docker-get-started). -- Read HashiCorp's Well-Architected Framework to learn how to [codify your infrastructure with Terraform](/operational-excellence/operational-excellence-manage-your-infrastructure-components-with-terraform). - -## Multi-cloud deployment - -Provisioning infrastructure across multiple clouds increases fault-tolerance, allowing for more graceful recovery from cloud provider outages. However, multi-cloud deployments add complexity because each provider has its own interfaces, tools, and workflows. Terraform lets you use the same workflow to manage multiple providers and handle cross-cloud dependencies. This simplifies management and orchestration for large-scale, multi-cloud infrastructures. - -- Learn how to [standardize artifacts across multiple cloud providers](https://developer.hashicorp.com/packer/tutorials/cloud-production/multicloud) with Terraform and Packer. -- Try our [Deploy Federated Multi-Cloud Kubernetes Clusters](/terraform/tutorials/networking/multicloud-kubernetes) tutorial to provision Kubernetes clusters in both Azure and AWS environments, configure Consul federation with mesh gateways across the two clusters, and deploy microservices across the two clusters to verify federation. -- Browse the [Terraform Registry](https://registry.terraform.io/browse/providers) to find thousands of publicly available providers. - -## Multi-environment deployments - -Application development workflows can depend on multiple environments to test features, such as QA and staging, before releasing them to production. As production grows more complex, it becomes increasingly difficult to synchronize deployments and keep them up-to-date for each stage of the development process. - -[Terraform Stacks](/terraform/language/stacks) let you split your Terraform configuration into components and then deploy and manage those components across multiple environments. You can manage the lifecycle of each deployment separately, making it easy to validate changes throughout your deployments. - -- Learn about [Stacks use cases](https://developer.hashicorp.com/terraform/language/stacks/use-cases). -- Read the [Deploy a Stack with HCP Terraform](/terraform/tutorials/cloud/stacks-deploy) tutorial to get hands-on experience. You will create a Terraform Stack that deploys an AWS Lambda function across a development, test, and production environment. - -## Application infrastructure deployment, scaling, and monitoring tools - -You can use Terraform to efficiently deploy, release, scale, and monitor infrastructure for multi-tier applications. N-tier application architecture lets you scale application components independently and provides a separation of concerns. An application could consist of a pool of web servers that use a database tier, with additional tiers for API servers, caching servers, and routing meshes. Terraform allows you to manage the resources in each tier together, and automatically handles dependencies between tiers. For example, Terraform will deploy a database tier before provisioning the web servers that depend on it. - -- Try our [Automate Monitoring with the Terraform Datadog Provider](/terraform/tutorials/applications/datadog-provider) tutorial to deploy a demo Nginx application to a Kubernetes cluster with Helm and install the Datadog agent across the cluster. The Datadog agent reports the cluster health back to your Datadog dashboard. -- Try our [Use Application Load Balancers for Blue-Green and Canary Deployments](/terraform/tutorials/aws/blue-green-canary-tests-deployments) tutorial. You will provision the blue and green environments, add feature toggles to your Terraform configuration to define a list of potential deployment strategies, conduct a canary test, and incrementally promote your green environment. -- Read the HashiCorp Well-Architected Framework recommendations for [managing infrastructure and service monitoring](/well-architected-framework/reliability/reliability-deploy-application-monitoring-components) - - -## Self-service infrastructure - -At a large organization, your centralized operations team may get many repetitive infrastructure requests. You can use Terraform to build a "self-serve" infrastructure model that lets product teams manage their own infrastructure independently. You can create and use Terraform modules that codify the standards for deploying and managing services in your organization, allowing teams to efficiently deploy services in compliance with your organization's practices. HCP Terraform can also integrate with ticketing systems like ServiceNow to automatically generate new infrastructure requests. - -- Try the [Use Modules from the Registry](/terraform/tutorials/modules/module-use) tutorial to get started using public modules in your Terraform configuration. -Try the [Build and Use a Local Module](/terraform/tutorials/modules/module-create) tutorial to create a module to manage AWS S3 buckets. -- Follow these [ServiceNow Service Catalog Integration Setup Instructions](/terraform/cloud-docs/integrations/service-now) to connect ServiceNow to HCP Terraform. - - -## Policy compliance and management - -Terraform can help you enforce policies on the types of resources teams can provision and use. Ticket-based review processes are a bottleneck that can slow down development. Instead, you can use Sentinel, a policy-as-code framework, to automatically enforce compliance and governance policies before Terraform makes infrastructure changes. Sentinel policies are available in Terraform Enterprise and [HCP Terraform](https://www.hashicorp.com/products/terraform/pricing). - -- Try the [Control Costs with Policies](/terraform/tutorials/cloud-get-started/cost-estimation) tutorial to estimate the cost of infrastructure changes and define policy to limit it. -- The [Sentinel documentation](/terraform/cloud-docs/policy-enforcement) provides more in-depth information and a list of example policies that you can adapt for your use cases. - -## Software-defined networking - -Terraform can interact with Software Defined Networks (SDNs) to automatically configure the network according to the needs of the applications running in it. This lets you move from a ticket-based workflow to an automated one, reducing deployment times. - -For example, when a service registers with [HashiCorp Consul](https://www.consul.io/), [Consul-Terraform-Sync](/consul/docs/nia) can automatically generate Terraform configuration to expose appropriate ports and adjust network settings for any SDN that has an associated Terraform provider. Network Infrastructure Automation (NIA) allows you to safely approve the changes that your applications require without having to manually translate tickets from developers into the changes you think their applications need. - -- Try the [Network Infrastructure Automation with Consul-Terraform-Sync Intro](/consul/tutorials/network-infrastructure-automation/consul-terraform-sync-intro) tutorial to install Consul-Terraform-Sync on a node. You will then configure it to communicate with a Consul datacenter, react to service changes, and execute an example task. -- Try the [Consul-Terraform-Sync and Terraform Enterprise/Cloud Integration](/consul/tutorials/network-infrastructure-automation/consul-terraform-sync-terraform-enterprise) tutorial to configure Consul-Terraform-Sync to interact with Terraform Enterprise and HCP Terraform. - -## Kubernetes - -Kubernetes is an open-source workload scheduler for containerized applications. Terraform lets you both deploy a Kubernetes cluster and manage its resources (e.g., pods, deployments, services, etc.). You can also use the [Kubernetes Operator for Terraform](https://github.com/hashicorp/terraform-k8s) to manage cloud and on-prem infrastructure through a Kubernetes Custom Resource Definition (CRD) and HCP Terraform. - -- Learn how to provision a Kubernetes cluster in [AWS](/terraform/tutorials/kubernetes/eks), [Google Cloud Platform](/terraform/tutorials/kubernetes/gke), and [Azure](/terraform/tutorials/kubernetes/aks). -- Try the [Manage Kubernetes Resources via Terraform](/terraform/tutorials/kubernetes/kubernetes-provider) tutorial. You will use Terraform to schedule and expose a NGINX deployment on a Kubernetes cluster. -- Learn how to [deploy applications with the Helm provider](/terraform/tutorials/kubernetes/helm-provider). -- Try the [Deploy Infrastructure with the HCP Terraform Operator for Kubernetes](/terraform/tutorials/kubernetes/kubernetes-operator-v2) tutorial. You will configure and deploy the Operator to a Kubernetes cluster and use it to create an HCP Terraform workspace and provision a message queue for an example application. diff --git a/website/docs/intro/vs/boto.mdx b/website/docs/intro/vs/boto.mdx deleted file mode 100644 index eb2ca24e4e..0000000000 --- a/website/docs/intro/vs/boto.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -page_title: Terraform versus Boto, Fog, and other cloud provider client libraries -description: Learn how Terraform's syntax compares to Boto, Flog, and other cloud provider client libraries. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 versus Boto, Fog, and other cloud provider client libraries - -Libraries like Boto, Fog, etc. are used to provide native access -to cloud providers and services by using their APIs. Some -libraries are focused on specific clouds, while others attempt -to bridge them all and mask the semantic differences. Using a client -library only provides low-level access to APIs, requiring application -developers to create their own tooling to build and manage their infrastructure. - -Terraform is not intended to give low-level programmatic access to -providers, but instead provides a high level syntax for describing -how cloud resources and services should be created, provisioned, and -combined. Terraform is very flexible, using a plugin-based model to -support providers and provisioners, giving it the ability to support -almost any service that exposes APIs. diff --git a/website/docs/intro/vs/chef-puppet.mdx b/website/docs/intro/vs/chef-puppet.mdx deleted file mode 100644 index 963920bca1..0000000000 --- a/website/docs/intro/vs/chef-puppet.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -page_title: 'Terraform vs. Chef, Puppet, etc.' -description: >- - How Terraform compares to configuration management tools like Chef and - Puppet. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 vs. Chef, Puppet, etc. - -Configuration management tools install and manage software on a machine -that already exists. Terraform is not a configuration management tool, -and it allows existing tooling to focus on their strengths: bootstrapping -and initializing resources. - -Terraform focuses on the higher-level abstraction of the datacenter and -associated services, while allowing you to use configuration management -tools on individual systems. It also aims to bring the same benefits of -codification of your system configuration to infrastructure management. - -If you are using traditional configuration management within your compute -instances, you can use Terraform to configure bootstrapping software like -cloud-init to activate your configuration management software on first -system boot. diff --git a/website/docs/intro/vs/cloudformation.mdx b/website/docs/intro/vs/cloudformation.mdx deleted file mode 100644 index 6eb8094ab6..0000000000 --- a/website/docs/intro/vs/cloudformation.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -page_title: Terraform versus CloudFormation, Heat, and other infrastructure as code tools -description: >- - Learn how Terraform manages various cloud providers and services, such as AWS, OpenStack, Cloudflare, and DNSimple, versus CloudFormation, Heat, and other tools. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 versus CloudFormation, Heat, and other infrastructure as code tools - -CloudFormation, Heat, and other infrastructure as code tools allow you to codify the details of infrastructure -into a configuration file. The configuration files allow -the infrastructure to be elastically created, modified and destroyed. Terraform -is inspired by the problems they solve. - -Terraform similarly uses configuration files to detail the infrastructure -setup, but it goes further by being both cloud-agnostic and enabling -multiple providers and services to be combined and composed. For example, -Terraform can be used to orchestrate an AWS and OpenStack cluster simultaneously, -while enabling 3rd-party providers like Cloudflare and DNSimple to be integrated -to provide CDN and DNS services. This enables Terraform to represent and -manage the entire infrastructure with its supporting services, instead of -only the subset that exists within a single provider. It provides a single -unified syntax, instead of requiring operators to use independent and -non-interoperable tools for each platform and service. - -Terraform also separates the planning phase from the execution phase, -by using the concept of an execution plan. By running `terraform plan`, -the current state is refreshed and the configuration is consulted to -generate an action plan. The plan includes all actions to be taken: -which resources will be created, destroyed or modified. It can be -inspected by operators to ensure it is exactly what is expected. Using -`terraform graph`, the plan can be visualized to show dependent ordering. -Once the plan is captured, the execution phase can be limited to only -the actions in the plan. Other tools combine the planning and execution -phases, meaning operators are forced to mentally reason about the effects -of a change, which quickly becomes intractable in large infrastructures. -Terraform lets operators apply changes with confidence, as they know exactly -what will happen beforehand. diff --git a/website/docs/intro/vs/custom.mdx b/website/docs/intro/vs/custom.mdx deleted file mode 100644 index 64a2f61803..0000000000 --- a/website/docs/intro/vs/custom.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -page_title: Terraform versus Custom Solutions -description: >- - Learn how the Terraform syntax enables to Terraform binary to overcome challenges of custom infrastructure as code solutions. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 versus Custom Solutions - -Most organizations start by manually managing infrastructure through -simple scripts or web-based interfaces. As the infrastructure grows, -any manual approach to management becomes both error-prone and tedious, -and many organizations begin to home-roll tooling to help -automate the mechanical processes involved. - -These tools require time and resources to build and maintain. -As tools of necessity, they represent the minimum viable -features needed by an organization, being built to handle only -the immediate needs. As a result, they are often hard -to extend and difficult to maintain. Because the tooling must be -updated in lockstep with any new features or infrastructure, -it becomes the limiting factor for how quickly the infrastructure -can evolve. - -Terraform is designed to tackle these challenges. It provides a simple, -unified syntax, allowing almost any resource to be managed without -learning new tooling. By capturing all the resources required, the -dependencies between them can be resolved automatically so that operators -do not need to remember and reason about them. Removing the burden -of building the tool allows operators to focus on their infrastructure -and not the tooling. - -Furthermore, Terraform is a free, source-available tool. In addition to -HashiCorp, the community around Terraform helps to extend its features, -fix bugs and document new use cases. Terraform helps solve a problem -that exists in every organization and provides a standard that can -be adopted to avoid reinventing the wheel between and within organizations. -Its source code license ensures it will be around in the long term. diff --git a/website/docs/intro/vs/index.mdx b/website/docs/intro/vs/index.mdx deleted file mode 100644 index 620f39691c..0000000000 --- a/website/docs/intro/vs/index.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -page_title: Terraform versus alternatives overview -description: Terraform lets you define infrastructure as code and automate infrastructure lifecycle management. Learn how Terraform compares to other cloud infrastructure tools. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 versus Alternatives Overview - -Terraform provides a flexible abstraction of resources and providers. This model -allows for representing everything from physical hardware, virtual machines, and -containers, to email and DNS providers. Because of this flexibility, Terraform -can be used to solve many different problems. This means there are a number of -existing tools that overlap with the capabilities of Terraform. We compare Terraform -to a number of these tools, but it should be noted that Terraform is not mutually -exclusive with other systems. It can be used to manage a single application, or the -entire datacenter. - -Learn how Terraform compares to: - -- [Chef, Puppet, etc.](/terraform/intro/vs/chef-puppet) -- [CloudFormation, Heat, etc.](/terraform/intro/vs/cloudformation) -- [Boto, Fog, etc.](/terraform/intro/vs/boto) -- [Custom Solutions](/terraform/intro/vs/custom) diff --git a/website/docs/language/attr-as-blocks.mdx b/website/docs/language/attr-as-blocks.mdx deleted file mode 100644 index a2e2983f45..0000000000 --- a/website/docs/language/attr-as-blocks.mdx +++ /dev/null @@ -1,182 +0,0 @@ ---- -page_title: Attributes as Blocks - Configuration Language -description: >- - For historical reasons, certain arguments within resource blocks can use - either - - block or attribute syntax. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Attributes as Blocks - --> **Note:** This page is an appendix to the Terraform documentation. Most users do not need to know the full details of this behavior. - -## Summary - -Many resource types use repeatable nested blocks to manage collections of -sub-objects related to the primary resource. - -Rarely, some resource types _also_ support an argument with the same name as a -nested block type, and will purge any sub-objects of that type if that argument -is set to an empty list (` = []`). - -Most users do not need to know any further details of this "nested block or -empty list" behavior. However, read further if you need to: - -- Use Terraform's [JSON syntax](/terraform/language/syntax/json) with this - type of resource. -- Create a reusable module that wraps this type of resource. - -## Details - -In Terraform v0.12 and later, the language makes a distinction between -[argument syntax and nested block syntax](/terraform/language/syntax/configuration#arguments-and-blocks) -within blocks: - -- Argument syntax sets a named argument for the containing object. If the - attribute has a default value then an explicitly-specified value entirely - overrides that default. - -- Nested block syntax represents a related child object of the container that - has its own set of arguments. Where multiple such objects are possible, multiple - blocks of the same type can be present. If the nested attributes themselves - have default values, they are honored for each nested block separately, - merging in with any explicitly-defined arguments. - -The distinction between these is particularly important for -[JSON syntax](/terraform/language/syntax/json) -because the same primitive JSON constructs (lists and objects) will be -interpreted differently depending on whether a particular name is an argument -or a nested block type. - -However, in some cases existing provider features were relying on the -conflation of these two concepts in the language of Terraform v0.11 and earlier, -using nested block syntax in most cases but using argument syntax to represent -explicitly the idea of removing all existing objects of that type, since the -absence of any blocks was interpreted as "ignore any existing objects". - -The information on this page only applies to certain special arguments that -were relying on this usage pattern prior to Terraform v0.12. The documentation -for each of those features links to this page for details of the special usage -patterns that apply. In all other cases, use either argument or nested block -syntax as directed by the examples in the documentation for a particular -resource type. - -## Defining a Fixed Object Collection Value - -When working with resource type arguments that behave in this way, it is valid -and we recommend to use the nested block syntax whenever defining a fixed -collection of objects: - -```hcl -example { - foo = "bar" -} -example { - foo = "baz" -} -``` - -The above implicitly specifies a two-element list of objects assigned to the -`example` argument, treating it as if it were a nested block type. - -If you need to explicitly call for zero `example` objects, you must use the -argument syntax with an empty list: - -```hcl -example = [] -``` - -These two forms cannot be mixed; there cannot be both explicitly zero `example` -objects and explicit single `example` blocks declared at the same time. - -For true nested blocks where this special behavior does not apply, assigning -`[]` using argument syntax is not valid. The normal way to specify zero objects -of a type is to write no nested blocks at all. - -## Arbitrary Expressions with Argument Syntax - -Although we recommend using block syntax for simple cases for readability, the -names that work in this mode _are_ defined as arguments, and so it is possible -to use argument syntax to assign arbitrary dynamic expressions to them, as -long as the expression has the expected result type: - -```hcl -example = [ - for name in var.names: { - foo = name - } -] -``` - -```hcl -# Not recommended, but valid: a constant list-of-objects expression -example = [ - { - foo = "bar" - }, - { - foo = "baz" - }, -] -``` - -Because of the rule that argument declarations like this fully override any -default value, when creating a list-of-objects expression directly the usual -handling of optional arguments does not apply, so all of the arguments must be -assigned a value, even if it's an explicit `null`: - -```hcl -example = [ - { - # Cannot omit foo in this case, even though it would be optional in the - # nested block syntax. - foo = null - }, -] -``` - -If you are writing a reusable module that allows callers to pass in a list of -objects to assign to such an argument, you may wish to use the `merge` function -to populate any attributes the user didn't explicitly set, in order to give -the module user the effect of optional arguments: - -```hcl -example = [ - for ex in var.examples: merge({ - foo = null # (or any other suitable default value) - }, ex) -] -``` - -For the arguments that use the attributes-as-blocks usage mode, the above is -a better pattern than using -[`dynamic` blocks](/terraform/language/expressions/dynamic-blocks) -because the case where the -caller provides an empty list will result in explicitly assigning an empty -list value, rather than assigning no value at all and thus retaining and -ignoring any existing objects. `dynamic` blocks are required for -dynamically-generating _normal_ nested blocks, though. - -## In JSON syntax - -Arguments that use this special mode are specified in JSON syntax always using -the [JSON expression mapping](/terraform/language/syntax/json#expression-mapping) -to produce a list of objects. - -The interpretation of these values in JSON syntax is, therefore, equivalent -to that described under _Arbitrary Expressions with Argument Syntax_ above, -but expressed in JSON syntax instead. - -Due to the ambiguity of the JSON syntax, there is no way to distinguish based -on the input alone between argument and nested block usage, so the JSON syntax -cannot support the nested block processing mode for these arguments. This is, -unfortunately, one necessary concession on the equivalence between native syntax -and JSON syntax made pragmatically for compatibility with existing provider -design patterns. Providers may phase out such patterns in future major releases. diff --git a/website/docs/language/backend/azurerm.mdx b/website/docs/language/backend/azurerm.mdx deleted file mode 100644 index 0d1bafc832..0000000000 --- a/website/docs/language/backend/azurerm.mdx +++ /dev/null @@ -1,587 +0,0 @@ ---- -page_title: 'Backend Type: azurerm' -description: Terraform can store state remotely in Azure Blob Storage. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# azurerm - -Stores the state as a Blob with the given Key within the Blob Container within [the Blob Storage Account](https://docs.microsoft.com/en-us/azure/storage/common/storage-introduction). - -This backend supports state locking and consistency checking with Azure Blob Storage native capabilities. - -## Authentication - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The `azurerm` backend needs to authenticate to the storage account data plane in order to manipulate the state file blob in the storage account container. In order to do that, it needs to authenticate and to know the data plane URI for the storage account. - -The `azurerm` backend supports 5 methods to authenticate to the storage account data plane: - -- [Azure Active Directory](#azure-active-directory) **(Recommended)** -- [SAS Token](#sas-token) *(Not recommended for new workloads)* -- [Access Key](#access-key) *(Not recommended for new workloads)* -- [Access Key Lookup](#access-key-lookup) *(Not recommended for new workloads)* - -### Azure Active Directory and Access Key Lookup Authentication Types - -There are 5 types of Azure Active Directory authentication supported, which apply to the Azure Active Directory and Access Key Lookup methods. - -- OpenID Connect / Workload identity federation **(Recommended)** - - User Assigned Managed Identity with Federated Credentials **(Recommended)** - - Service Princial / App Registration with Federated Credentials -- User or System Assigned Managed Identity - - User Assigned Managed Identity attached to Azure compute instance (agent / runner) - - System Assigned Managed Identity attached to Azure compute instance (agent / runner) -- Service Principal / App Registration with Client Secret -- Service Principal / App REgistration with Client Certificate -- User Account with Azure CLI only (for local development cycle) - -These types can be supplied via inputs or via a pre-authenticated Azure CLI. We cover them in more depth in the following sections. - -### Data Plane URI - -In most cases, you can infer the data plane URI from the `storage_account_name` and `container_name`. Refer to the [storage account overview documentation](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-overview#standard-endpoints) for more information on the standard endpoints. - -If you are using the ['Azure DNS zone endpoints' feature](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-overview#azure-dns-zone-endpoints-preview), the backend will need to lookup the data plane URI from the management plane. This requires that you set the `lookup_blob_endpoint` configuration option to `true` and the `Reader` role assignment on the storage account. - -## Azure Active Directory - -This method requires a valid Azure Active Directory principal and a predictable storage account data plane URI. - -### Required Configuration Options - -The following configuration options are always required for this method: - -- `use_azuread_auth` - Set to `true` to use Azure Active Directory authentication to the storage account data plane. This can also be set via the `ARM_USE_AZUREAD` environment variable. -- `tenant_id` - The tenant ID of the Azure Active Directory principal is required to authenticate to the storage account data plane. If using Azure CLI, this can be inferred from the CLI session. This can also be set via the `ARM_TENANT_ID` environment variable. -- `storage_account_name` - The name of the storage account to write the state file blob to. -- `container_name` - The name of the storage account container to write the state file blob to. -- `key` - The name of the blob within the storage account container to write the state file to. - -### Optional Inputs - -These optional configuration options apply when [looking up the data plane URI](#data-plane-uri) from the management plane. They are not required when the data plane URI can be inferred from the `storage_account_name` and `container_name`. - -- `lookup_blob_endpoint` - Set to `true` to lookup the storage account data plane URI from the management plane. This is required if you are using the 'Azure DNS zone endpoints' feature. Defaults to `false`. This value can also be sourced from the `ARM_USE_DNS_ZONE_ENDPOINT` environment variable. -- `subscription_id` - The subscription ID of the storage account is required to query the management plane. This is only required if `lookup_blob_endpoint` is set to `true`. If using Azure CLI, this can be inferred from the CLI session. This can also be set via the `ARM_SUBSCRIPTION_ID` environment variable. -- `resource_group_name` - The resource group name of the storage account is required to query the management plane. This is only required if `lookup_blob_endpoint` is set to `true`. - -### Storage Account Required Role Assignments - -The recommended data plane role assignments required for this method are either one of: - -- `Storage Blob Data Owner` on the storage account container (Recommended) -- `Storage Blob Data Contributor` on the storage account - -The recommended management plane role assignments required for this method are: - -- `Reader` on the storage account *(Only required if `lookup_blob_endpoint` is set to `true`)* - -### Azure Active Directory with OpenID Connect / Workload identity federation - -#### Required Configuration Options - -The following additional configuration options are always required for this sub-type: - -- `use_oidc` - Set to `true` to use OpenID Connect / Workload identity federation to authenticate to the storage account data plane. This can also be set via the `ARM_USE_OIDC` environment variable. -- `client_id` - The client ID of the Azure Active Directory Service Principal / App Registration or User Assigned Managed Identity is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_ID` environment variable. - -#### Example Configuration for GitHub - -With GitHub, the ID Token environment variables are automatically found, so no further settings are required. - -```hcl -terraform { - backend "azurerm" { - use_oidc = true # Can also be set via `ARM_USE_OIDC` environment variable. - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -#### Example Configuration for Azure DevOps - -With Azure DevOps, the ID Token endpoint environment variables are automatically found, but you need to supply the service connection ID in `oidc_azure_service_connection_id`. If you are using the `AzureCLI` or `AzurePowerShell` tasks, the service connection ID is automatically set to the `AZURESUBSCRIPTION_SERVICE_CONNECTION_ID` environment variable. - -```hcl -terraform { - backend "azurerm" { - use_oidc = true # Can also be set via `ARM_USE_OIDC` environment variable. - oidc_azure_service_connection_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_OIDC_AZURE_SERVICE_CONNECTION_ID` environment variable. - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Azure Active Directory with Compute Attached Managed Identity - -#### Required Configuration Options - -The following additional configuration options are always required for this sub-type: - -- `use_msi` - Set to `true` to use the managed identity to authenticate to the storage account data plane. This can also be set via the `ARM_USE_MSI` environment variable. - -#### Optional Configuration Options - -The following additional configuration options are optional for this sub-type: - -- `client_id` - The client ID of the User Assigned Managed Identity is required to authenticate to the storage account data plane. This is not required for System Assigned Managed Identity. This can also be set via the `ARM_CLIENT_ID` environment variable. - -#### Example Configuration - -```hcl -terraform { - backend "azurerm" { - use_msi = true # Can also be set via `ARM_USE_MSI` environment variable. - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. Not required for System Assigned Managed Identity. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Azure Active Directory with Azure CLI - -You must have a pre-authenticated Azure CLI session using any supported method. - -#### Required Configuration Options - -The following additional configuration options are always required for this sub-type: - -- `use_cli` - Set to `true` to use the Azure CLI session authenticate to the storage account data plane. This can also be set via the `ARM_USE_CLI` environment variable. - -#### Example Configuration - -```hcl -terraform { - backend "azurerm" { - use_cli = true # Can also be set via `ARM_USE_CLI` environment variable. - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. Azure CLI will fallback to use the connected tenant ID if not supplied. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Azure Active Directory with Client Secret - -Terraform retains this method for backwards compatibility only, do not use it for any new workloads. - -~> **Warning!** This method requires you to manage and rotate a secret. Use OpenID Connect / Workload identity federation as a more secure approach. - -#### Required Inputs - -The following additional configuration options are always required for this sub-type: - -- `client_id` - The client ID of the Azure Active Directory Service Principal / App Registration is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_ID` environment variable. -- `client_secret` - The client secret of the Azure Active Directory Service Principal / App Registration is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_SECRET` environment variable. - -#### Example Configuration - -```hcl -terraform { - backend "azurerm" { - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - client_secret = "************************************" # Can also be set via `ARM_CLIENT_SECRET` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Azure Active Directory with Client Certificate - -Terraform retains this method for backwards compatibility only, do not use it for any new workloads. - -~> **Warning!** This method requires you to manage and rotate a secret. Use OpenID Connect / Workload identity federation as a more secure approach. - -#### Required Inputs - -The following additional configuration options are always required for this sub-type: - -- `client_id` - The client ID of the Azure Active Directory Service Principal / App Registration is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_ID` environment variable. -- `client_certificate_path` - The path to the client certificate bundle is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_CERTIFICATE_PATH` environment variable. -- `client_certificate_password` - The password for the client certificate bundle is required to authenticate to the storage account data plane. This can also be set via the `ARM_CLIENT_CERTIFICATE_PASSWORD` environment variable. - -#### Example Configuration - -```hcl -terraform { - backend "azurerm" { - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - client_certificate_path = "/path/to/bundle.pfx" # Can also be set via `ARM_CLIENT_CERTIFICATE_PATH` environment variable. - client_certificate_password = "************************************" # Can also be set via `ARM_CLIENT_CERTIFICATE_PASSWORD` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -## Access Key - -This method requires you find the Access Key for the storage account and supply it to the backend configuration. - -The Access Key is then used to directly authenticate to the storage account data plane. - -Terraform retains this method for backwards compatibility, we do not recommend it for new workloads. - -### Required Configuration Options - -The following configuration options are always required for this method: - -- `access_key` - The Access Key of the storage account is required to authenticate to the storage account data plane. This can also be set via the `ARM_ACCESS_KEY` environment variable. -- `storage_account_name` - The name of the storage account to write the state file blob to. -- `container_name` - The name of the storage account container to write the state file blob to. -- `key` - The name of the blob within the storage account container to write the state file to. - -### Storage Account Required Role Assignments - -There are no role assignments required on the storage account for this method as the Access Key is used to authenticate to the data plane. - -### Example Configuration - -~> **Warning!** This method requires you to manage and rotate a secret. Consider using OIDC as a more secure approach. - -```hcl -terraform { - backend "azurerm" { - access_key = "abcdefghijklmnopqrstuvwxyz0123456789..." # Can also be set via `ARM_ACCESS_KEY` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -## SAS Token - -This method requires you generate a SAS Token for the storage account container or blob and supply it to the backend configuration. - -The SAS Token is then used to directly authenticate to the storage account data plane. - -Terraform retains this method for backwards compatibility, we do not recommend it for new workloads. - -### Required Configuration Options - -The following configuration options are always required for this method: - -- `sas_token` - The SAS Token for the storage account container or blob is required to authenticate to the storage account data plane. This can also be set via the `ARM_SAS_TOKEN` environment variable. -- `storage_account_name` - The name of the storage account to write the state file blob to. -- `container_name` - The name of the storage account container to write the state file blob to. -- `key` - The name of the blob within the storage account container to write the state file to. - -### Storage Account Required Permissions - -The SAS Token requires `write` and `list` permissions on the container or blob. - -### Example Configuration - -~> **Warning!** This method requires you to manage and rotate a secret. Consider using OIDC as a more secure approach. - -```hcl -terraform { - backend "azurerm" { - sas_token = "abcdefghijklmnopqrstuvwxyz0123456789..." # Can also be set via `ARM_SAS_TOKEN` environment variable. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -## Access Key Lookup - -This method requires a valid Azure Active Directory principal and is a fallback for when Azure Active Directory authentication cannot be used on the storage account data plane. - -This method queries the management plane to get the storage account Access Key and then uses that Access Key to authenticate to the storage account data plane. It requires elevated permissions on the storage account. - -Terraform retains this method for backwards compatibility, we do not recommend it for new workloads. - -### Required Configuration Options - -The following configuration options are always required for this method: - -- `tenant_id` - The tenant ID of the Azure Active Directory principal is required to authenticate to the storage account management and data plane. If using Azure CLI, this can be inferred from the CLI session. This can also be set via the `ARM_TENANT_ID` environment variable. -- `subscription_id` - The subscription ID of the storage account is required to query the management plane. If using Azure CLI, this can be inferred from the CLI session. This can also be set via the `ARM_SUBSCRIPTION_ID` environment variable. -- `resource_group_name` - The resource group name of the storage account is required to query the management plane. -- `storage_account_name` - The name of the storage account to write the state file blob to. -- `container_name` - The name of the storage account container to write the state file blob to. -- `key` - The name of the blob within the storage account container to write the state file to. - -### Optional Configuration Options - -These optional configuration options apply when [looking up the data plane URI](#data-plane-uri) from the management plane. They are not required when the data plane URI can be inferred from the `storage_account_name` and `container_name`. - -- `lookup_blob_endpoint` - Set to `true` to lookup the storage account data plane URI from the management plane. This is required if you are using the 'Azure DNS zone endpoints' feature. Defaults to `false`. This value can also be sourced from the `ARM_USE_DNS_ZONE_ENDPOINT` environment variable. - -### Storage Account Required Role Assignments - -The recommended data plane role assignments required for this method are either one of: - -- `Storage Blob Data Owner` on the storage account container (Recommended) -- `Storage Blob Data Contributor` on the storage account - -The recommended management plane role assignments required for this method are: - -- `Reader` on the storage account -- `Storage Account Key Operator Service Role` on the storage account - -### Access Key Lookup with OpenID Connect / Workload identity federation - -OpenID Connect / Workload identity federation is the recommended method for this scenario. - -#### Required Configuration Options - -The following additional configuration options are always required for this sub-type: - -- `use_oidc` - Set to `true` to use OpenID Connect / Workload identity federation to authenticate to the storage account management and data plane. This can also be set via the `ARM_USE_OIDC` environment variable. -- `client_id` - The client ID of the Azure Active Directory Service Principal / App Registration or User Assigned Managed Identity is required to authenticate to the storage account management and data plane. This can also be set via the `ARM_CLIENT_ID` environment variable. - -#### Example Configuration for GitHub - -With GitHub, the ID Token environment variables are automatically found, so no further settings are required. - -```hcl -terraform { - backend "azurerm" { - use_oidc = true # Can also be set via `ARM_USE_OIDC` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -#### Example Configuration for Azure DevOps - -With Azure DevOps, the ID Token endpoint environment variables are automatically found, but you need to supply the service connection ID in `oidc_azure_service_connection_id`. If you are using the `AzureCLI` or `AzurePowerShell` tasks, the service connection ID is automatically set to the `AZURESUBSCRIPTION_SERVICE_CONNECTION_ID` environment variable. - -```hcl -terraform { - backend "azurerm" { - use_oidc = true # Can also be set via `ARM_USE_OIDC` environment variable. - oidc_azure_service_connection_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_OIDC_AZURE_SERVICE_CONNECTION_ID` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Access Key Lookup with Compute Attached Managed Identity - -#### Required Configuration Options - -The following additional configuration options are always required for this sub-type: - -- `use_msi` - Set to `true` to use the managed identity to authenticate to the storage account data plane. This can also be set via the `ARM_USE_MSI` environment variable. - -#### Optional Configuration Options - -The following additional configuration options are optional for this sub-type: - -- `client_id` - The client ID of the User Assigned Managed Identity is required to authenticate to the storage account data plane. This is not required for System Assigned Managed Identity. This can also be set via the `ARM_CLIENT_ID` environment variable. - -#### Example Configuration - -```hcl -terraform { - backend "azurerm" { - use_msi = true # Can also be set via `ARM_USE_MSI` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. Not required for System Assigned Managed Identity. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Access Key Lookup with Azure CLI - -You must have a pre-authenticated Azure CLI session using any supported method. - -```hcl -terraform { - backend "azurerm" { - use_cli = true # Can also be set via `ARM_USE_CLI` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. Azure CLI will fallback to use the connected tenant ID if not supplied. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. Azure CLI will fallback to use the connected subscription ID if not supplied. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Access Key Lookup with Client Secret - -Terraform retains this method for backwards compatibility only, do not use it for any new workloads. - -~> **Warning!** This method requires you to manage and rotate a secret. Use OpenID Connect / Workload identity federation as a more secure approach. - -```hcl -terraform { - backend "azurerm" { - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - client_secret = "************************************" # Can also be set via `ARM_CLIENT_SECRET` environment variable. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -### Access Key Lookup with Client Certificate - -Terraform retains this method for backwards compatibility only, do not use it for any new workloads. - -~> **Warning!** This method requires you to manage and rotate a secret. Use OpenID Connect / Workload identity federation as a more secure approach. - -```hcl -terraform { - backend "azurerm" { - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - subscription_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_SUBSCRIPTION_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - client_certificate_path = "/path/to/bundle.pfx" # Can also be set via `ARM_CLIENT_CERTIFICATE_PATH` environment variable. - client_certificate_password = "************************************" # Can also be set via `ARM_CLIENT_CERTIFICATE_PASSWORD` environment variable. - resource_group_name = "StorageAccount-ResourceGroup" # Can be passed via `-backend-config=`"resource_group_name="` in the `init` command. - storage_account_name = "abcd1234" # Can be passed via `-backend-config=`"storage_account_name="` in the `init` command. - container_name = "tfstate" # Can be passed via `-backend-config=`"container_name="` in the `init` command. - key = "prod.terraform.tfstate" # Can be passed via `-backend-config=`"key="` in the `init` command. - } -} -``` - -## terraform_remote_state Data Source - -To use the `terraform_remote_state` data source with the `azurerm` backend, you must use the exact same configuration as you would for the `backend` block in your configuration. - -For example to use [Direct Azure Active Directory authentication with OpenID Connect / Workload identity federation for GitHub](#azure-active-directory-with-openid-connect--workload-identity-federation) you would use the following configuration: - -```hcl -data "terraform_remote_state" "foo" { - backend = "azurerm" - config = { - use_oidc = true # Can also be set via `ARM_USE_OIDC` environment variable. - use_azuread_auth = true # Can also be set via `ARM_USE_AZUREAD` environment variable. - tenant_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_TENANT_ID` environment variable. - client_id = "00000000-0000-0000-0000-000000000000" # Can also be set via `ARM_CLIENT_ID` environment variable. - storage_account_name = "abcd1234" # There is not environment variable support for this input. - container_name = "tfstate" # There is not environment variable support for this input. - key = "prod.terraform.tfstate" # There is not environment variable support for this input. - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -For more information on when each of these configuration settings is required, refer to the previous sections of this page. - -The following configuration options are supported: - -* `storage_account_name` - (Required) The Name of [the Storage Account](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account). - -* `container_name` - (Required) The Name of [the Storage Container](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_container) within the Storage Account. - -* `key` - (Required) The name of the Blob used to retrieve/store Terraform's State file inside the Storage Container. - -* `environment` - (Optional) The Azure Environment which should be used. This can also be sourced from the `ARM_ENVIRONMENT` environment variable. Possible values are `public`, `china` and `usgovernment`. Defaults to `public`. - -* `metadata_host` - (Optional) The Hostname of the Azure Metadata Service (for example `management.azure.com`), used to obtain the Cloud Environment when using a Custom Azure Environment. This can also be sourced from the `ARM_METADATA_HOSTNAME` Environment Variable. - -* `lookup_blob_endpoint` - (Optional) Set to `true` to look up the Storage Account Data Plane URI from the Management Plane. Defaults to `false`. This value can also be sourced from the `ARM_USE_DNS_ZONE_ENDPOINT` environment variable. - -* `snapshot` - (Optional) Set to `true` to snapshot the Blob used to store the Terraform state file before use. Defaults to `false`. This value can also be sourced from the `ARM_SNAPSHOT` environment variable. - -* `tenant_id` - (Optional) The Tenant ID of the principal. This can also be sourced from the `ARM_TENANT_ID` environment variable. - -* `use_azuread_auth` - (Optional) Whether Azure Active Directory Authentication for storage account data plane authentication. This can also be sourced from the `ARM_USE_AZUREAD` environment variable. - -* `subscription_id` - (Optional) The Subscription ID of the storage account required for management plane authentication. This can also be sourced from the `ARM_SUBSCRIPTION_ID` environment variable. - -* `resource_group_name` - (Optional) The Name of the Resource Group in which the Storage Account exists required for management plane authentication. - -* `access_key` - (Optional) The Access Key used to authenticate to the storage account data plane with the [Direct Access Key](#direct-access-key) authenticaton method. This can also be sourced from the `ARM_ACCESS_KEY` environment variable. - -* `sas_token` - (Optional) The SAS Token used to authenticate to the storage account data plane with the [Direct SAS Token](#direct-sas-token) authentication method. This can also be sourced from the `ARM_SAS_TOKEN` environment variable. - -* `use_cli` - (Optional) Set to `true` to use the Azure CLI session for authentication to the storage account management and data plane. This value can also be sourced from the `ARM_USE_CLI` environment variable. - -* `use_oidc` - (Optional) Set to `true` to use OpenID Connect / Workload identity federation authentication for authentication to the storage account management and data plane. This can also be sourced from the `ARM_USE_OIDC` environment variable. - -* `client_id` - (Optional) The Client ID of the Azure Active Directory Principal required for some authentication sub-types. This can also be sourced from the `ARM_CLIENT_ID` environment variable. - -* `ado_pipeline_service_connection_id` - (Optional) The Azure DevOps Pipeline Service Connection ID required for Open ID Connect / Workload identity federation authentication with Azure DevOps. This can also be sourced from the `ARM_ADO_PIPELINE_SERVICE_CONNECTION_ID` or `ARM_OIDC_AZURE_SERVICE_CONNECTION_ID` environment variables. The provider will look for values in this order and use the first it finds configured. - -* `oidc_request_url` - (Optional) The URL for the Open ID Connect provider from which to request an ID token. This is only required for advanced scenarios or third party integrations. This can also be sourced from the `ARM_OIDC_REQUEST_URL`, `ACTIONS_ID_TOKEN_REQUEST_URL` or `SYSTEM_OIDCREQUESTURI` environment variables. The provider will look for values in this order and use the first it finds configured. - -* `oidc_request_token` - (Optional) The bearer token for the request to the Open ID Connect provider. This is only required for advanced scenarios or third party integrations. This can also be sourced from the `ARM_OIDC_REQUEST_TOKEN`, `ACTIONS_ID_TOKEN_REQUEST_TOKEN` or `SYSTEM_ACCESSTOKEN` environment variables. The provider will look for values in this order and use the first it finds configured. - -* `oidc_token` - (Optional) The ID Token when authenticating using OpenID Connect. This is only required for advanced scenarios or third party integrations. This can also be sourced from the `ARM_OIDC_TOKEN` environment variable. - -* `oidc_token_file_path` - (Optional) The path to a file containing an ID token when authenticating using OpenID Connect. This is only required for advanced scenarios or third party integrations. This can also be sourced from the `ARM_OIDC_TOKEN_FILE_PATH` environment variable. - -* `use_aks_workload_identity` (Optional) Set to `true` to use Azure AKS Workload Identity for authentication. This is only required for advanced scenarios or third party integrations. This can also be sourced from the `ARM_USE_AKS_WORKLOAD_IDENTITY` environment variable. - -* `use_msi` - (Optional) Set to `true` to use a Compute Attached Managed Service Identity for authentication to the storage account management and data planes. This can also be sourced from the `ARM_USE_MSI` environment variable. - -* `msi_endpoint` - (Optional) The path to a custom Managed Service Identity endpoint which is automatically determined if not specified. This can also be sourced from the `ARM_MSI_ENDPOINT` environment variable. - -* `client_id_file_path` (Optional) The path to a file containing the Client ID which should be used. This can also be sourced from the `ARM_CLIENT_ID_FILE_PATH` Environment Variable. - -* `client_certificate_password` - (Optional) The password associated with the Client Certificate specified in `client_certificate_path`. This can also be sourced from the `ARM_CLIENT_CERTIFICATE_PASSWORD` environment variable. - -* `client_certificate_path` - (Optional) The path to the PFX file used as the Client Certificate when authenticating as a Service Principal. This can also be sourced from the `ARM_CLIENT_CERTIFICATE_PATH` environment variable. - -* `client_certificate` - (Optional) Base64 encoded PKCS#12 certificate bundle to use when authenticating as a Service Principal using a Client Certificate. This can also be sourced from the `ARM_CLIENT_CERTIFICATE` environment variable. - -* `client_id_file_path` (Optional) The path to a file containing the Client ID which should be used. This can also be sourced from the `ARM_CLIENT_ID_FILE_PATH` Environment Variable. - -* `client_secret` - (Optional) The Client Secret of the Service Principal. This can also be sourced from the `ARM_CLIENT_SECRET` environment variable. - -* `client_secret_file_path` - (Optional) The path to a file containing the Client Secret which should be used. This can also be sourced from the `ARM_CLIENT_SECRET_FILE_PATH` Environment Variable. diff --git a/website/docs/language/backend/consul.mdx b/website/docs/language/backend/consul.mdx deleted file mode 100644 index 22670b32bb..0000000000 --- a/website/docs/language/backend/consul.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -page_title: 'Backend Type: consul' -description: Terraform can store state in Consul. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# consul - -Stores the state in the [Consul](https://www.consul.io/) KV store at a given path. - -This backend supports [state locking](/terraform/language/state/locking). - -## Example Configuration - -```hcl -terraform { - backend "consul" { - address = "consul.example.com" - scheme = "https" - path = "full/path" - } -} -``` - -Note that for the access credentials we recommend using a -[partial configuration](/terraform/language/backend#partial-configuration). - -## Data Source Configuration - -```hcl -data "terraform_remote_state" "foo" { - backend = "consul" - config = { - path = "full/path" - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options / environment variables are supported: - -- `path` - (Required) Path in the Consul KV store -- `access_token` / `CONSUL_HTTP_TOKEN` - (Required) Access token -- `address` / `CONSUL_HTTP_ADDR` - (Optional) DNS name and port of your Consul endpoint specified in the - format `dnsname:port`. Defaults to the local agent HTTP listener. -- `scheme` - (Optional) Specifies what protocol to use when talking to the given - `address`, either `http` or `https`. SSL support can also be triggered - by setting then environment variable `CONSUL_HTTP_SSL` to `true`. -- `datacenter` - (Optional) The datacenter to use. Defaults to that of the agent. -- `http_auth` / `CONSUL_HTTP_AUTH` - (Optional) HTTP Basic Authentication credentials to be used when - communicating with Consul, in the format of either `user` or `user:pass`. -- `gzip` - (Optional) `true` to compress the state data using gzip, or `false` (the default) to leave it uncompressed. -- `lock` - (Optional) `false` to disable locking. This defaults to true, but will require session permissions with Consul and at least kv write permissions on `$path/.lock` to perform locking. -- `ca_file` / `CONSUL_CACERT` - (Optional) A path to a PEM-encoded certificate authority used to verify the remote agent's certificate. -- `cert_file` / `CONSUL_CLIENT_CERT` - (Optional) A path to a PEM-encoded certificate provided to the remote agent; requires use of `key_file`. -- `key_file` / `CONSUL_CLIENT_KEY` - (Optional) A path to a PEM-encoded private key, required if `cert_file` is specified. diff --git a/website/docs/language/backend/cos.mdx b/website/docs/language/backend/cos.mdx deleted file mode 100644 index e218f5a314..0000000000 --- a/website/docs/language/backend/cos.mdx +++ /dev/null @@ -1,229 +0,0 @@ ---- -page_title: 'Backend Type: cos' -description: >- - Terraform can store the state remotely, making it easier to version and work - with in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# COS - -Stores the state as an object in a configurable prefix in a given bucket on [Tencent Cloud Object Storage](https://intl.cloud.tencent.com/product/cos) (COS). - -This backend supports [state locking](/terraform/language/state/locking). Storing your state in a COS bucket requires the following permissions: - -- `CreateTag`, `DeleteTag`, and `DescribeTags` on the tag key `tencentcloud-terraform-lock` -- `Put`, `Get`, and `Delete` files for the specified bucket's prefix - -~> **Warning!** It is highly recommended that you enable [Object Versioning](https://intl.cloud.tencent.com/document/product/436/19883) -on the COS bucket to allow for state recovery in the case of accidental deletions and human error. - -## Example Configuration - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-1258798060" - prefix = "terraform/state" - } -} -``` - -This assumes we have a [COS Bucket](https://registry.terraform.io/providers/tencentcloudstack/tencentcloud/latest/docs/resources/cos_bucket) created named `bucket-for-terraform-state-1258798060`, -Terraform state will be written into the file `terraform/state/terraform.tfstate`. - -## Data Source Configuration - -To make use of the COS remote state in another configuration, use the [`terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -```hcl -data "terraform_remote_state" "foo" { - backend = "cos" - - config = { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-1258798060" - prefix = "terraform/state" - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backends#credentials-and-sensitive-data) for details. - -The following configuration options or environment variables are supported: - -- `secret_id` - (Optional) Secret id of Tencent Cloud. It supports environment variables `TENCENTCLOUD_SECRET_ID`. -- `secret_key` - (Optional) Secret key of Tencent Cloud. It supports environment variables `TENCENTCLOUD_SECRET_KEY`. -- `security_token` - (Optional) TencentCloud Security Token of temporary access credentials. It supports environment variables `TENCENTCLOUD_SECURITY_TOKEN`. -- `region` - (Optional) The region of the COS bucket. It supports environment variables `TENCENTCLOUD_REGION`. -- `bucket` - (Required) The name of the COS bucket. You shall manually create it first. -- `prefix` - (Optional) The directory for saving the state file in bucket. Default to "env:". -- `key` - (Optional) The path for saving the state file in bucket. Defaults to `terraform.tfstate`. -- `encrypt` - (Optional) Whether to enable server side encryption of the state file. If it is true, COS will use 'AES256' encryption algorithm to encrypt state file. -- `acl` - (Optional) Object ACL to be applied to the state file, allows `private` and `public-read`. Defaults to `private`. -- `accelerate` - (Optional) Whether to enable global Acceleration. Defaults to `false`. -- `endpoint` - (Optional) The Custom Endpoint for the COS backend. It supports the environment variable `TENCENTCLOUD_ENDPOINT`. -- `domain` - (Optional) The root domain of the API request. Defaults to `tencentcloudapi.com`. It supports the environment variable `TENCENTCLOUD_DOMAIN`. - -### Assume Role -If provided with an assume role, Terraform will attempt to assume this role using the supplied credentials. -Assume role can be provided by adding an `assume_role` block in the cos backend block. - -- `assume_role` - (Optional) The `assume_role` block. If provided, terraform will attempt to assume this role using the supplied credentials. - -The details of `assume_role` block as following: -- `role_arn` - (Required) The ARN of the role to assume. It can be sourced from the `TENCENTCLOUD_ASSUME_ROLE_ARN`. -- `session_name` - (Required) The session name to use when making the AssumeRole call. It can be sourced from the `TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME`. -- `session_duration` - (Required) The duration of the session when making the AssumeRole call. Its value ranges from 0 to 43200(seconds), and default is 7200 seconds. It can be sourced from the `TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION`. -- `policy` - (Optional) A more restrictive policy when making the AssumeRole call. Its content must not contains `principal` elements. Notice: more syntax references, please refer to: [policies syntax logic](https://intl.cloud.tencent.com/document/product/598/10603). - -Usage: - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-{appid}" - prefix = "terraform/state" - assume_role { - role_arn = "qcs::cam::uin/xxx:roleName/yyy" - session_name = "my-session-name" - session_duration = 7200 - } - } -} -``` - -In addition, these `assume_role` configurations can also be provided by environment variables. - -Usage: - -```shell -$ export TENCENTCLOUD_SECRET_ID="my-secret-id" -$ export TENCENTCLOUD_SECRET_KEY="my-secret-key" -$ export TENCENTCLOUD_REGION="ap-guangzhou" -$ export TENCENTCLOUD_ASSUME_ROLE_ARN="qcs::cam::uin/xxx:roleName/yyy" -$ export TENCENTCLOUD_ASSUME_ROLE_SESSION_NAME="my-session-name" -$ export TENCENTCLOUD_ASSUME_ROLE_SESSION_DURATION=7200 -$ terraform plan -``` - -### Shared credentials -You can use [Tencent Cloud credentials](https://www.tencentcloud.com/document/product/1013/33464) to specify your credentials. The default location is `$HOME/.tccli` on Linux and macOS, And `"%USERPROFILE%\.tccli"` on Windows. You can optionally specify a different location in the Terraform configuration by providing the `shared_credentials_dir` argument or using the `TENCENTCLOUD_SHARED_CREDENTIALS_DIR` environment variable. This method also supports a `profile` configuration and matching `TENCENTCLOUD_PROFILE` environment variable: - -- `shared_credentials_dir` - (Optional) The directory of the shared credentials. It can also be sourced from the `TENCENTCLOUD_SHARED_CREDENTIALS_DIR` environment variable. If not set this defaults to ~/.tccli. -- `profile` - (Optional) The profile name as set in the shared credentials. It can also be sourced from the `TENCENTCLOUD_PROFILE` environment variable. If not set, the default profile created with `tccli configure` will be used. - -Usage: - -On Linux/MacOS - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-{appid}" - prefix = "terraform/state" - shared_credentials_dir = "/Users/tf_user/.tccli" - profile = "default" - } -} -``` - -On Windows - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-{appid}" - prefix = "terraform/state" - shared_credentials_dir = "C:\\Users\\tf_user\\.tccli" - profile = "default" - } -} -``` - -In addition, these `shared_credentials_dir`, `profile` configurations can also be provided by environment variables. - -Usage: - -```shell -$ export PROVIDER_SHARED_CREDENTIALS_DIR="/Users/tf_user/.tccli" -$ export PROVIDER_PROFILE="default" -$ terraform plan -``` - -### Cam role name -If provided with a Cam role name, Terraform will just access the metadata URL: `http://metadata.tencentyun.com/latest/meta-data/cam/security-credentials/` to obtain the STS credential. The CVM Instance Role also can be set using the `TENCENTCLOUD_CAM_ROLE_NAME` environment variables. - -- `cam_role_name` - (Optional) The name of the CVM instance CAM role. It can be sourced from the `TENCENTCLOUD_CAM_ROLE_NAME` environment variable. - -Usage: - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-{appid}" - prefix = "terraform/state" - cam_role_name = "my-cam-role-name" - } -} -``` - -It can also be authenticated together with method Assume role. Authentication process: Perform CAM authentication first, then proceed with Assume role authentication. - -Usage: - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-{appid}" - prefix = "terraform/state" - cam_role_name = "my-cam-role-name" - assume_role { - role_arn = "qcs::cam::uin/xxx:roleName/yyy" - session_name = "my-session-name" - session_duration = 7200 - external_id = "my-external-id" - } - } -} -``` - -In addition, these `cam_role_name` configurations can also be provided by environment variables. - -Usage: - -```shell -$ export PROVIDER_CAM_ROLE_NAME="my-cam-role-name" -$ terraform plan -``` - -### Endpoint -If provided with an endpoint URL, Terraform will attempt to access the COS backend by the `endpoint` configuration or the environment variable `TENCENTCLOUD_ENDPOINT`. - -A typical endpoint looks like this: `http://cos-internal.{Region}.tencentcos.cn`. Both HTTP and HTTPS are accepted. - -Usage: - -```hcl -terraform { - backend "cos" { - region = "ap-guangzhou" - bucket = "bucket-for-terraform-state-1258798060" - prefix = "terraform/state" - endpoint = "http://cos-internal.ap-guangzhou.tencentcos.cn" - } -} -``` \ No newline at end of file diff --git a/website/docs/language/backend/gcs.mdx b/website/docs/language/backend/gcs.mdx deleted file mode 100644 index ecde4dcd76..0000000000 --- a/website/docs/language/backend/gcs.mdx +++ /dev/null @@ -1,142 +0,0 @@ ---- -page_title: 'Backend Type: gcs' -description: >- - Terraform can store the state remotely, making it easier to version and work - with in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# gcs - -Stores the state as an object in a configurable prefix in a pre-existing bucket on [Google Cloud Storage](https://cloud.google.com/storage/) (GCS). -The bucket must exist prior to configuring the backend. - -This backend supports [state locking](/terraform/language/state/locking). - -~> **Warning!** It is highly recommended that you enable -[Object Versioning](https://cloud.google.com/storage/docs/object-versioning) -on the GCS bucket to allow for state recovery in the case of accidental deletions and human error. - -## Example Configuration - -```hcl -terraform { - backend "gcs" { - bucket = "tf-state-prod" - prefix = "terraform/state" - } -} -``` - -## Data Source Configuration - -```hcl -data "terraform_remote_state" "foo" { - backend = "gcs" - config = { - bucket = "terraform-state" - prefix = "prod" - } -} - -# Terraform >= 0.12 -resource "local_file" "foo" { - content = data.terraform_remote_state.foo.outputs.greeting - filename = "${path.module}/outputs.txt" -} - -# Terraform <= 0.11 -resource "local_file" "foo" { - content = "${data.terraform_remote_state.foo.greeting}" - filename = "${path.module}/outputs.txt" -} -``` - -## Authentication - -IAM Changes to buckets are [eventually consistent](https://cloud.google.com/storage/docs/consistency#eventually_consistent_operations) and may take upto a few minutes to take effect. Terraform will return 403 errors till it is eventually consistent. - -### Running Terraform on your workstation. - -If you are using terraform on your workstation, you will need to install the Google Cloud SDK and authenticate using [User Application Default -Credentials](https://cloud.google.com/sdk/gcloud/reference/auth/application-default). - -User ADCs do [expire](https://developers.google.com/identity/protocols/oauth2#expiration) and you can refresh them by running `gcloud auth application-default login`. - -### Running Terraform on Google Cloud - -If you are running terraform on Google Cloud, you can configure that instance or cluster to use a [Google Service -Account](https://cloud.google.com/compute/docs/authentication). This will allow Terraform to authenticate to Google Cloud without having to bake in a separate -credential/authentication file. Make sure that the scope of the VM/Cluster is set to cloud-platform. - -### Running Terraform outside of Google Cloud - -If you are running terraform outside of Google Cloud, generate a service account key and set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to -the path of the service account key. Terraform will use that key for authentication. - -### Impersonating Service Accounts - -Terraform can impersonate a Google Service Account as described [here](https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials). A valid credential must be provided as mentioned in the earlier section and that identity must have the `roles/iam.serviceAccountTokenCreator` role on the service account you are impersonating. - -## Encryption - -!> **Warning:** Take care of your encryption keys because state data encrypted with a lost or deleted key is not recoverable. If you use customer-supplied encryption keys, you must securely manage your keys and ensure you do not lose them. You must not delete customer-managed encryption keys in Cloud KMS used to encrypt state. However, if you accidentally delete a key, there is a time window where [you can recover it](https://cloud.google.com/kms/docs/destroy-restore#restore). - -### Customer-supplied encryption keys - -To get started, follow this guide: [Use customer-supplied encryption keys](https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys) - -If you want to remove customer-supplied keys from your backend configuration or change to a different customer-supplied key, Terraform cannot perform a state migration automatically and manual intervention is necessary instead. This intervention is necessary because Google does not store customer-supplied encryption keys, any requests sent to the Cloud Storage API must supply them instead (see [Customer-supplied Encryption Keys](https://cloud.google.com/storage/docs/encryption/customer-supplied-keys)). At the time of state migration, the backend configuration loses the old key's details and Terraform cannot use the key during the migration process. - -~> **Important:** To migrate your state away from using customer-supplied encryption keys or change the key used by your backend, you need to perform a [rewrite (gsutil CLI)](https://cloud.google.com/storage/docs/gsutil/commands/rewrite) or [cp (gcloud CLI)](https://cloud.google.com/sdk/gcloud/reference/storage/cp#--decryption-keys) operation to remove use of the old customer-supplied encryption key on your state file. Once you remove the encryption, you can successfully run `terraform init -migrate-state` with your new backend configuration. - -### Customer-managed encryption keys (Cloud KMS) - -To get started, follow this guide: [Use customer-managed encryption keys](https://cloud.google.com/storage/docs/encryption/using-customer-managed-keys) - -If you want to remove customer-managed keys from your backend configuration or change to a different customer-managed key, Terraform _can_ manage a state migration without manual intervention. This ability is because GCP stores customer-managed encryption keys and are accessible during the state migration process. However, these changes do not fully come into effect until the first write operation occurs on the state file after state migration occurs. In the first write operation after state migration, the file decrypts with the old key and then writes with the new encryption method. This method is equivalent to the [rewrite](https://cloud.google.com/storage/docs/gsutil/commands/rewrite) operation described in the customer-supplied encryption keys section. Because of the importance of the first write to state after state migration, you should not delete old KMS keys until any state file(s) encrypted with that key update. - -Customer-managed keys do not need to be sent in requests to read files from GCS buckets because decryption occurs automatically within GCS. This process means that if you use the `terraform_remote_state` [data source](/terraform/language/state/remote-state-data) to access KMS-encrypted state, you do not need to specify the KMS key in the data source's `config` object. - -~> **Important:** To use customer-managed encryption keys, you need to create a key and give your project's GCS service agent permission to use it with the Cloud KMS CryptoKey Encrypter/Decrypter predefined role. - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform includes these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options are supported: - -- `bucket` - (Required) The name of the GCS bucket. This name must be - globally unique. For more information, see [Bucket Naming - Guidelines](https://cloud.google.com/storage/docs/bucketnaming.html#requirements). -- `credentials` / `GOOGLE_BACKEND_CREDENTIALS` / `GOOGLE_CREDENTIALS` - - (Optional) Local path to Google Cloud Platform account credentials in JSON - format. If unset, the path uses [Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). The provided credentials must have the Storage Object Admin role on the bucket. - **Warning**: if using the Google Cloud Platform provider as well, it will - also pick up the `GOOGLE_CREDENTIALS` environment variable. -- `impersonate_service_account` / `GOOGLE_BACKEND_IMPERSONATE_SERVICE_ACCOUNT` / `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` - (Optional) The service account to impersonate for accessing the State Bucket. - You must have `roles/iam.serviceAccountTokenCreator` role on that account for the impersonation to succeed. - If you are using a delegation chain, you can specify that using the `impersonate_service_account_delegates` field. -- `impersonate_service_account_delegates` - (Optional) The delegation chain for an impersonating a service account as described [here](https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-delegated). -- `access_token` - (Optional) A temporary \[OAuth 2.0 access token] obtained - from the Google Authorization server, i.e. the `Authorization: Bearer` token - used to authenticate HTTP requests to GCP APIs. This is an alternative to - `credentials`. If both are specified, `access_token` will be used over the - `credentials` field. -- `prefix` - (Optional) GCS prefix inside the bucket. Named states for - workspaces are stored in an object called `/.tfstate`. -- `encryption_key` / `GOOGLE_ENCRYPTION_KEY` - (Optional) A 32 byte base64 - encoded 'customer-supplied encryption key' used when reading and writing state files in the bucket. For - more information see [Customer-supplied Encryption - Keys](https://cloud.google.com/storage/docs/encryption/customer-supplied-keys). -- `kms_encryption_key` / `GOOGLE_KMS_ENCRYPTION_KEY` - (Optional) A Cloud KMS key ('customer-managed encryption key') - used when reading and writing state files in the bucket. - Format should be `projects/{{project}}/locations/{{location}}/keyRings/{{keyRing}}/cryptoKeys/{{name}}`. - For more information, including IAM requirements, see [Customer-managed Encryption - Keys](https://cloud.google.com/storage/docs/encryption/customer-managed-keys). -- `storage_custom_endpoint` / `GOOGLE_BACKEND_STORAGE_CUSTOM_ENDPOINT` / `GOOGLE_STORAGE_CUSTOM_ENDPOINT` - (Optional) A URL containing three parts: the protocol, the DNS name pointing to a Private Service Connect endpoint, and the path for the Cloud Storage API (`/storage/v1/b`, [see here](https://cloud.google.com/storage/docs/json_api/v1/buckets/get#http-request)). You can either use [a DNS name automatically made by the Service Directory](https://cloud.google.com/vpc/docs/configure-private-service-connect-apis#configure-p-dns) or a [custom DNS name](https://cloud.google.com/vpc/docs/configure-private-service-connect-apis#configure-dns-default) made by you. For example, if you create an endpoint called `xyz` and want to use the automatically-created DNS name, you should set the field value as `https://storage-xyz.p.googleapis.com/storage/v1/b`. For help creating a Private Service Connect endpoint using Terraform, [see this guide](https://cloud.google.com/vpc/docs/configure-private-service-connect-apis#terraform_1). diff --git a/website/docs/language/backend/http.mdx b/website/docs/language/backend/http.mdx deleted file mode 100644 index ad83547f03..0000000000 --- a/website/docs/language/backend/http.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -page_title: 'Backend Type: http' -description: Terraform can store state remotely at any valid HTTP endpoint. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# http - -Stores the state using a simple [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) client. - -State will be fetched via GET, updated via POST, and purged with DELETE. The method used for updating is configurable. - -This backend optionally supports [state locking](/terraform/language/state/locking). When locking -support is enabled it will use LOCK and UNLOCK requests providing the lock info in the body. The -endpoint should return a 423: Locked or 409: Conflict with the holding lock info when it's already -taken, 200: OK for success. Any other status will be considered an error. The ID of the holding lock -info will be added as a query parameter to state updates requests. - -## Example Usage - -```hcl -terraform { - backend "http" { - address = "http://myrest.api.com/foo" - lock_address = "http://myrest.api.com/foo" - unlock_address = "http://myrest.api.com/foo" - } -} -``` - -## Data Source Configuration - -```hcl -data "terraform_remote_state" "foo" { - backend = "http" - config = { - address = "http://my.rest.api.com" - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options / environment variables are supported: - -- `address` / `TF_HTTP_ADDRESS` - (Required) The address of the REST endpoint -- `update_method` / `TF_HTTP_UPDATE_METHOD` - (Optional) HTTP method to use - when updating state. Defaults to `POST`. -- `lock_address` / `TF_HTTP_LOCK_ADDRESS` - (Optional) The address of the lock - REST endpoint. Defaults to disabled. -- `lock_method` / `TF_HTTP_LOCK_METHOD` - (Optional) The HTTP method to use - when locking. Defaults to `LOCK`. -- `unlock_address` / `TF_HTTP_UNLOCK_ADDRESS` - (Optional) The address of the - unlock REST endpoint. Defaults to disabled. -- `unlock_method` / `TF_HTTP_UNLOCK_METHOD` - (Optional) The HTTP method to use - when unlocking. Defaults to `UNLOCK`. -- `username` / `TF_HTTP_USERNAME` - (Optional) The username for HTTP basic - authentication -- `password` / `TF_HTTP_PASSWORD` - (Optional) The password for HTTP basic - authentication -- `skip_cert_verification` - (Optional) Whether to skip TLS verification. - Defaults to `false`. -- `retry_max` / `TF_HTTP_RETRY_MAX` – (Optional) The number of HTTP request - retries. Defaults to `2`. -- `retry_wait_min` / `TF_HTTP_RETRY_WAIT_MIN` – (Optional) The minimum time in - seconds to wait between HTTP request attempts. Defaults to `1`. -- `retry_wait_max` / `TF_HTTP_RETRY_WAIT_MAX` – (Optional) The maximum time in - seconds to wait between HTTP request attempts. Defaults to `30`. - -For mTLS authentication, the following three options may be set: - - - `client_certificate_pem` / `TF_HTTP_CLIENT_CERTIFICATE_PEM` - (Optional) A PEM-encoded certificate used by the server to verify the client during mutual TLS (mTLS) authentication. - - `client_private_key_pem` /`TF_HTTP_CLIENT_PRIVATE_KEY_PEM` - (Optional) A PEM-encoded private key, required if client_certificate_pem is specified. - - `client_ca_certificate_pem` / `TF_HTTP_CLIENT_CA_CERTIFICATE_PEM` - (Optional) A PEM-encoded CA certificate chain used by the client to verify server certificates during TLS authentication. diff --git a/website/docs/language/backend/index.mdx b/website/docs/language/backend/index.mdx deleted file mode 100644 index 389823125d..0000000000 --- a/website/docs/language/backend/index.mdx +++ /dev/null @@ -1,242 +0,0 @@ ---- -page_title: Backend block configuration overview -description: >- - Use the `backend` block to control where Terraform stores state. Learn about the available state backends, the backend block, initializing backends, partial backend configuration, changing backend configuration, and unconfiguring a backend. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Backend block configuration overview - -This topic provides an overview of how to configure the `backend` block in your Terraform configuration. The `backend` defines where Terraform stores its [state](/terraform/language/state) data files. - -## Overview - -Terraform uses persisted state data to keep track of the resources it manages. You can either [integrate with HCP Terraform](/terraform/language/terraform#terraform-cloud) to store state data or define a `backend` block to store state in a remote object. This lets multiple people access the state data and work together on that collection of infrastructure resources. - -## Define a `backend` block - -Do not configure a backend when connecting your configuration to workspaces in HCP Terraform or Terraform Enterprise. These systems automatically manage state in the workspaces associated with your configuration. If your configuration includes a [`cloud` block](/terraform/language/terraform#terraform-cloud), it cannot include a `backend` block. - -To configure a backend, add a nested `backend` block within the top-level -`terraform` block. The following example configures the `remote` backend. - -```hcl -terraform { - backend "remote" { - organization = "example_corp" - - workspaces { - name = "my-app-prod" - } - } -} -``` - -There are some important limitations on backend configuration: - -- A configuration can only provide one backend block. -- A backend block cannot refer to named values (like input variables, locals, or data source attributes). -- You cannot reference values declared within backend blocks elsewhere in the configuration. Refer to [References to Resource Attributes](/terraform/language/expressions/references#references-to-resource-attributes) for more details. - -### Default backend - -Terraform uses a backend called [`local`](/terraform/language/backend/local) by default. The `local` backend type stores state as a local file on disk. - -### Backend types - -Terraform ships with several built-in backend types. Some backends function as remote disks for state files, while others support locking the state during Terraform operations to prevent conflicts and inconsistencies. You cannot load additional backends as plugins. - -Specify the backend type as the `backend` block label. The following example instructs Terraform to use a remote backend: - -```hcl -backend "remote" { - organization = "example_corp" - . . . -} -``` - -The specified backend must be available in the version of Terraform you are using. - -### Backend arguments - -The arguments in the `backend` block body are specific to the backend type. They specify where and how the backend stores configuration state. Some backend types allow you to configure additional behaviors. Refer to the documentation for your backend for additional information. - -Some backends allow you to provide access credentials as part of the configuration, but we do not recommend including access credentials directly in the configuration. Instead, leave credential-related arguments unset and provide them using the credentials files or environment variables that are conventional for the target system. - -Refer to the page for each backend type for full details and that type's configuration arguments. - -### Credentials and sensitive data - -Backends store state in a remote service, which allows multiple people to access it. Accessing remote state generally requires access credentials, since state data contains extremely sensitive information. - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. This can leak sensitive credentials. - -Terraform writes the backend configuration in plain text in two separate files. -- The `.terraform/terraform.tfstate` file contains the backend configuration for the current working directory. -- All plan files capture the information in `.terraform/terraform.tfstate` at the time the plan was created. This helps ensure Terraform is applying the plan to correct set of infrastructure. - -When applying a plan that you previously saved to a file, Terraform uses the backend configuration stored in that file instead of the current backend settings. If that configuration contains time-limited credentials, they may expire before you finish applying the plan. Use environment variables to pass credentials when you need to use different values between the plan and apply steps. - -## Initialize the backend - -When you change a backend's configuration, you must run `terraform init` again -to validate and configure the backend before you can perform any plans, applies, -or state operations. - -After you initialize, Terraform creates a `.terraform/` directory locally. This directory contains the most recent backend configuration, including any authentication parameters you provided to the Terraform CLI. Do not check this directory into Git, as it may contain sensitive credentials for your remote backend. - -The local backend configuration is different and entirely separate from the `terraform.tfstate` file that contains [state data](/terraform/language/state) about your real-world infrastructure. Terraform stores the `terraform.tfstate` file in your remote backend. - -When you change backends, Terraform gives you the option to migrate -your state to the new backend. This lets you adopt backends without losing -any existing state. - -~> **Important:** Before migrating to a new backend, we strongly recommend manually backing up your state by copying your `terraform.tfstate` file -to another location. - -## Partial configuration - -You do not need to specify every required argument in the backend configuration. -Omitting certain arguments may be desirable if some arguments are provided -automatically by an automation script running Terraform. When some or all of -the arguments are omitted, we call this a _partial configuration_. - -With a partial configuration, the remaining configuration arguments must be -provided as part of [the initialization process](/terraform/cli/init). - -There are several ways to supply the remaining arguments: - -- **File**: A configuration file may be specified via the `init` command line. - To specify a file, use the `-backend-config=PATH` option when running - `terraform init`. The partial configuration must have a `backend` block containing keys set to empty values. When you run the `terraform init -backend-config=""` command, Terraform populates the keys in the partial `backend` configuration with matching key values from the specified configuration file. In the following example, the keys defined in the `backend` block of the `state.tf` configuration file are populated with values from the `state.config` configuration: - ``` - $ `terraform init -backend-config="./state.config"` - ``` - - ```hcl - # state.tf - terraform { - backend "s3" { - bucket = "" - key = "" - region = "" - profile= "" - } - } - ``` - - ```hcl - # state.config - bucket = "your-bucket" - key = "your-state.tfstate" - region = "eu-central-1" - profile= "Your_Profile" - ``` - - When your configuration file contains secrets, you can store them in - a secure data store, such as [Vault](https://www.vaultproject.io/), - in which case it must be downloaded to the local disk before running Terraform. - -- **Command-line key/value pairs**: Key/value pairs can be specified via the - `init` command line. Note that many shells retain command-line flags in a - history file, so this isn't recommended for secrets. To specify a single - key/value pair, use the `-backend-config="KEY=VALUE"` option when running - `terraform init`. - -- **Interactively**: Terraform will interactively ask you for the required - values, unless interactive input is disabled. Terraform will not prompt for - optional values. - -If backend settings are provided in multiple locations, the top-level -settings are merged such that any command-line options override the settings -in the main configuration and then the command-line options are processed -in order, with later options overriding values set by earlier options. - -The final, merged configuration is stored on disk in the `.terraform` -directory, which should be ignored from version control. This means that -sensitive information can be omitted from version control, but it will be -present in plain text on local disk when running Terraform. - -When using partial configuration, Terraform requires at a minimum that -an empty backend configuration is specified in one of the root Terraform -configuration files, to specify the backend type. For example: - -```hcl -terraform { - backend "consul" {} -} -``` - -### File - -A backend configuration file has the contents of the `backend` block as -top-level attributes, without the need to wrap it in another `terraform` -or `backend` block: - -```hcl -address = "demo.consul.io" -path = "example_app/terraform_state" -scheme = "https" -``` - -`*.backendname.tfbackend` (e.g. `config.consul.tfbackend`) is the recommended -naming pattern. Terraform will not prevent you from using other names but following -this convention will help your editor understand the content and likely provide -better editing experience as a result. - -You can use the `-backend-config` argument on the CLI to provide a partial backend configuration. You can either specify a file containing a partial configuration or specify a set of key-value pairs. The configuration must already include a `backend` block to use this argument. Terraform applies the configurations to the arguments in the `backend` block, but it does not change the backend type. In the following example, Terraform stores state in the default backend using the arguments supplied in the `-backend-config` argument: - -```hcl -terraform { - backend { - # values provided by backend-config file - } -} -``` - -### Command-line key/value pairs - -The same settings can alternatively be specified on the command line as -follows: - -``` -$ terraform init \ - -backend-config="address=demo.consul.io" \ - -backend-config="path=example_app/terraform_state" \ - -backend-config="scheme=https" -``` - -The Consul backend also requires a Consul access token. Per the recommendation -above of omitting credentials from the configuration and using other mechanisms, -the Consul token would be provided by setting either the `CONSUL_HTTP_TOKEN` -or `CONSUL_HTTP_AUTH` environment variables. See the documentation of your -chosen backend to learn how to provide credentials to it outside of its main -configuration. - -## Change configuration - -You can change your backend configuration at any time. You can change -both the configuration itself as well as the type of backend (for example -from "consul" to "s3"). - -Terraform will automatically detect any changes in your configuration -and request a [reinitialization](/terraform/cli/init). As part of -the reinitialization process, Terraform will ask if you'd like to migrate -your existing state to the new configuration. This allows you to easily -switch from one backend to another. - -If you're using multiple [workspaces](/terraform/language/state/workspaces), -Terraform can copy all workspaces to the destination. If Terraform detects -you have multiple workspaces, it will ask if this is what you want to do. - -If you're just reconfiguring the same backend, Terraform will still ask if you -want to migrate your state. You can respond "no" in this scenario. - -## Remove a backend configuration - -Remove the `backend` block from your configuration and [reinitialize](/terraform/cli/init) the directory when prompted. Terraform also prompts you to migrate the state to the default `local` backend. diff --git a/website/docs/language/backend/kubernetes.mdx b/website/docs/language/backend/kubernetes.mdx deleted file mode 100644 index 309ebe8a39..0000000000 --- a/website/docs/language/backend/kubernetes.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -page_title: 'Backend Type: Kubernetes' -description: Terraform can store state remotely in Kubernetes and lock that 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# kubernetes - -Stores the state in a [Kubernetes secret](https://kubernetes.io/docs/concepts/configuration/secret/). - -This backend supports [state locking](/terraform/language/state/locking), with locking done using a Lease resource. - -## Example Configuration - -```hcl -terraform { - backend "kubernetes" { - secret_suffix = "state" - config_path = "~/.kube/config" - } -} -``` - -This assumes the user/service account running terraform has [permissions](https://kubernetes.io/docs/reference/access-authn-authz/authorization/) to read/write secrets in the [namespace](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) used to store the secret. - -If the `config_path` or `config_paths` attribute is set the backend will attempt to use a [kubeconfig file](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/) to gain access to the cluster. - -If the `in_cluster_config` flag is set the backend will attempt to use a [service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) to access the cluster. This can be used if Terraform is being run from within a pod running in the Kubernetes cluster. - -For most use cases either `in_cluster_config`, `config_path`, or `config_paths` will need to be set. If all flags are set the configuration at `config_path` will be used. - -Note that for the access credentials we recommend using a [partial configuration](/terraform/language/backend#partial-configuration). - -## Example Referencing - -```hcl -data "terraform_remote_state" "foo" { - backend = "kubernetes" - config = { - secret_suffix = "state" - load_config_file = true - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options are supported: - -* `secret_suffix` - (Required) Suffix used when creating the secret. The secret will be named in the format: `tfstate-{workspace}-{secret_suffix}`. Note that the backend may append its own numeric index to the secret name when chunking large state files into multiple secrets. In this case, there will be multiple secrets named in the format: `tfstate-{workspace}-{secret_suffix}-{index}`. -* `labels` - (Optional) Map of additional labels to be applied to the secret and lease. -* `namespace` - (Optional) Namespace to store the secret and lease in. Can be sourced from `KUBE_NAMESPACE`. -* `in_cluster_config` - (Optional) Used to authenticate to the cluster from inside a pod. Can be sourced from `KUBE_IN_CLUSTER_CONFIG`. -* `host` - (Optional) The hostname (in form of URI) of Kubernetes master. Can be sourced from `KUBE_HOST`. Defaults to `https://localhost`. -* `username` - (Optional) The username to use for HTTP basic authentication when accessing the Kubernetes master endpoint. Can be sourced from `KUBE_USER`. -* `password` - (Optional) The password to use for HTTP basic authentication when accessing the Kubernetes master endpoint. Can be sourced from `KUBE_PASSWORD`. -* `insecure` - (Optional) Whether server should be accessed without verifying the TLS certificate. Can be sourced from `KUBE_INSECURE`. Defaults to `false`. -* `client_certificate` - (Optional) PEM-encoded client certificate for TLS authentication. Can be sourced from `KUBE_CLIENT_CERT_DATA`. -* `client_key` - (Optional) PEM-encoded client certificate key for TLS authentication. Can be sourced from `KUBE_CLIENT_KEY_DATA`. -* `cluster_ca_certificate` - (Optional) PEM-encoded root certificates bundle for TLS authentication. Can be sourced from `KUBE_CLUSTER_CA_CERT_DATA`. -* `config_path` - (Optional) Path to the kube config file. Can be sourced from `KUBE_CONFIG_PATH`. -* `config_paths` - (Optional) List of paths to kube config files. Can be sourced from `KUBE_CONFIG_PATHS`. -* `config_context` - (Optional) Context to choose from the config file. Can be sourced from `KUBE_CTX`. -* `config_context_auth_info` - (Optional) Authentication info context of the kube config (name of the kubeconfig user, `--user` flag in `kubectl`). Can be sourced from `KUBE_CTX_AUTH_INFO`. -* `config_context_cluster` - (Optional) Cluster context of the kube config (name of the kubeconfig cluster, `--cluster` flag in `kubectl`). Can be sourced from `KUBE_CTX_CLUSTER`. -* `token` - (Optional) Token of your service account. Can be sourced from `KUBE_TOKEN`. -* `exec` - (Optional) Configuration block to use an [exec-based credential plugin](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins), e.g. call an external command to receive user credentials. - * `api_version` - (Required) API version to use when decoding the ExecCredentials resource, e.g. `client.authentication.k8s.io/v1beta1`. - * `command` - (Required) Command to execute. - * `args` - (Optional) List of arguments to pass when executing the plugin. - * `env` - (Optional) Map of environment variables to set when executing the plugin. diff --git a/website/docs/language/backend/local.mdx b/website/docs/language/backend/local.mdx deleted file mode 100644 index 7b6802f65e..0000000000 --- a/website/docs/language/backend/local.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -page_title: 'Backend Type: local' -description: >- - Terraform can store the state remotely, making it easier to version and work - with in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# local - -**Kind: Enhanced** - -The local backend stores state on the local filesystem, locks that -state using system APIs, and performs operations locally. - -## Example Configuration - -```hcl -terraform { - backend "local" { - path = "relative/path/to/terraform.tfstate" - } -} -``` - -## Data Source Configuration - -```hcl -data "terraform_remote_state" "foo" { - backend = "local" - - config = { - path = "${path.module}/../../terraform.tfstate" - } -} -``` - -## Configuration variables - -The following configuration options are supported: - -* `path` - (Optional) The path to the `tfstate` file. This defaults to - "terraform.tfstate" relative to the root module by default. -* `workspace_dir` - (Optional) The path to non-default workspaces. - -## Command Line Arguments - -~> This section describes legacy features that we've preserved for backward -compatibility but that we no longer recommend. See below for more details. - -For configurations that include a `backend "local"` block or that default to -the local backend by not specifying a backend at all, most commands that either -read or write state snapshots from the backend accept the following -additional arguments: - -* `-state=FILENAME` - overrides the state filename when _reading_ the prior - state snapshot. -* `-state-out=FILENAME` - overrides the state filename when _writing_ new state - snapshots. - - If you use `-state` without also using `-state-out` then Terraform will - use the `-state` filename for both `-state` and `-state-out`, which means - Terraform will overwrite the input file if it creates a new state snapshot. -* `-backup=FILENAME` - overrides the default filename that the local backend - would normally choose dynamically to create backup files when it writes new - state. - - If you use `-state` without also using `-backup` then Terraform will use - the `-state` filename as a filename prefix for generating a backup filename. - You can use `-backup=-` (that is, set the filename to just the ASCII - dash character) to disable the creation of backup files altogether. - -These three options are preserved for backward-compatibility with earlier -workflows that predated the introduction of built-in remote state, where -users would write wrapper scripts that fetch prior state before running -Terraform and then save the new state after Terraform exits, in which case -the three arguments would typically all be paths within a temporary -directory used just for one operation. - -Because these old workflows predate the introduction of the possibility of -[multiple workspaces](/terraform/language/state/workspaces), setting them -overrides Terraform's usual behavior of selecting a different state filename -based on the selected workspace. If you use all three of these options then -the selected workspace has no effect on which filenames Terraform will select -for state files, and so you'll need to select different filenames yourself if -you wish to keep workspace state files distinct from one another. - -These three options have no effect for configurations that have a different -backend type selected. - -We do not recommend using these options in new systems, even if you are running -Terraform in automation. Instead, -[select a different backend which supports remote state](/terraform/language/backend) and configure it -within your root module, which ensures that everyone working on your -configuration will automatically retrieve and store state in the correct shared -location without any special command line options. diff --git a/website/docs/language/backend/oci.mdx b/website/docs/language/backend/oci.mdx deleted file mode 100644 index 293005a168..0000000000 --- a/website/docs/language/backend/oci.mdx +++ /dev/null @@ -1,206 +0,0 @@ ---- -page_title: 'Backend Type: oci' -description: Terraform can store and lock state remotely in OCI object storage. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# oci - -The oci backend stores the Terraform state file in [Oracle Cloud Infrastructure (OCI) Object Storage](https://docs.oracle.com/en-us/iaas/Content/Object/Concepts/objectstorageoverview.htm#overview), allowing multiple users to collaborate using a shared remote state and benefit from features such as [state locking](https://developer.hashicorp.com/terraform/language/v1.12.x/state/locking) and [workspaces](https://developer.hashicorp.com/terraform/language/v1.12.x/state/workspaces). - -> ⚠️ **Warning:** It is highly recommended that you enable -> [Bucket Versioning](https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/usingversioning_topic-To_enable_versioning_during_bucket_creation.htm) -> on the object storage bucket to allow for state recovery in the case of accidental deletions and human error. - -## Example Configuration - -```hcl -terraform { - backend "oci" { - # Required - bucket = "mybucket" - namespace = "my-namespace" - # Optional - tenancy_ocid = "ocid1.tenancy.oc1..xxxxxxx" - user_ocid = "ocid1.user.oc1..xxxxxxxx" - fingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" - private_key_path = "~/.oci/oci_api_key.pem" - region = "us-ashburn-1" - key = "path/to/my/key" - workspace_key_prefix = "envs/" - kms_key_id = "ocid1.key.oc1.iad.xxxxxxxxxxxxxx" - auth = "APIKey" - config_file_profile = "DEFAULT" - } -} -``` - -This assumes we have a bucket created called `mybucket`. The Terraform state is written to the key `path/to/my/key`. - -Note that for the access credentials we recommend using a [partial configuration](/terraform/language/backend#partial-configuration). - -## State Storage - -The oci backend stores Terraform state files in Oracle Cloud Infrastructure (OCI) Object Storage at the path defined by the `key` parameter, inside the bucket specified by the `bucket` parameter. - -Using the example shown above, the state file would be stored at: -`path/to/my/key` in the bucket `mybucket`. - -When using Terraform workspaces, the state for the default workspace is stored exactly at the path described above. -For non-default workspaces, the state is stored using the following path format: - `//` - - - The default workspace_key_prefix is `tf-state-env`, but it can be customized using the `workspace_key_prefix` backend parameter. - - - For example, with workspace `development`, the state would be stored at: `tf-state-env/development/path/to/my/key` - -## State Locking -- The oci backend supports state locking by leveraging the `If-None-Match: *` header capability of OCI Object Storage. -- When a user initiates a `terraform plan/apply/destroy`, the backend creates a lock object in the same bucket as the state file. -- For example, the lock file for the `development` workspace would be stored at: `tf-state-env/development/path/to/my/key.lock` - -This locking mechanism helps prevent concurrent operations on the same state file, reducing the risk of corruption or conflicting changes. - -## Permissions Required - -### OCI Object Storage Bucket Permissions -Terraform requires the following [OCI IAM permissions](https://docs.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm) on the target backend bucket to manage the state file and associated lock files: - -- OBJECT_INSPECT (includes HeadObject) -- OBJECT_CREATE (includes PutObject, CreateMultipartUpload, UploadPart, and CommitMultipartUpload) -- OBJECT_DELETE (includes DeleteObject) -- OBJECT_READ (includes GetObject) - -Alternatively, you can specify the exact operations if you're using fine-grained policies: - -- GetObject -- PutObject -- DeleteObject -- HeadObject -- CreateMultipartUpload -- UploadPart -- CommitMultipart - -Note: These permissions should be granted on the specific bucket being used for Terraform state storage. -### OCI IAM Policy Reference -> [OCI IAM Policy Reference](https://docs.oracle.com/en-us/iaas/Content/Identity/Reference/policyreference.htm) This resource provides comprehensive details on the required permissions and how to structure your policies to grant Terraform the appropriate access to Object Storage resources. - -## Data Source Configuration - -To make use of the oci remote state in another configuration, -use the [`terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -```hcl -data "terraform_remote_state" "mystate" { - backend = "oci" - config = { - bucket = "mybucket" - key = "path/to/my/key" - namespace = "my-namespace" - tenancy_ocid = "ocid1.tenancy.oc1..xxxxxxx" - user_ocid = "ocid1.user.oc1..xxxxxxxx" - fingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" - private_key_path = "~/.oci/oci_api_key.pem" - region = "us-ashburn-1" - } -} -``` - -The `terraform_remote_state` data source will return all of the root module -outputs defined in the referenced remote state (but not any outputs from -nested modules unless they are explicitly output again in the root). An -example output might look like: - -``` -# data.terraform_remote_state.mystate: -data "terraform_remote_state" "mystate" { - backend = "oci" - config = { - bucket = "mybucket" - key = "path/to/my/key" - namespace = "my-namespace" - tenancy_ocid = "ocid1.tenancy.oc1..xxxxxxx" - user_ocid = "ocid1.user.oc1..xxxxxxxx" - fingerprint = "xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx" - private_key_path = "~/.oci/oci_api_key.pem" - region = "us-ashburn-1" - } -} -``` - -## Configuration - -The oci backend requires the configuration of the OCI namespace and Object Storage bucket where the Terraform state file will be stored. -### Credentials and Shared Configuration - -> ⚠️ **Warning:** -> We strongly recommend using **environment variables** to supply credentials and other sensitive data. -> Avoid hardcoding these values directly in your configuration or using the `-backend-config` flag with plaintext secrets. -> -> Sensitive values passed this way may be saved in: -> - The `.terraform` subdirectory -> - Terraform plan files (`*.tfplan`) -> -> For more guidance, refer to the [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) documentation. - -## Attribute reference - -### Required Properties - -| Name | Description | -|-----------|-----------------------------------------------------------------------------| -| `bucket` | The name of the OCI Object Storage bucket where the state file will be stored. | -| `namespace` | The namespace of the OCI Object Storage. | - -### Optional Properties - -| Name | Description | -|------------------------|-------------------------------------------------------------------------------------------------| -| `key` | The name of the state file stored in the backend. Defaults to `terraform.tfstate`. | -| `tenancy_ocid` | The OCID of the tenancy. Required for API key authentication. | -| `user_ocid` | The OCID of the user. Required for API key authentication. | -| `fingerprint` | The fingerprint of the user's API key. Required for API key authentication. | -| `private_key_path` | Path to the private key file for API authentication. Required for API key authentication. | -| `region` | The OCI region where the bucket is located. Required for most configurations. | -| `kms_key_id` | The OCID of a master encryption key used for encrypting the state file. | -| `workspace_key_prefix` | A prefix applied to the non-default state path inside the bucket. Defaults to `tf-state-env`. | -| `auth` | Authentication method (e.g., `APIKey`, `InstancePrincipal`, `ResourcePrincipal`, `InstancePrincipalWithCerts`, `SecurityToken`,`OKEWorkloadIdentity`). | -| `config_file_profile` | Profile name from the OCI config file (default `~/.oci/config`). | -| `sse_customer_key` | The customer-managed encryption key used for server-side encryption. | -| `sse_customer_key_sha256` | The SHA256 hash of the customer-managed encryption key. | -| `sse_customer_algorithm` | The algorithm used for server-side encryption. Supported values: `AES256` | - -### 🔧 Setting Backend Configuration via Environment Variables -You can configure the OCI Terraform backend using environment variables. This provides flexibility and simplifies automation workflows. - -For any backend attribute (e.g., region), you can set its value using one of the following environment variable formats: - -#### 🧩 Supported Environment Variable Prefixes (in order of priority): -1. `OCI_` – OCI SDK-compatible environment variable. Can also be used for Terraform Provider OCI credentials. - ```bash - export OCI_region=us-ashburn-1 - ``` -2. No prefix – Generic (lowest priority) - ```bash - export region=us-ashburn-1 - ``` -Terraform will resolve the attribute value using the first match it finds based on the above priority order. - -### Custom encryption key - -To use a custom encryption key, you can generate a new key and its SHA256 hash using the following commands: - -1. Generate a 256-bit (32-byte) base64-encoded AES key: -```bash - openssl rand -base64 32 -``` -2. Generate the SHA-256 hash of the decoded key: -```bash - generate using command `echo -n | base64 -d | openssl dgst -sha256 -binary | base64` -``` -Replace with the value generated in step 1. \ No newline at end of file diff --git a/website/docs/language/backend/oss.mdx b/website/docs/language/backend/oss.mdx deleted file mode 100644 index 4f2353722a..0000000000 --- a/website/docs/language/backend/oss.mdx +++ /dev/null @@ -1,144 +0,0 @@ ---- -page_title: 'Backend Type: oss' -description: Terraform can store state remotely in OSS and lock that state with OSS. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# OSS - -Stores the state as a given key in a given bucket on Stores -[Alibaba Cloud OSS](https://www.alibabacloud.com/help/product/31815.htm). -This backend also supports state locking and consistency checking via -[Alibaba Cloud Table Store](https://www.alibabacloud.com/help/doc-detail/27280.htm), which can be enabled by setting -the `tablestore_table` field to an existing TableStore table name. - -This backend supports [state locking](/terraform/language/state/locking) via TableStore. - --> **Note:** The OSS backend is available from terraform version 0.12.2. - -## Example Configuration - -```hcl -terraform { - backend "oss" { - bucket = "bucket-for-terraform-state" - prefix = "path/mystate" - key = "version-1.tfstate" - region = "cn-beijing" - tablestore_endpoint = "https://terraform-remote.cn-hangzhou.ots.aliyuncs.com" - tablestore_table = "statelock" - } -} -``` - -This assumes we have a [OSS Bucket](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/oss_bucket) created called `bucket-for-terraform-state`, -a [OTS Instance](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ots_instance) called `terraform-remote` and -a [OTS TableStore](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ots_table) called `statelock`. The -Terraform state will be written into the file `path/mystate/version-1.tfstate`. The `TableStore` must have a primary key named `LockID` of type `String`. - -## Data Source Configuration - -To make use of the OSS remote state in another configuration, use the -[`terraform_remote_state` data -source](/terraform/language/state/remote-state-data). - -```hcl -terraform { - backend "oss" { - bucket = "remote-state-dns" - prefix = "mystate/state" - key = "terraform.tfstate" - region = "cn-beijing" - } -} -``` - -The `terraform_remote_state` data source will return all of the root outputs -defined in the referenced remote state, an example output might look like: - -```hcl -data "terraform_remote_state" "network" { - backend = "oss" - config = { - bucket = "remote-state-dns" - key = "terraform.tfstate" - prefix = "mystate/state" - region = "cn-beijing" - } - outputs = {} - workspace = "default" -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options or environment variables are supported: - -* `access_key` - (Optional) Alibaba Cloud access key. It supports environment variables `ALICLOUD_ACCESS_KEY` and `ALIBABA_CLOUD_ACCESS_KEY_ID`(Recommended). - -* `secret_key` - (Optional) Alibaba Cloud secret access key. It supports environment variables `ALICLOUD_SECRET_KEY` and `ALIBABA_CLOUD_ACCESS_KEY_SECRET`(Recommended). - -* `security_token` - (Optional) STS access token. It supports environment variable `ALICLOUD_SECURITY_TOKEN` and `ALIBABA_CLOUD_SECURITY_TOKEN`(Recommended). - -* `ecs_role_name` - (Optional) The RAM Role Name attached on a ECS instance for API operations. You can retrieve this from the 'Access Control' section of the Alibaba Cloud console. - -* `region` - (Optional) The region of the OSS bucket. It supports environment variables `ALICLOUD_REGION` and `ALIBABA_CLOUD_REGION`(Recommended). - -* `endpoint` - (Optional) A custom endpoint for the OSS API. It supports environment variables `ALICLOUD_OSS_ENDPOINT` and `ALIBABA_CLOUD_OSS_ENDPOINT`(Recommended). - -* `bucket` - (Required) The name of the OSS bucket. - -* `prefix` - (Opeional) The path directory of the state file will be stored. Default to "env:". - -* `key` - (Optional) The name of the state file. Defaults to `terraform.tfstate`. - -* `tablestore_endpoint` - (Optional) A custom endpoint for the TableStore API. It supports environment variables `ALICLOUD_TABLESTORE_ENDPOINT` and `ALIBABA_CLOUD_TABLESTORE_ENDPOINT`(Recommended). - -* `tablestore_instance_name` - (Optional) Specifies the name of an instance that `TableStore` belongs to. By default, Terraform parses the name from `tablestore_endpoint`. - You should set the access URL explicitly when the `tablestore` endpoint is a VPC access URL. - -* `tablestore_table` - (Optional) A TableStore table for state locking and consistency. The table must have a primary key named `LockID` of type `String`. - -* `sts_endpoint` - (Optional) Custom endpoint for the AliCloud Security Token Service (STS) API. It supports environment variable `ALICLOUD_STS_ENDPOINT` and `ALIBABA_CLOUD_STS_ENDPOINT`(Recommended). - -* `encrypt` - (Optional) Whether to enable server side - encryption of the state file. If it is true, OSS will use 'AES256' encryption algorithm to encrypt state file. - -* `acl` - (Optional) [Object - ACL](https://www.alibabacloud.com/help/doc-detail/52284.htm) - to be applied to the state file. - -* `shared_credentials_file` - (Optional) This is the path to the shared credentials file. It can also be sourced from the `ALICLOUD_SHARED_CREDENTIALS_FILE` or `ALIBABA_CLOUD_CREDENTIALS_FILE`(Recommended) environment variable. If this is not set and a profile is specified, `~/.aliyun/config.json` will be used. - -* `profile` - (Optional) This is the Alibaba Cloud profile name as set in the shared credentials file. It supports environment variable `ALICLOUD_PROFILE` and `ALIBABA_CLOUD_PROFILE`(Recommended). - -* `assume_role_role_arn` - (Optional) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN` and `ALIBABA_CLOUD_ROLE_ARN`(Recommended). - Terraform executes configuration on account with provided credentials. - -* `assume_role_policy` - (Optional) A more restrictive policy to apply to the temporary credentials. This gives you a way to further restrict the permissions for the resulting temporary security credentials. You cannot use this policy to grant permissions that exceed those of the role that is being assumed. - -* `assume_role_session_name` - (Optional) The session name to use when assuming the role. If omitted, 'terraform' is passed to the AssumeRole call as session name. It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_NAME` and `ALIBABA_CLOUD_ROLE_SESSION_NAME`(Recommended). - -* `assume_role_session_expiration` - (Optional) The time after which the established session for assuming role expires. Valid value range: \[900-3600] seconds. Default to 3600 (in this case Alibaba Cloud uses its own default value). It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION`. - -* `assume_role` - (**Deprecated as of 1.1.0+**) If provided with a role ARN, will attempt to assume this role using the supplied credentials. It will be ignored when `assume_role_role_arn` is specified. - - **Deprecated in favor of flattening assume_role_\* options** - - * `role_arn` - (Required) The ARN of the role to assume. If ARN is set to an empty string, it does not perform role switching. It supports the environment variable `ALICLOUD_ASSUME_ROLE_ARN` and `ALIBABA_CLOUD_ROLE_ARN`(Recommended). - Terraform executes configuration on account with provided credentials. - - * `policy` - (Optional) A more restrictive policy to apply to the temporary credentials. This gives you a way to further restrict the permissions for the resulting temporary security credentials. You cannot use this policy to grant permissions that exceed those of the role that is being assumed. - - * `session_name` - (Optional) The session name to use when assuming the role. If omitted, 'terraform' is passed to the AssumeRole call as session name. It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_NAME`. - - * `session_expiration` - (Optional) The time after which the established session for assuming role expires. Valid value range: \[900-3600] seconds. Default to 3600 (in this case Alibaba Cloud uses its own default value). It supports environment variable `ALICLOUD_ASSUME_ROLE_SESSION_EXPIRATION`. - --> **Note:** If you want to store state in the custom OSS endpoint, you can specify an environment variable `OSS_ENDPOINT`, like "oss-cn-beijing-internal.aliyuncs.com" diff --git a/website/docs/language/backend/pg.mdx b/website/docs/language/backend/pg.mdx deleted file mode 100644 index bf02be3eab..0000000000 --- a/website/docs/language/backend/pg.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -page_title: 'Backend Type: pg' -description: Terraform can store state remotely in a Postgres database with locking. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# pg - -Stores the state in a [Postgres database](https://www.postgresql.org) version 10 or newer. - -This backend supports [state locking](/terraform/language/state/locking). - -## Example Configuration - -```hcl -terraform { - backend "pg" { - conn_str = "postgres://user:pass@db.example.com/terraform_backend" - } -} -``` - -Before initializing the backend with `terraform init`, the database must already exist: - -``` -createdb terraform_backend -``` - -This `createdb` command is found in [Postgres client applications](https://www.postgresql.org/docs/10/reference-client.html) which are installed along with the database server. - - -### Using environment variables - -We recommend using environment variables to configure the `pg` backend in order -not to have sensitive credentials written to disk and committed to source -control. - -The `pg` backend supports the standard [`libpq` environment variables](https://www.postgresql.org/docs/current/libpq-envars.html). - -The backend can be configured either by giving the whole configuration as an -environment variable: - -```hcl -terraform { - backend "pg" {} -} -``` - -```shellsession -$ export PG_CONN_STR=postgres://user:pass@db.example.com/terraform_backend -$ terraform init -``` - -or just the sensitive parameters: - -```hcl -terraform { - backend "pg" { - conn_str = "postgres://db.example.com/terraform_backend" - } -} -``` - -```shellsession -$ export PGUSER=user -$ read -s PGPASSWORD -$ export PGPASSWORD -$ terraform init -``` - -## Data Source Configuration - -To make use of the pg remote state in another configuration, use the [`terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -```hcl -data "terraform_remote_state" "network" { - backend = "pg" - config = { - conn_str = "postgres://localhost/terraform_backend" - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options or environment variables are supported: - -- `conn_str` - Postgres connection string; a `postgres://` URL. The `PG_CONN_STR` and [standard `libpq`](https://www.postgresql.org/docs/current/libpq-envars.html) environment variables can also be used to indicate how to connect to the PostgreSQL database. -- `schema_name` - Name of the automatically-managed Postgres schema, default to `terraform_remote_state`. Can also be set using the `PG_SCHEMA_NAME` environment variable. -- `skip_schema_creation` - If set to `true`, the Postgres schema must already exist. Can also be set using the `PG_SKIP_SCHEMA_CREATION` environment variable. Terraform won't try to create the schema, this is useful when it has already been created by a database administrator. -- `skip_table_creation` - If set to `true`, the Postgres table must already exist. Can also be set using the `PG_SKIP_TABLE_CREATION` environment variable. Terraform won't try to create the table, this is useful when it has already been created by a database administrator. -- `skip_index_creation` - If set to `true`, the Postgres index must already exist. Can also be set using the `PG_SKIP_INDEX_CREATION` environment variable. Terraform won't try to create the index, this is useful when it has already been created by a database administrator. - -## Technical Design - -This backend creates one table **states** in the automatically-managed Postgres schema configured by the `schema_name` variable. - -The table is keyed by the [workspace](/terraform/language/state/workspaces) name. If workspaces are not in use, the name `default` is used. - -Locking is supported using [Postgres advisory locks](https://www.postgresql.org/docs/9.5/explicit-locking.html#ADVISORY-LOCKS). [`force-unlock`](/terraform/cli/commands/force-unlock) is not supported, because these database-native locks will automatically unlock when the session is aborted or the connection fails. To see outstanding locks in a Postgres server, use the [`pg_locks` system view](https://www.postgresql.org/docs/9.5/view-pg-locks.html). - -The **states** table contains: - -- a serial integer `id`, used as the key for advisory locks -- the workspace `name` key as _text_ with a unique index -- the Terraform state `data` as _text_ diff --git a/website/docs/language/backend/remote.mdx b/website/docs/language/backend/remote.mdx deleted file mode 100644 index 2176c47d97..0000000000 --- a/website/docs/language/backend/remote.mdx +++ /dev/null @@ -1,251 +0,0 @@ ---- -page_title: 'Backend Type: remote' -description: >- - Terraform can store the state and run operations remotely, making it easier to - version and work with in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# remote - --> **Note:** We introduced the remote backend in Terraform v0.11.13 and Terraform Enterprise v201809-1. As of Terraform v1.1.0 and Terraform Enterprise v202201-1, we recommend using HCP Terraform's built-in [`cloud` integration](/terraform/cli/cloud/settings) instead. The `cloud` option supports an improved user experience and more features, such as [structured run output mode](/terraform/cloud-docs/workspaces/settings#user-interface), which displays your plan and apply results in a human-readable format. - -The remote backend is unique among all other Terraform backends because it can both store state snapshots and execute operations for HCP Terraform's [CLI-driven run workflow](/terraform/cloud-docs/run/cli). It used to be called an "enhanced" backend. - -When using full remote operations, operations like `terraform plan` or `terraform apply` can be executed in Terraform -Cloud's run environment, with log output streaming to the local terminal. Remote plans and applies use variable values from the associated HCP Terraform workspace. - -You can also use HCP Terraform with local operations, in which case only state is stored in the HCP Terraform backend. - -## Command Support - -The remote backend supports the following Terraform commands: - -- `apply` -- `console` (supported in Terraform >= v0.11.12) -- `destroy` -- `fmt` -- `get` -- `graph` (supported in Terraform >= v0.11.12) -- `import` (supported in Terraform >= v0.11.12) -- `init` -- `output` -- `plan` -- `providers` -- `show` -- `state` (supports all sub-commands: list, mv, pull, push, rm, show) -- `taint` -- `untaint` -- `validate` -- `version` -- `workspace` - -## Workspaces - -The remote backend can work with either a single remote HCP Terraform workspace, or with multiple similarly-named remote workspaces (like `networking-dev` and `networking-prod`). The `workspaces` block of the backend configuration -determines which mode it uses: - -- To use a single remote HCP Terraform workspace, set `workspaces.name` to the - remote workspace's full name (like `networking-prod`). - -- To use multiple remote workspaces, set `workspaces.prefix` to a prefix used in - all of the desired remote workspace names. For example, set - `prefix = "networking-"` to use HCP Terraform workspaces with - names like `networking-dev` and `networking-prod`. This is helpful when - mapping multiple Terraform CLI [workspaces](/terraform/language/state/workspaces) - used in a single Terraform configuration to multiple HCP Terraform - workspaces. - - -The backend configuration requires either `name` or `prefix`. Omitting both or -setting both results in a configuration error. - -If previous state is present when you run `terraform init` and the corresponding -remote workspaces are empty or absent, Terraform will create workspaces and -update the remote state accordingly. However, if your workspace requires variables or a specific version of Terraform for remote operations, we -recommend that you create your remote workspaces on HCP Terraform before -running any remote operations against them. - -### Workspace Names - -Terraform uses shortened names without the common prefix to interact with workspaces on the command line. For example, if `prefix = "networking-"`, use `terraform workspace select prod` to switch to the Terraform CLI workspace `prod` within the current configuration. However, remote Terraform operations such as `plan` and `apply` for that Terraform CLI workspace will take place in the HCP Terraform workspace `networking-prod`. - -Because of this, the [`terraform.workspace`](/terraform/language/state/workspaces#current-workspace-interpolation) interpolation expression produces different results depending on whether a remote workspace is configured to perform operations locally or remotely. For example, in a remote workspace called `networking-prod` created with `prefix = "networking-"` the expression produces the following: - -- For local operations, `terraform.workspace` = `prod` -- For remote operations, `terraform.workspace`= `networking-prod` - -Prior to Terraform version 1.1.0, HCP Terraform workspaces used only the single `default` Terraform CLI workspace internally. So if a Terraform configuration used `terraform.workspace` to return `dev` or `prod`, remote runs in HCP Terraform would always evaluate it as `default`, regardless of -which workspace you set with the `terraform workspace select` command. Therefore, we do not recommend using `terraform.workspace` in Terraform configurations that use Terraform 1.0.x or earlier and run remote operations against HCP Terraform workspaces. - -### Determining Run Environment - -If you need to determine whether a run is local or remote in your Terraform configuration, we recommend using [HCP Terraform run environment variables](/terraform/cloud-docs/run/run-environment#environment-variables). The example below uses `HCP_TERRAFORM_RUN_ID`. - -```hcl -output "current_workspace_name" { - value = terraform.workspace -} - -variable "HCP_TERRAFORM_RUN_ID" { - type = string - default = "" -} - -output "remote_execution_determine" { - value = "Remote run environment? %{if var.HCP_TERRAFORM_RUN_ID != ""}Yes%{else}No this is local%{endif}!" -} -``` - - -## Example Configurations - --> **Note:** We recommend omitting the token from the configuration, and instead using -[`terraform login`](/terraform/cli/commands/login) or manually configuring -`credentials` in the [CLI config file](/terraform/cli/config/config-file#credentials). - -### Basic Configuration - -```hcl -# Using a single workspace: -terraform { - backend "remote" { - hostname = "app.terraform.io" - organization = "company" - - workspaces { - name = "my-app-prod" - } - } -} - -# Using multiple workspaces: -terraform { - backend "remote" { - hostname = "app.terraform.io" - organization = "company" - - workspaces { - prefix = "my-app-" - } - } -} -``` - -### Using CLI Input - -```hcl -# main.tf -terraform { - required_version = "~> 0.12.0" - - backend "remote" {} -} -``` - -Backend configuration file: - -```hcl -# config.remote.tfbackend -workspaces { name = "workspace" } -hostname = "app.terraform.io" -organization = "company" -``` - -Running `terraform init` with the backend file: - -```sh -terraform init -backend-config=config.remote.tfbackend -``` - -### Data Source Configuration - -```hcl -data "terraform_remote_state" "foo" { - backend = "remote" - - config = { - organization = "company" - - workspaces = { - name = "workspace" - } - } -} -``` - -## Configuration Variables - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration options are supported: - -- `hostname` - (Optional) The remote backend hostname to connect to. Defaults - to app.terraform.io. -- `organization` - (Required) The name of the organization containing the - targeted workspace(s). -- `token` - (Optional) The token used to authenticate with the remote backend. - We recommend omitting the token from the configuration, and instead using - [`terraform login`](/terraform/cli/commands/login) or manually configuring - `credentials` in the - [CLI config file](/terraform/cli/config/config-file#credentials). -- `workspaces` - (Required) A block specifying which remote workspace(s) to use. - The `workspaces` block supports the following keys: - - - `name` - (Optional) The full name of one remote workspace. When configured, - only the default workspace can be used. This option conflicts with `prefix`. - - `prefix` - (Optional) A prefix used in the names of one or more remote - workspaces, all of which can be used with this configuration. The full - workspace names are used in HCP Terraform, and the short names - (minus the prefix) are used on the command line for Terraform CLI workspaces. - If omitted, only the default workspace can be used. This option conflicts with `name`. - --> **Note:** You must use the `name` key when configuring a `terraform_remote_state` -data source that retrieves state from another HCP Terraform workspace. The `prefix` key is only -intended for use when configuring an instance of the remote backend. - -## Command Line Arguments - -For configurations that include a `backend "remote"` 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. - - Normally state-modification operations require using a local version of - Terraform CLI which is compatible with the Terraform version selected - for the remote workspace as part of its settings. This is to avoid the - local operation creating a new state snapshot which the workspace's - remote execution environment would then be unable to decode. - - Overriding this check can result in an HCP Terraform workspace that is - no longer able to complete remote operations, so we recommend against - using this option. - -## Excluding Files from Upload with .terraformignore - --> **Version note:** `.terraformignore` support was added in Terraform 0.12.11. - -When executing a remote `plan` or `apply` in a [CLI-driven run](/terraform/cloud-docs/run/cli), -an archive of your configuration directory is uploaded to HCP Terraform. You can define -paths to ignore from upload via a `.terraformignore` file at the root of your configuration directory. If this file is not present, the archive will exclude the following by default: - -- `.git/` directories -- `.terraform/` directories (exclusive of `.terraform/modules`) - -The `.terraformignore` file can include rules as one would include in a -[`.gitignore` file](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository#_ignoring) - -- Comments (starting with `#`) or blank lines are ignored -- End a pattern with a forward slash `/` to specify a directory -- Negate a pattern by starting it with an exclamation point `!` - -Note that unlike `.gitignore`, only the `.terraformignore` at the root of the configuration -directory is considered. diff --git a/website/docs/language/backend/s3.mdx b/website/docs/language/backend/s3.mdx deleted file mode 100644 index 5227c07f57..0000000000 --- a/website/docs/language/backend/s3.mdx +++ /dev/null @@ -1,623 +0,0 @@ ---- -page_title: 'Backend Type: s3' -description: Terraform can store and lock state remotely in Amazon S3. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# S3 - -Stores the state as a given key in a given bucket on [Amazon S3](https://aws.amazon.com/s3/). -This backend also supports state locking which can be enabled by setting the `use_lockfile` argument to `true`. - -~> **Warning!** It is highly recommended that you enable -[Bucket Versioning](https://docs.aws.amazon.com/AmazonS3/latest/userguide/manage-versioning-examples.html) -on the S3 bucket to allow for state recovery in the case of accidental deletions and human error. - -## Example Configuration - -```hcl -terraform { - backend "s3" { - bucket = "mybucket" - key = "path/to/my/key" - region = "us-east-1" - } -} -``` - -This assumes we have a bucket created called `mybucket`. The Terraform state is written to the key `path/to/my/key`. - -Note that for the access credentials we recommend using a [partial configuration](/terraform/language/backend#partial-configuration). - -## State Storage - -The S3 backend stores state data in an S3 object at the path set by the `key` parameter in the S3 bucket indicated by the `bucket` parameter. -Using the example shown above, the state would be stored at the path `path/to/my/key` in the bucket `mybucket`. - -When using [workspaces](/terraform/language/state/workspaces), the state for the `default` workspace is stored at the location described above. -Other workspaces are stored using the path `//`. -The default workspace key prefix is `env:` and it can be configured using the parameter `workspace_key_prefix`. -Using the example above, the state for the workspace `development` would be stored at the path `env:/development/path/to/my/key`. - - -### State Locking - -State locking is an opt-in feature of the S3 backend. - -Locking can be enabled via S3 or DynamoDB. However, **DynamoDB-based locking is deprecated** and will be removed in a future minor version. To support migration from older versions of Terraform that only support DynamoDB-based locking, the S3 and DynamoDB arguments can be configured simultaneously. - -#### Enabling S3 State Locking - -To enable S3 state locking, use the following optional argument: - -- `use_lockfile` - (Optional) Whether to use a lockfile for locking the state file. Defaults to `false`. - -#### Enabling DynamoDB State Locking (Deprecated) - -To enable DynamoDB state locking, use the following optional arguments: - -- `dynamodb_endpoint` - (Optional, **Deprecated**) Custom endpoint URL for the AWS DynamoDB API. Use `endpoints.dynamodb` instead. -- `dynamodb_table` - (Optional, **Deprecated**) Name of the DynamoDB Table to use for state locking and consistency. The table must have a partition key named `LockID` with a type of `String`. - -## Permissions Required - -### S3 Bucket Permissions - -When not using [workspaces](/terraform/language/state/workspaces)(or when only using the `default` workspace), Terraform will need the following AWS IAM permissions on the target backend bucket: - -* `s3:ListBucket` on `arn:aws:s3:::mybucket`. At a minimum, this must be able to list the path where the state is stored. -* `s3:GetObject` on `arn:aws:s3:::mybucket/path/to/my/key` -* `s3:PutObject` on `arn:aws:s3:::mybucket/path/to/my/key` - --> **Note:** If `use_lockfile` is set, `s3:GetObject`, `s3:PutObject`, -and `s3:DeleteObject` are required on the lock file, e.g., -`arn:aws:s3:::mybucket/path/to/my/key.tflock`. - --> **Note:** `s3:DeleteObject` is not required on the state file, as Terraform does not delete it. - -This is seen in the following AWS IAM Statement: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:ListBucket", - "Resource": "arn:aws:s3:::mybucket", - "Condition": { - "StringEquals": { - "s3:prefix": "path/to/my/key" - } - } - }, - { - "Effect": "Allow", - "Action": ["s3:GetObject", "s3:PutObject"], - "Resource": [ - "arn:aws:s3:::mybucket/path/to/my/key" - ] - }, - { - "Effect": "Allow", - "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"], - "Resource": [ - "arn:aws:s3:::mybucket/path/to/my/key.tflock" - ] - } - ] -} -``` - -When using [workspaces](/terraform/language/state/workspaces), Terraform will also need permissions to create, list, read, update, and delete the workspace state file: - -* `s3:ListBucket` on `arn:aws:s3:::mybucket`. At a minumum, this must be able to list the path where the `default` workspace is stored as well as the other workspaces. -* `s3:GetObject` on `arn:aws:s3:::mybucket/path/to/my/key`, `arn:aws:s3:::mybucket//*/path/to/my/key` -* `s3:PutObject` on `arn:aws:s3:::mybucket/path/to/my/key`, `arn:aws:s3:::mybucket//*/path/to/my/key` -* `s3:DeleteObject` on `arn:aws:s3:::mybucket//*/path/to/my/key` - --> **Note:** If `use_lockfile` is set, `s3:GetObject`, `s3:PutObject`, -and `s3:DeleteObject` are required on the lock file, e.g., -`arn:aws:s3:::mybucket//*/path/to/my/key.tflock`. - --> **Note:** AWS can control access to S3 buckets with either IAM policies -attached to users/groups/roles (like the example above) or resource policies -attached to bucket objects (which look similar but also require a `Principal` to -indicate which entity has those permissions). For more details, see Amazon's -documentation about -[S3 access control](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html). - -### DynamoDB Table Permissions - -If you are using the deprecated DynamoDB-based locking mechanism, Terraform will need the following AWS IAM -permissions on the DynamoDB table (`arn:aws:dynamodb:::table/mytable`): - -* `dynamodb:DescribeTable` -* `dynamodb:GetItem` -* `dynamodb:PutItem` -* `dynamodb:DeleteItem` - -This is seen in the following AWS IAM Statement: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "dynamodb:DescribeTable", - "dynamodb:GetItem", - "dynamodb:PutItem", - "dynamodb:DeleteItem" - ], - "Resource": "arn:aws:dynamodb:*:*:table/mytable" - } - ] -} -``` - -## Data Source Configuration - -To make use of the S3 remote state in another configuration, -use the [`terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -```hcl -data "terraform_remote_state" "network" { - backend = "s3" - config = { - bucket = "terraform-state-prod" - key = "network/terraform.tfstate" - region = "us-east-1" - } -} -``` - -The `terraform_remote_state` data source will return all of the root module -outputs defined in the referenced remote state (but not any outputs from -nested modules unless they are explicitly output again in the root). An -example output might look like: - -``` -data.terraform_remote_state.network: - id = 2016-10-29 01:57:59.780010914 +0000 UTC - addresses.# = 2 - addresses.0 = 52.207.220.222 - addresses.1 = 54.196.78.166 - backend = s3 - config.% = 3 - config.bucket = terraform-state-prod - config.key = network/terraform.tfstate - config.region = us-east-1 - elb_address = web-elb-790251200.us-east-1.elb.amazonaws.com - public_subnet_id = subnet-1e05dd33 -``` - -## Configuration - -This backend requires the configuration of the AWS Region and S3 state storage. Other configuration, such as enabling state locking, is optional. - -### Credentials and Shared Configuration - -!> **Warning:** We recommend using environment variables to supply credentials and other sensitive data. If you use `-backend-config` or hardcode these values directly in your configuration, Terraform will include these values in both the `.terraform` subdirectory and in plan files. Refer to [Credentials and Sensitive Data](/terraform/language/backend#credentials-and-sensitive-data) for details. - -The following configuration is required: - -* `region` - (Required) AWS Region of the S3 Bucket and DynamoDB Table (if used). This can also be sourced from the `AWS_DEFAULT_REGION` and `AWS_REGION` environment variables. - -The following configuration is optional: - -* `use_lockfile` - (Optional) Whether to use a lockfile for locking the state file. Defaults to `false`. -* `access_key` - (Optional) AWS access key. If configured, must also configure `secret_key`. This can also be sourced from the `AWS_ACCESS_KEY_ID` environment variable, AWS shared credentials file (e.g. `~/.aws/credentials`), or AWS shared configuration file (e.g. `~/.aws/config`). -* `allowed_account_ids` - (Optional) List of allowed AWS account IDs to prevent potential destruction of a live environment. Conflicts with `forbidden_account_ids`. -* `custom_ca_bundle` - (Optional) File containing custom root and intermediate certificates. Can also be set using the `AWS_CA_BUNDLE` environment variable. Setting ca_bundle in the shared config file is not supported. -* `ec2_metadata_service_endpoint` - (Optional) Custom endpoint URL for the EC2 Instance Metadata Service (IMDS) API. - Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT` environment variable. -* `ec2_metadata_service_endpoint_mode` - (Optional) Mode to use in communicating with the metadata service. - Valid values are `IPv4` and `IPv6`. - Can also be set with the `AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE` environment variable. -* `forbidden_account_ids` - (Optional) List of forbidden AWS account IDs to prevent potential destruction of a live environment. Conflicts with `allowed_account_ids`. -* `http_proxy` - (Optional) URL of a proxy to use for HTTP requests when accessing the AWS API. - Can also be set using the `HTTP_PROXY` or `http_proxy` environment variables. -* `https_proxy` - (Optional) URL of a proxy to use for HTTPS requests when accessing the AWS API. - Can also be set using the `HTTPS_PROXY` or `https_proxy` environment variables. -* `iam_endpoint` - (Optional, **Deprecated**) Custom endpoint URL for the AWS Identity and Access Management (IAM) API. - Use `endpoints.iam` instead. -* `insecure` - (Optional) Whether to explicitly allow the backend to perform "insecure" SSL requests. If omitted, the default value is `false`. -* `no_proxy` - (Optional) Comma-separated list of hosts that should not use HTTP or HTTPS proxies. - Each value can be one of: - * A domain name - * An IP address - * A CIDR address - * An asterisk (`*`), to indicate that no proxying should be performed - Domain name and IP address values can also include a port number. - Can also be set using the `NO_PROXY` or `no_proxy` environment variables. -* `max_retries` - (Optional) The maximum number of times an AWS API request is retried on retryable failure. Defaults to 5. -* `profile` - (Optional) Name of AWS profile in AWS shared credentials file (e.g. `~/.aws/credentials`) or AWS shared configuration file (e.g. `~/.aws/config`) to use for credentials and/or configuration. This can also be sourced from the `AWS_PROFILE` environment variable. -* `retry_mode` - (Optional) Specifies how retries are attempted. Valid values are `standard` and `adaptive`. Can also be configured using the `AWS_RETRY_MODE` environment variable or the shared config file parameter `retry_mode`. -* `secret_key` - (Optional) AWS access key. If configured, must also configure `access_key`. This can also be sourced from the `AWS_SECRET_ACCESS_KEY` environment variable, AWS shared credentials file (e.g. `~/.aws/credentials`), or AWS shared configuration file (e.g. `~/.aws/config`). -* `shared_config_files` - (Optional) List of paths to AWS shared configuration files. Defaults to `~/.aws/config`. -* `shared_credentials_file` - (Optional, **Deprecated**, use `shared_credentials_files` instead) Path to the AWS shared credentials file. Defaults to `~/.aws/credentials`. -* `shared_credentials_files` - (Optional) List of paths to AWS shared credentials files. Defaults to `~/.aws/credentials`. -* `skip_credentials_validation` - (Optional) Skip credentials validation via the STS API. - Useful for testing and for AWS API implementations that do not have STS available. -* `skip_region_validation` - (Optional) Skip validation of provided region name. -* `skip_requesting_account_id` - (Optional) Whether to skip requesting the account ID. - Useful for AWS API implementations that do not have the IAM, STS API, or metadata API. -* `skip_metadata_api_check` - (Optional) Skip usage of EC2 Metadata API. -* `skip_s3_checksum` - (Optional) Do not include checksum when uploading S3 Objects. - Useful for some S3-Compatible APIs. -* `sts_endpoint` - (Optional, **Deprecated**) Custom endpoint URL for the AWS Security Token Service (STS) API. - Use `endpoints.sts` instead. -* `sts_region` - (Optional) AWS region for STS. If unset, AWS will use the same region for STS as other non-STS operations. -* `token` - (Optional) Multi-Factor Authentication (MFA) token. This can also be sourced from the `AWS_SESSION_TOKEN` environment variable. -* `use_dualstack_endpoint` - (Optional) Force the backend to resolve endpoints with DualStack capability. Can also be set with the `AWS_USE_DUALSTACK_ENDPOINT` environment variable or in a shared config file (`use_dualstack_endpoint`). -* `use_fips_endpoint` - (Optional) Force the backend to resolve endpoints with FIPS capability. Can also be set with the `AWS_USE_FIPS_ENDPOINT` environment variable or in a shared config file (`use_fips_endpoint`). - -#### Overriding AWS API endpoints - -The optional argument `endpoints` contains the following arguments: - -* `dynamodb` - (Optional, **Deprecated**) Custom endpoint URL for the AWS DynamoDB API. - This can also be sourced from the environment variable `AWS_ENDPOINT_URL_DYNAMODB` or the deprecated environment variable `AWS_DYNAMODB_ENDPOINT`. -* `iam` - (Optional) Custom endpoint URL for the AWS IAM API. - This can also be sourced from the environment variable `AWS_ENDPOINT_URL_IAM` or the deprecated environment variable `AWS_IAM_ENDPOINT`. -* `s3` - (Optional) Custom endpoint URL for the AWS S3 API. - This can also be sourced from the environment variable `AWS_ENDPOINT_URL_S3` or the deprecated environment variable `AWS_S3_ENDPOINT`. -* `sso` - (Optional) Custom endpoint URL for the AWS IAM Identity Center (formerly known as AWS SSO) API. - This can also be sourced from the environment variable `AWS_ENDPOINT_URL_SSO`. -* `sts` - (Optional) Custom endpoint URL for the AWS STS API. - This can also be sourced from the environment variable `AWS_ENDPOINT_URL_STS` or the deprecated environment variable `AWS_STS_ENDPOINT`. - -The environment variable `AWS_ENDPOINT_URL` can be used to set a base endpoint URL for all services. - -Endpoints can also be overridden using the [AWS shared configuration file](https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html#ss-endpoints-config). -Setting the parameter `endpoint_url` on a profile will set that endpoint for all services. -To set endpoints for specific services, create a `services` section and set the `endpoint_url` parameters for each desired service. -Endpoints set for specific services will override the base endpoint configured in the profile. - -#### Assume Role Configuration - -The argument `assume_role` contains the following arguments: - -* `role_arn` - (Required) Amazon Resource Name (ARN) of the IAM Role to assume. -* `duration` - (Optional) The duration individual credentials will be valid. - Credentials are automatically renewed up to the maximum defined by the AWS account. - Specified using the format `hms` with any unit being optional. - For example, an hour and a half can be specified as `1h30m` or `90m`. - Must be between 15 minutes (15m) and 12 hours (12h). -* `external_id` - (Optional) External identifier to use when assuming the role. -* `policy` - (Optional) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed. -* `policy_arns` - (Optional) Set of Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed. -* `session_name` - (Optional) Session name to use when assuming the role. -* `source_identity` - (Optional) Source identity specified by the principal assuming the role. -* `tags` - (Optional) Map of assume role session tags. -* `transitive_tag_keys` - (Optional) Set of assume role session tag keys to pass to any subsequent sessions. - -Multiple `assume_role` values can be specified, and the roles will be assumed in order. - -```terraform -terraform { - backend "s3" { - bucket = "example-bucket" - key = "path/to/state" - region = "us-east-1" - assume_role = { - role_arn = "arn:aws:iam::PRODUCTION-ACCOUNT-ID:role/Terraform" - } - } -} -``` - -#### Assume Role With Web Identity Configuration - -The following `assume_role_with_web_identity` configuration block is optional: - -* `role_arn` - (Required) Amazon Resource Name (ARN) of the IAM Role to assume. - Can also be set with the `AWS_ROLE_ARN` environment variable. -* `duration` - (Optional) The duration individual credentials will be valid. - Credentials are automatically renewed up to the maximum defined by the AWS account. - Specified using the format `hms` with any unit being optional. - For example, an hour and a half can be specified as `1h30m` or `90m`. - Must be between 15 minutes (15m) and 12 hours (12h). -* `policy` - (Optional) IAM Policy JSON describing further restricting permissions for the IAM Role being assumed. -* `policy_arns` - (Optional) Set of Amazon Resource Names (ARNs) of IAM Policies describing further restricting permissions for the IAM Role being assumed. -* `session_name` - (Optional) Session name to use when assuming the role. - Can also be set with the `AWS_ROLE_SESSION_NAME` environment variable. -* `web_identity_token` - (Optional) The value of a web identity token from an OpenID Connect (OIDC) or OAuth provider. - One of `web_identity_token` or `web_identity_token_file` is required. -* `web_identity_token_file` - (Optional) File containing a web identity token from an OpenID Connect (OIDC) or OAuth provider. - One of `web_identity_token_file` or `web_identity_token` is required. - Can also be set with the `AWS_WEB_IDENTITY_TOKEN_FILE` environment variable. - -```terraform -terraform { - backend "s3" { - bucket = "example-bucket" - key = "path/to/state" - region = "us-east-1" - assume_role_with_web_identity = { - role_arn = "arn:aws:iam::PRODUCTION-ACCOUNT-ID:role/Terraform" - web_identity_token = "" - } - } -} -``` - -### S3 State Storage - -The following configuration is required: - -* `bucket` - (Required) Name of the S3 Bucket. -* `key` - (Required) Path to the state file inside the S3 Bucket. When using a non-default [workspace](/terraform/language/state/workspaces), the state path will be `//` (see also the `workspace_key_prefix` configuration). - -The following configuration is optional: - -* `acl` - (Optional) [Canned ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl) to be applied to the state and lock files. -* `encrypt` - (Optional) Enable [server side encryption](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html) of the state and lock files. -* `endpoint` - (Optional, **Deprecated**) Custom endpoint URL for the AWS S3 API. - Use `endpoints.s3` instead. -* `force_path_style` - (Optional, **Deprecated**) Enable path-style S3 URLs (`https:///` instead of `https://.`). -* `kms_key_id` - (Optional) Amazon Resource Name (ARN) of a Key Management Service (KMS) Key to use for encrypting the state and lock files. Note that if this value is specified, Terraform will need `kms:Encrypt`, `kms:Decrypt` and `kms:GenerateDataKey` permissions on this KMS key. -* `sse_customer_key` - (Optional) The key to use for encrypting state and lock files with [Server-Side Encryption with Customer-Provided Keys (SSE-C)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html). This is the base64-encoded value of the key, which must decode to 256 bits. This can also be sourced from the `AWS_SSE_CUSTOMER_KEY` environment variable, which is recommended due to the sensitivity of the value. Setting it inside a terraform file will cause it to be persisted to disk in `terraform.tfstate`. -* `use_path_style` - (Optional) Enable path-style S3 URLs (`https:///` instead of `https://.`). -* `workspace_key_prefix` - (Optional) Prefix applied to the state path inside the bucket. This is only relevant when using a non-default workspace. Defaults to `env:`. - -## Multi-account AWS Architecture - -A common architectural pattern is for an organization to use a number of -separate AWS accounts to isolate different teams and environments. For example, -a "staging" system will often be deployed into a separate AWS account than -its corresponding "production" system, to minimize the risk of the staging -environment affecting production infrastructure, whether via rate limiting, -misconfigured access controls, or other unintended interactions. - -The S3 backend can be used in a number of different ways that make different -tradeoffs between convenience, security, and isolation in such an organization. -This section describes one such approach that aims to find a good compromise -between these tradeoffs, allowing use of -[Terraform's workspaces feature](/terraform/language/state/workspaces) to switch -conveniently between multiple isolated deployments of the same configuration. - -Use this section as a starting-point for your approach, but note that -you will probably need to make adjustments for the unique standards and -regulations that apply to your organization. You will also need to make some -adjustments to this approach to account for _existing_ practices within your -organization, if for example other tools have previously been used to manage -infrastructure. - -Terraform is an administrative tool that manages your infrastructure, and so -ideally the infrastructure that is used by Terraform should exist outside of -the infrastructure that Terraform manages. This can be achieved by creating a -separate _administrative_ AWS account which contains the user accounts used by -human operators and any infrastructure and tools used to manage the other -accounts. Isolating shared administrative tools from your main environments -has a number of advantages, such as avoiding accidentally damaging the -administrative infrastructure while changing the target infrastructure, and -reducing the risk that an attacker might abuse production infrastructure to -gain access to the (usually more privileged) administrative infrastructure. - -### Administrative Account Setup - -Your administrative AWS account will contain at least the following items: - -* One or more [IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) - for system administrators that will log in to maintain infrastructure in - the other accounts. -* Optionally, one or more [IAM groups](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) - to differentiate between different groups of users that have different - levels of access to the other AWS accounts. -* An [S3 bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html) - that will contain the Terraform state files for each workspace. - -Provide the S3 bucket name to Terraform in the S3 backend configuration -using the `bucket` argument. Set `use_lockfile` to true to enable state locking. -Configure a suitable `workspace_key_prefix` to manage states of workspaces that -will be created for this configuration. - -### Environment Account Setup - -For the sake of this section, the term "environment account" refers to one -of the accounts whose contents are managed by Terraform, separate from the -administrative account described above. - -Your environment accounts will eventually contain your own product-specific -infrastructure. Along with this it must contain one or more -[IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) -that grant sufficient access for Terraform to perform the desired management -tasks. - -### Delegating Access - -Each Administrator will run Terraform using credentials for their IAM user -in the administrative account. -[IAM Role Delegation](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html) -is used to grant these users access to the roles created in each environment -account. - -Full details on role delegation are covered in the AWS documentation linked -above. The most important details are: - -* Each role's _Assume Role Policy_ must grant access to the administrative AWS - account, which creates a trust relationship with the administrative AWS - account so that its users may assume the role. -* The users or groups within the administrative account must also have a - policy that creates the converse relationship, allowing these users or groups - to assume that role. - -Since the purpose of the administrative account is only to host tools for -managing other accounts, it is useful to give the administrative accounts -restricted access only to the specific operations needed to assume the -environment account role and access the Terraform state. By blocking all -other access, you remove the risk that user error will lead to staging or -production resources being created in the administrative account by mistake. - -When configuring Terraform, use either environment variables or the standard -credentials file `~/.aws/credentials` to provide the administrator user's -IAM credentials within the administrative account to both the S3 backend _and_ -to Terraform's AWS provider. - -Use conditional configuration to pass a different `assume_role` value to -the AWS provider depending on the selected workspace. For example: - -```hcl -variable "workspace_iam_roles" { - default = { - staging = "arn:aws:iam::STAGING-ACCOUNT-ID:role/Terraform" - production = "arn:aws:iam::PRODUCTION-ACCOUNT-ID:role/Terraform" - } -} - -provider "aws" { - # No credentials explicitly set here because they come from either the - # environment or the global credentials file. - - assume_role = { - role_arn = var.workspace_iam_roles[terraform.workspace] - } -} -``` - -If workspace IAM roles are centrally managed and shared across many separate -Terraform configurations, the role ARNs could also be obtained via a data -source such as [`terraform_remote_state`](/terraform/language/state/remote-state-data) -to avoid repeating these values. - -### Creating and Selecting Workspaces - -With the necessary objects created and the backend configured, run -`terraform init` to initialize the backend and establish an initial workspace -called "default". This workspace will not be used, but is created automatically -by Terraform as a convenience for users who are not using the workspaces -feature. - -Create a workspace corresponding to each key given in the `workspace_iam_roles` -variable value above: - -``` -$ terraform workspace new staging -Created and switched to workspace "staging"! - -... - -$ terraform workspace new production -Created and switched to workspace "production"! - -... -``` - -Due to the `assume_role` setting in the AWS provider configuration, any -management operations for AWS resources will be performed via the configured -role in the appropriate environment AWS account. The backend operations, such -as reading and writing the state from S3, will be performed directly as the -administrator's own user within the administrative account. - -``` -$ terraform workspace select staging -$ terraform apply -... -``` - -### Running Terraform in Amazon EC2 - -Teams that make extensive use of Terraform for infrastructure management -often [run Terraform in automation](/terraform/tutorials/automation/automate-terraform?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) -to ensure a consistent operating environment and to limit access to the -various secrets and other sensitive information that Terraform configurations -tend to require. - -When running Terraform in an automation tool running on an Amazon EC2 instance, -consider running this instance in the administrative account and using an -[instance profile](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html) -in place of the various administrator IAM users suggested above. An IAM -instance profile can also be granted cross-account delegation access via -an IAM policy, giving this instance the access it needs to run Terraform. - -To isolate access to different environment accounts, use a separate EC2 -instance for each target account so that its access can be limited only to -the single account. - -Similar approaches can be taken with equivalent features in other AWS compute -services, such as ECS. - -### Protecting Access to Workspace State - -In a simple implementation of the pattern described earlier, -all users can read and write states for all workspaces. -In many cases, it is desirable to apply precise access controls -to the Terraform state objects stored in S3. For example, only -trusted administrators should modify the production state. -It is also important to control access to _reading_ the state file. -If state locking is enabled, the lock file (`.tflock`) -must also be included in the access controls. - -Amazon S3 supports fine-grained access control on a per-object-path basis -using IAM policy. A full description of S3's access control mechanism is -beyond the scope of this guide, but an example IAM policy granting access -to only a single state object within an S3 bucket is shown below: - -```json -{ - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:ListBucket", - "Resource": "arn:aws:s3:::example-bucket", - "Condition": { - "StringEquals": { - "s3:prefix": "path/to/state" - } - } - }, - { - "Effect": "Allow", - "Action": ["s3:GetObject", "s3:PutObject"], - "Resource": [ - "arn:aws:s3:::example-bucket/myapp/production/tfstate", - ] - }, - { - "Effect": "Allow", - "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"], - "Resource": [ - "arn:aws:s3:::example-bucket/myapp/production/tfstate.tflock" - ] - } - ] -} -``` - -The example backend configuration below documents the corresponding `bucket`, `key` and `use_lockfile` arguments: - -```hcl -terraform { - backend "s3" { - bucket = "example-bucket" - key = "path/to/state" - use_lockfile = true - region = "us-east-1" - } -} -``` -Refer to the [AWS documentation on S3 access control](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-access-control.html) for more details. - -### Configuring Custom User-Agent Information - -Note this feature is optional and only available in Terraform v0.13.1+. - -By default, the underlying AWS client used by the Terraform AWS Provider creates requests with User-Agent headers including information about Terraform and AWS Go SDK versions. To provide additional information in the User-Agent headers, the `TF_APPEND_USER_AGENT` environment variable can be set and its value will be directly added to HTTP requests. e.g. - -```sh -$ export TF_APPEND_USER_AGENT="JenkinsAgent/i-12345678 BuildID/1234 (Optional Extra Information)" -``` - -## Support for "S3 Compatible" Storage Providers - -Support for S3 Compatible storage providers is offered as “best effort”. -HashiCorp only tests the `s3` backend against Amazon S3, so cannot offer any guarantees when using an alternate provider. diff --git a/website/docs/language/checks/index.mdx b/website/docs/language/checks/index.mdx deleted file mode 100644 index 926409128f..0000000000 --- a/website/docs/language/checks/index.mdx +++ /dev/null @@ -1,127 +0,0 @@ ---- -page_title: Checks - Configuration Language -description: >- - Check customized infrastructure requirements to provide ongoing and continuous verification. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Checks - --> **Note:** Check blocks are only available in Terraform v1.5.0 and later. - -The `check` block can validate your infrastructure outside the usual resource lifecycle. Check blocks address a gap between post-apply and functional validation of infrastructure. - -> **Hands-on:** Try the [Validate Infrastructure Using Checks](/terraform/tutorials/configuration-language/checks) tutorial. - -Check blocks allow you to define [custom conditions](/terraform/language/expressions/custom-conditions) that execute on every Terraform plan or apply operation without affecting the overall status of an operation. Check blocks execute as the last step of a plan or apply after Terraform has planned or provisioned your infrastructure. - -## Syntax - -You can declare a `check` block with a local name, zero-to-one scoped [data sources](#scoped-data-sources), and one-to-many [assertions](#assertions). - -The following example loads the Terraform website and validates that it returns the expected status code `200`. - -```hcl -check "health_check" { - data "http" "terraform_io" { - url = "https://www.terraform.io" - } - - assert { - condition = data.http.terraform_io.status_code == 200 - error_message = "${data.http.terraform_io.url} returned an unhealthy status code" - } -} -``` - -### Scoped data sources - -You can use any data source from any provider as a scoped data source within a `check` block. - -A `check` block can optionally contain a nested (a.k.a. scoped) data source. This `data` block behaves like an external [data source](/terraform/language/data-sources), except you can not reference it outside its enclosing `check` block. Additionally, if a scoped data source's provider raises any errors, they are masked as warnings and do not prevent Terraform from continuing operation execution. - -You can use a scoped data source to validate the status of a piece of infrastructure outside of the usual Terraform resource lifecycle. [In the above example](#checks-syntax), if the `terraform_io` data source fails to load, you receive a warning instead of a blocking error, which would occur if you declared this data source outside of a `check` block. - -#### Meta-Arguments - -Scoped data sources support the `depends_on` and `provider` [meta-arguments](/terraform/language/resources/syntax#meta-arguments). Scoped data sources do not support the `count` or`for_each` meta-arguments. - -##### `depends_on` - -The `depends_on` meta-argument can be particularly powerful when used within scoped data sources. - -The first time Terraform creates the _initial_ plan for our [previous example](#checks-syntax), the plan fails because Terraform has not applied its configuration yet. Meaning this test fails because Terraform must still create the resources to make this website exist. Therefore, the first time Terraform runs this check, it always throws a potentially distracting error message. - -You can fix this by adding [`depends_on`](/terraform/language/meta-arguments/depends_on) to your scoped data source, ensuring it depends on an essential piece of your site's infrastructure, such as the load balancer. The check returns `known after apply` until that crucial piece of your website is ready. This strategy avoids producing unnecessary warnings during setup, and the check executes during subsequent plans and applies. - -One problem with this strategy is that if the resource your scoped data source `depends_on` changes, the check block returns `known after apply` until Terraform has updated that resource. Depending on your use case, this behavior could be acceptable or problematic. - -We recommend implementing the `depends_on` meta-argument if your scoped data source depends on the existence of another resource without referencing it directly. - -### Assertions - -Check blocks validate your custom assertions using `assert` blocks. Each `check` block must have at least one, but potentially many, `assert` blocks. Each `assert` block has a [`condition` attribute](/terraform/language/expressions/custom-conditions#condition-expressions) and an [`error_message` attribute](/terraform/language/expressions/custom-conditions#error-messages). - -Unlike other [custom conditions](/terraform/language/expressions/custom-conditions), assertions do not affect Terraform's execution of an operation. A failed assertion reports a warning without halting the ongoing operation. This contrasts with other custom conditions, such as a postcondition, where Terraform produces an error immediately, halting the operation and blocking the application or planning of future resources. - -Condition arguments within `assert` blocks can refer to scoped data sources within the enclosing `check` block and any variables, resources, data sources, or module outputs within the current module. - -[Learn more about assertions](/terraform/language/expressions/custom-conditions#checks-with-assertions). - -### Meta-Arguments - -Check blocks do not currently support [meta-arguments](/terraform/language/resources/syntax#meta-arguments). We are still collecting feedback on this feature, so if your use case would benefit from check blocks supporting meta-arguments, please [let us know](https://github.com/hashicorp/terraform/issues/new/choose). - -## Continuous validation in HCP Terraform - -HCP Terraform can automatically validate whether checks in a workspace’s configuration continue to pass after Terraform provisions new infrastructure. See [Continuous Validation](/terraform/cloud-docs/workspaces/health#continuous-validation) for details. - -## Choosing Checks or other Custom Conditions - -Check blocks offer the most _flexible_ validation solution within Terraform. You can reference outputs, variables, resources, and data sources within check assertions. You can also use checks to model every alternate [Custom Condition](/terraform/language/expressions/custom-conditions). However, that does not mean you should replace all your custom conditions with check blocks. - -There are major behavioral differences between check block assertions and other custom conditions, the main one being that check blocks do _not_ affect Terraform's execution of an operation. You can use this non-blocking behavior to decide the best type of validation for your use case. - -### Outputs and variables - -[Output preconditions](/terraform/language/expressions/custom-conditions#outputs) and [variable validations](/terraform/language/expressions/custom-conditions#input-variable-validation) both make assertions around inputs and outputs. - -This is one of the cases where you might want Terraform to block further execution. - -For example, it is not helpful for Terraform to warn that an input variable is invalid after it applies an entire configuration with that input variable. In this case, a check block would warn of the invalid input variable _without_ interrupting the operation. A validation block for the same input variable would alert you of the invalid variable and halt the plan or apply operation. - -### Resource Preconditions and Postconditions - -The difference between [preconditions and postconditions](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions) and check blocks is more nuanced. - -Preconditions are unique amongst the custom conditions in that they execute _before_ a resource change is applied or planned. [Choosing Between Preconditions and Postconditions](/terraform/language/expressions/custom-conditions#choosing-between-preconditions-and-postconditions) offers guidance on choosing between a precondition and a postcondition, and the same topics also apply to choosing between a precondition and a check block. - -You can often use postconditions interchangeably with check blocks to validate resources and data sources. - -For example, you can [rewrite the above `check` block example](#syntax) to use a postcondition instead. The below code uses a `postcondition` block to validate that the Terraform website returns the expected status code of `200`. - -```hcl -data "http" "terraform_io" { - url = "https://www.terraform.io" - - lifecycle { - postcondition { - condition = self.status_code == 200 - error_message = "${self.url} returned an unhealthy status code" - } - } -} -``` - -Both the `check` and `postcondition` block examples validate that the Terraform website returns a `200` status code during a plan or an apply operation. The difference between the two blocks is how each handles failure. - -If a `postcondition` block fails, it _blocks_ Terraform from executing the current operation. If a `check` block fails, it _does not_ block Terraform from executing an operation. - -If the above example's postcondition fails, it is impossible to recover from. Terraform blocks any future plan or apply operations if your postcondition is unsatisfied during the planning stage. This problem occurs because the postcondition does not directly depend on Terraform configuration, but instead on the complex interactions between multiple resources. - -We recommend using check blocks to validate the status of infrastructure as a whole. We only recommend using postconditions when you want a guarantee on a single resource based on that resource's configuration. diff --git a/website/docs/language/data-sources/index.mdx b/website/docs/language/data-sources/index.mdx deleted file mode 100644 index 96a00e2c62..0000000000 --- a/website/docs/language/data-sources/index.mdx +++ /dev/null @@ -1,268 +0,0 @@ ---- -page_title: Data Sources - Configuration Language -description: >- - Data sources allow Terraform to use external data, function output, and data - from other configurations. Learn data resource arguments, behavior, and - lifecycle. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Data Sources - -_Data sources_ allow Terraform to use information defined outside of Terraform, -defined by another separate Terraform configuration, or modified by functions. - -> **Hands-on:** Try the [Query Data Sources](/terraform/tutorials/configuration-language/data-sources) tutorial. - -Each [provider](/terraform/language/providers) may offer data sources -alongside its set of [resource](/terraform/language/resources) -types. - -## Using Data Sources - -A data source is accessed via a special kind of resource known as a -_data resource_, declared using a `data` block: - -```hcl -data "aws_ami" "example" { - most_recent = true - - owners = ["self"] - tags = { - Name = "app-server" - Tested = "true" - } -} -``` - -A `data` block requests that Terraform read from a given data source ("aws_ami") -and export the result under the given local name ("example"). The name is used -to refer to this resource from elsewhere in the same Terraform module, but has -no significance outside of the scope of a module. - -The data source and name together serve as an identifier for a given -resource and so must be unique within a module. - -Within the block body (between `{` and `}`) are query constraints defined by -the data source. Most arguments in this section depend on the -data source, and indeed in this example `most_recent`, `owners` and `tags` are -all arguments defined specifically for [the `aws_ami` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami). - -When distinguishing from data resources, the primary kind of resource (as declared -by a `resource` block) is known as a _managed resource_. Both kinds of resources -take arguments and export attributes for use in configuration, but while -managed resources cause Terraform to create, update, and delete infrastructure -objects, data resources cause Terraform only to _read_ objects. For brevity, -managed resources are often referred to just as "resources" when the meaning -is clear from context. - -## Data Source Arguments - -Each data resource is associated with a single data source, which determines -the kind of object (or objects) it reads and what query constraint arguments -are available. - -Each data source in turn belongs to a [provider](/terraform/language/providers), -which is a plugin for Terraform that offers a collection of resource types and -data sources that most often belong to a single cloud or on-premises -infrastructure platform. - -Most of the items within the body of a `data` block are defined by and -specific to the selected data source, and these arguments can make full -use of [expressions](/terraform/language/expressions) and other dynamic -Terraform language features. - -However, there are some "meta-arguments" that are defined by Terraform itself -and apply across all data sources. These arguments often have additional -restrictions on what language features can be used with them, and are described -in more detail in the following sections. - -## Data Resource Behavior - -Terraform reads data resources during the planning phase when possible, but -announces in the plan when it must defer reading resources until the apply -phase to preserve the order of operations. Terraform defers reading data -resources in the following situations: -* At least one of the given arguments is a managed resource attribute or - other value that Terraform cannot predict until the apply step. -* The data resource depends directly on a managed resource that itself has - planned changes in the current plan. -* The data resource has - [custom conditions](#custom-condition-checks) - and it depends directly or indirectly on a managed resource that itself - has planned changes in the current plan. - -Refer to [Data Resource Dependencies](#data-resource-dependencies) for details -on what it means for a data resource to depend on other objects. Any resulting -attribute of such a data resource will be unknown during planning, so it cannot -be used in situations where values must be fully known. - -## Local-only Data Sources - -While many data sources correspond to an infrastructure object type that -is accessed via a remote network API, some specialized data sources operate -only within Terraform itself, calculating some results and exposing them -for use elsewhere. - -For example, local-only data sources exist for -[rendering templates](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file), -[reading local files](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file), and -[rendering AWS IAM policies](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document). - -The behavior of local-only data sources is the same as all other data -sources, but their result data exists only temporarily during a Terraform -operation, and is re-calculated each time a new plan is created. - -## Data Resource Dependencies - -Data resources have the same dependency resolution behavior -[as defined for managed resources](/terraform/language/resources/behavior#resource-dependencies). -Setting the `depends_on` meta-argument within `data` blocks defers reading of -the data source until after all changes to the dependencies have been applied. - -In order to ensure that data sources are accessing the most up to date -information possible in a wide variety of use cases, arguments directly -referencing managed resources are treated the same as if the resource was -listed in `depends_on`. This behavior can be avoided when desired by indirectly -referencing the managed resource values through a `local` value, unless the -data resource itself has -[custom conditions](#custom-condition-checks). - -~> **NOTE:** **In Terraform 0.12 and earlier**, due to the data resource behavior of deferring the read until the apply phase when depending on values that are not yet known, using `depends_on` with `data` resources will force the read to always be deferred to the apply phase, and therefore a configuration that uses `depends_on` with a `data` resource can never converge. Due to this behavior, we do not recommend using `depends_on` with data resources. - -## Custom Condition Checks - -You can use `precondition` and `postcondition` blocks to specify assumptions and guarantees about how the data source operates. The following examples creates a postcondition that checks whether the AMI has the correct tags. - -``` hcl -data "aws_ami" "example" { - id = var.aws_ami_id - - lifecycle { - # The AMI ID must refer to an existing AMI that has the tag "nomad-server". - postcondition { - condition = self.tags["Component"] == "nomad-server" - error_message = "tags[\"Component\"] must be \"nomad-server\"." - } - } -} -``` - -Custom conditions can help capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations. - -Refer to [Custom Condition Checks](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions) for more details. - - -## Multiple Resource Instances - -Data resources support [`count`](/terraform/language/meta-arguments/count) -and [`for_each`](/terraform/language/meta-arguments/for_each) -meta-arguments as defined for managed resources, with the same syntax and behavior. - -As with managed resources, when `count` or `for_each` is present it is important to -distinguish the resource itself from the multiple resource _instances_ it -creates. Each instance will separately read from its data source with its -own variant of the constraint arguments, producing an indexed result. - -## Selecting a Non-default Provider Configuration - -Data resources support [the `provider` meta-argument](/terraform/language/meta-arguments/resource-provider) -as defined for managed resources, with the same syntax and behavior. - -## Lifecycle Customizations - -Data resources do not have any customization settings available -for their lifecycle. Only the `precondition` and `postcondition` -blocks are allowed in the data resource `lifecycle` block. - -Refer to [Custom Condition Checks](#custom-condition-checks) for more details. - -## Example - -A data source configuration looks like the following: - -```hcl -# Find the latest available AMI that is tagged with Component = web -data "aws_ami" "web" { - filter { - name = "state" - values = ["available"] - } - - filter { - name = "tag:Component" - values = ["web"] - } - - most_recent = true -} -``` - -## Description - -The `data` block creates a data instance of the given _type_ (first -block label) and _name_ (second block label). The combination of the type -and name must be unique. - -Within the block (the `{ }`) is configuration for the data instance. The -configuration is dependent on the type; as with -[resources](/terraform/language/resources), each provider on the -[Terraform Registry](https://registry.terraform.io/browse/providers) has its own -documentation for configuring and using the data types it provides. - -Each data instance will export one or more attributes, which can be -used in other resources as reference expressions of the form -`data...`. For example: - -```hcl -resource "aws_instance" "web" { - ami = data.aws_ami.web.id - instance_type = "t1.micro" -} -``` - -## Meta-Arguments - -As data sources are essentially a read only subset of resources, they also -support the same [meta-arguments](/terraform/language/resources/syntax#meta-arguments) of resources -with the exception of the -[`lifecycle` configuration block](/terraform/language/meta-arguments/lifecycle). - -### Non-Default Provider Configurations - -Similarly to [resources](/terraform/language/resources), when -a module has multiple configurations for the same provider you can specify which -configuration to use with the `provider` meta-argument: - -```hcl -data "aws_ami" "web" { - provider = aws.west - - # ... -} -``` - -See -[The Resource `provider` Meta-Argument](/terraform/language/meta-arguments/resource-provider) -for more information. - -## Data Source Lifecycle - -If the arguments of a data instance contain no references to computed values, -such as attributes of resources that have not yet been created, then the -data instance will be read and its state updated during Terraform's "refresh" -phase, which by default runs prior to creating a plan. This ensures that the -retrieved data is available for use during planning and the diff will show -the real values obtained. - -Data instance arguments may refer to computed values, in which case the -attributes of the instance itself cannot be resolved until all of its -arguments are defined. In this case, refreshing the data instance will be -deferred until the "apply" phase, and all interpolations of the data instance -attributes will show as "computed" in the plan since the values are not yet -known. diff --git a/website/docs/language/expressions/conditionals.mdx b/website/docs/language/expressions/conditionals.mdx deleted file mode 100644 index d401ac4edf..0000000000 --- a/website/docs/language/expressions/conditionals.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -page_title: Conditional Expressions - Configuration Language -description: >- - Conditional expressions select one of two values. You can use them to define - defaults to replace invalid values. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Conditional Expressions - -A _conditional expression_ uses the value of a boolean expression to select one of -two values. - -> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -## Syntax - -The syntax of a conditional expression is as follows: - -```hcl -condition ? true_val : false_val -``` - -If `condition` is `true` then the result is `true_val`. If `condition` is -`false` then the result is `false_val`. - -A common use of conditional expressions is to define defaults to replace -invalid values: - -```hcl -var.a == "" ? "default-a" : var.a -``` - -If `var.a` is an empty string then the result is `"default-a"`, but otherwise -it is the actual value of `var.a`. - -## Conditions - -The condition can be any expression that resolves to a boolean value. This will -usually be an expression that uses the equality, comparison, or logical -operators. - -### Custom Condition Checks - -You can create conditions that produce custom error messages for several types of objects in a configuration. For example, you can add a condition to an input variable that checks whether incoming image IDs are formatted properly. - -Custom conditions can help capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations. - -Refer to [Custom Condition Checks](/terraform/language/expressions/custom-conditions#input-variable-validation) for details. - -## Result Types - -The two result values may be of any type, but they must both -be of the _same_ type so that Terraform can determine what type the whole -conditional expression will return without knowing the condition value. - -If the two result expressions don't produce the same type then Terraform will -attempt to find a type that they can both convert to, and make those -conversions automatically if so. - -For example, the following expression is valid and will always return a string, -because in Terraform all numbers can convert automatically to a string using -decimal digits: - -```hcl -var.example ? 12 : "hello" -``` - -Relying on this automatic conversion behavior can be confusing for those who -are not familiar with Terraform's conversion rules though, so we recommend -being explicit using type conversion functions in any situation where there may -be some uncertainty about the expected result type. - -The following example is contrived because it would be easier to write the -constant `"12"` instead of the type conversion in this case, but shows how to -use [`tostring`](/terraform/language/functions/tostring) to explicitly convert a number to -a string. - -```hcl -var.example ? tostring(12) : "hello" -``` diff --git a/website/docs/language/expressions/custom-conditions.mdx b/website/docs/language/expressions/custom-conditions.mdx deleted file mode 100644 index 907059c8ed..0000000000 --- a/website/docs/language/expressions/custom-conditions.mdx +++ /dev/null @@ -1,420 +0,0 @@ ---- -page_title: Custom Conditions - Configuration Language -description: >- - Check custom requirements for variables, outputs, data sources, and resources and provide better error messages in context. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Custom Conditions - -You can create conditions that produce custom error messages for several types of objects in a configuration. For example, you can add a condition to an input variable that checks whether incoming image IDs are formatted properly. Custom conditions can capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations. - -> **Hands On:** Try the [Validate Infrastructure Using Checks](/terraform/tutorials/configuration-language/checks) tutorial to learn how to use `check` blocks. Try the [Validate Modules with Custom Conditions](/terraform/tutorials/configuration-language/custom-conditions) tutorial to learn how to use other custom conditions. - -This page explains the following: - - Creating checks with [assertions](#checks-with-assertions) to verify your infrastructure as a whole (Terraform v1.5.0 and later) - - Creating [validation conditions](#input-variable-validation) for input variables (Terraform v0.13.0 and later) - - Creating [preconditions and postconditions](#preconditions-and-postconditions) for resources, data sources, and outputs (Terraform v1.2.0 and later) - - Writing effective [condition expressions](#condition-expressions) and [error messages](#error-messages) - - When Terraform [evaluates custom conditions](#conditions-checked-only-during-apply) during the plan and apply cycle - -## Selecting a Custom Condition for your use case - -Terraform's different custom conditions are best suited to various situations. Use the following broad guidelines to select the best custom condition for your use case: -1. [Check blocks with assertions](#checks-with-assertions) validate your infrastructure as a whole. Additionally, check blocks do not prevent or block the overall execution of Terraform operations. -1. [Validation conditions](#input-variable-validation) or [output postconditions](#preconditions-and-postconditions) can ensure your configuration's inputs and outputs meet specific requirements. -1. Resource [preconditions and postconditions](#preconditions-and-postconditions) can validate that Terraform produces your configuration with predictable results. - -For more information on when to use certain custom conditions, see [Choosing Between Preconditions and Postconditions](#choosing-between-preconditions-and-postconditions) and [Choosing Checks or Other Custom Conditions](/terraform/language/checks#choosing-checks-or-other-custom-conditions). - - -## Input Variable Validation - --> **Note:** Input variable validation is available in Terraform v0.13.0 and later. Before Terraform v1.9.0, validation rules can refer only to the variable being validated, and not to any other variables. - -Add one or more `validation` blocks within the `variable` block to specify custom conditions. Each validation requires a [`condition` argument](#condition-expressions), an expression that must use the value of the variable to return `true` if the value is valid, or `false` if it is invalid. The expression must not cause errors directly itself. - -If the condition evaluates to `false`, Terraform produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple validations, Terraform returns error messages for all failed conditions. - -The following example checks whether the AMI ID has valid syntax. - -```hcl -variable "image_id" { - type = string - description = "The id of the machine image (AMI) to use for the server." - - validation { - condition = length(var.image_id) > 4 && substr(var.image_id, 0, 4) == "ami-" - error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"." - } -} -``` - -If the failure of an expression determines the validation decision, use the [`can` function](/terraform/language/functions/can) as demonstrated in the following example. - -```hcl -variable "image_id" { - type = string - description = "The id of the machine image (AMI) to use for the server." - - validation { - # regex(...) fails if it cannot find a match - condition = can(regex("^ami-", var.image_id)) - error_message = "The image_id value must be a valid AMI id, starting with \"ami-\"." - } -} -``` - - -## Preconditions and Postconditions - --> **Note:** Preconditions and postconditions are available in Terraform v1.2.0 and later. - -Use `precondition` and `postcondition` blocks to create custom rules for resources, data sources, and outputs. - -Terraform checks a precondition _before_ evaluating the object it is associated with and checks a postcondition _after_ evaluating the object. Terraform evaluates custom conditions as early as possible, but must defer conditions that depend on unknown values until the apply phase. Refer to [Conditions Checked Only During Apply](#conditions-checked-only-during-apply) for more details. - -### Usage - -Each precondition and postcondition requires a [`condition` argument](#condition-expressions). This is an expression that must return `true` if the conditition is fufilled or `false` if it is invalid. The expression can refer to any other objects in the same module, as long as the references do not create cyclic dependencies. Resource postconditions can also use the [`self` object](#self-object) to refer to attributes of each instance of the resource where they are configured. - -If the condition evaluates to `false`, Terraform will produce an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple preconditions or postconditions, Terraform returns error messages for all failed conditions. - -The following example uses a postcondition to detect if the caller accidentally provided an AMI intended for the wrong system component. - -```hcl -data "aws_ami" "example" { - id = var.aws_ami_id - - lifecycle { - # The AMI ID must refer to an existing AMI that has the tag "nomad-server". - postcondition { - condition = self.tags["Component"] == "nomad-server" - error_message = "tags[\"Component\"] must be \"nomad-server\"." - } - } -} -``` - -#### Resources and Data Sources - -The `lifecycle` block inside a `resource` or `data` block can include both `precondition` and `postcondition` blocks. - -- Terraform evaluates `precondition` blocks after evaluating existing `count` and `for_each` arguments. This lets Terraform evaluate the precondition separately for each instance and then make `each.key`, `count.index`, etc. available to those conditions. Terraform also evaluates preconditions before evaluating the resource's configuration arguments. Preconditions can take precedence over argument evaluation errors. -- Terraform evaluates `postcondition` blocks after planning and applying changes to a managed resource, or after reading from a data source. Postcondition failures prevent changes to other resources that depend on the failing resource. - -In most cases, we do not recommend including both a `data` block and a `resource` block that both represent the same object in the same configuration. Doing so can prevent Terraform from understanding that the `data` block result can be affected by changes in the `resource` block. However, when you need to check a result of a `resource` block that the resource itself does not directly export, you can use a `data` block to check that object safely as long as you place the check as a direct `postcondition` of the `data` block. This tells Terraform that the `data` block is serving as a check of an object defined elsewhere, allowing Terraform to perform actions in the correct order. - -#### Outputs - -An `output` block can include a `precondition` block. - -Preconditions can serve a symmetrical purpose to input variable `validation` blocks. Whereas input variable validation checks assumptions the module makes about its inputs, preconditions check guarantees that the module makes about its outputs. You can use preconditions to prevent Terraform from saving an invalid new output value in the state. You can also use them to preserve a valid output value from the previous apply, if applicable. - -Terraform evaluates output value preconditions before evaluating the `value` expression to finalize the result. Preconditions can take precedence over potential errors in the `value` expression. - -### Examples - -The following example shows use cases for preconditions and postconditions. The preconditions and postconditions declare the following assumptions and guarantees. - -- **The AMI ID must refer to an AMI that contains an operating system for the -`x86_64` architecture.** The precondition would detect if the caller accidentally built an AMI for a different architecture, which may not be able to run the software this virtual machine is intended to host. - -- **The EC2 instance must be allocated a public DNS hostname.** In Amazon Web Services, EC2 instances are assigned public DNS hostnames only if they belong to a virtual network configured in a certain way. The postcondition would detect if the selected virtual network is not configured correctly, prompting the user to debug the network settings. - -- **The EC2 instance will have an encrypted root volume.** The postcondition ensures that the root volume is encrypted, even though the software running in this EC2 instance would probably still operate as expected on an unencrypted volume. This lets Terraform produce an error immediately, before any other components rely on the new EC2 instance. - -```hcl - -data "aws_ami" "example" { - owners = ["amazon"] - - filter { - name = "image-id" - values = ["ami-abc123"] - } -} - -resource "aws_instance" "example" { - instance_type = "t3.micro" - ami = data.aws_ami.example.id - - lifecycle { - # The AMI ID must refer to an AMI that contains an operating system - # for the `x86_64` architecture. - precondition { - condition = data.aws_ami.example.architecture == "x86_64" - error_message = "The selected AMI must be for the x86_64 architecture." - } - - # The EC2 instance must be allocated a public DNS hostname. - postcondition { - condition = self.public_dns != "" - error_message = "EC2 instance must be in a VPC that has public DNS hostnames enabled." - } - } -} - -data "aws_ebs_volume" "example" { - # Use data resources that refer to other resources to - # load extra data that isn't directly exported by a resource. - # - # Read the details about the root storage volume for the EC2 instance - # declared by aws_instance.example, using the exported ID. - - filter { - name = "volume-id" - values = [aws_instance.example.root_block_device[0].volume_id] - } - - # Whenever a data resource is verifying the result of a managed resource - # declared in the same configuration, you MUST write the checks as - # postconditions of the data resource. This ensures Terraform will wait - # to read the data resource until after any changes to the managed resource - # have completed. - lifecycle { - # The EC2 instance will have an encrypted root volume. - postcondition { - condition = self.encrypted - error_message = "The server's root volume is not encrypted." - } - } -} - -output "api_base_url" { - value = "https://${aws_instance.example.private_dns}:8433/" -} -``` - -### Choosing Between Preconditions and Postconditions - -You can often implement a validation check as either a postcondition of the resource producing the data or as a precondition of a resource or output value using the data. To decide which is most appropriate, consider whether the check is representing either an assumption or a guarantee. - -#### Use Preconditions for Assumptions - -An assumption is a condition that must be true in order for the configuration of a particular resource to be usable. For example, an `aws_instance` configuration can have the assumption that the given AMI will always be configured for the `x86_64` CPU architecture. - -We recommend using preconditions for assumptions, so that future maintainers can find them close to the other expressions that rely on that condition. This lets them understand more about what that resource is intended to allow. - -#### Use Postconditions for Guarantees - -A guarantee is a characteristic or behavior of an object that the rest of the configuration should be able to rely on. For example, an `aws_instance` configuration can have the guarantee that an EC2 instance will be running in a network that assigns it a private DNS record. - -We recommend using postconditions for guarantees, so that future maintainers can find them close to the resource configuration that is responsible for implementing those guarantees. This lets them more easily determine which behaviors they should preserve when changing the configuration. - -#### Additional Decision Factors - -You should also consider the following questions when creating preconditions and postconditions. - -- Which resource or output value would be most helpful to report in the error message? Terraform will always report errors in the location where the condition was declared. -- Which approach is more convenient? If a particular resource has many dependencies that all make an assumption about that resource, it can be pragmatic to declare that once as a post-condition of the resource, rather than declaring it many times as preconditions on each of the dependencies. -- Is it helpful to declare the same or similar conditions as both preconditions and postconditions? This can be useful if the postcondition is in a different module than the precondition because it lets the modules verify one another as they evolve independently. - -## Checks with Assertions - --> **Note:** Check blocks and their assertions are only available in Terraform v1.5.0 and later. - -[Check blocks](/terraform/language/checks) can validate your infrastructure outside the usual resource lifecycle. You can add custom conditions via `assert` blocks, which execute at the end of the plan and apply stages and produce warnings to notify you of problems within your infrastructure. - -You can add one or more `assert` blocks within a `check` block to verify custom conditions. Each assertion requires a [`condition` argument](#condition-expressions), a boolean expression that should return `true` if the intended assumption or guarantee is fulfilled or `false` if it does not. Your `condition` expression can refer to any resource, data source, or variable available to the surrounding `check` block. - -The following example uses a check block with an assertion to verify the Terraform website is healthy. - -```hcl -check "health_check" { - data "http" "terraform_io" { - url = "https://www.terraform.io" - } - - assert { - condition = data.http.terraform_io.status_code == 200 - error_message = "${data.http.terraform_io.url} returned an unhealthy status code" - } -} -``` - -If the condition evaluates to `false`, Terraform produces an [error message](#error-messages) that includes the result of the `error_message` expression. If you declare multiple assertions, Terraform returns error messages for all failed conditions. - -### Continuous Validation in HCP Terraform - -HCP Terraform can automatically check whether the checks in a workspace’s configuration continue to pass after Terraform provisions the infrastructure. For example, you can write a `check` to continuously monitor the validity of an API gateway certificate. Continuous validation alerts you when the condition fails, so you can update the certificate and avoid errors the next time you want to update your infrastructure. Refer to [Continuous Validation](/terraform/cloud-docs/workspaces/health#continuous-validation) in the HCP Terraform documentation for details. - -## Condition Expressions - -Check assertions, input variable validation, preconditions, and postconditions all require a `condition` argument. This is a boolean expression that should return `true` if the intended assumption or guarantee is fulfilled or `false` if it does not. - -You can use any of Terraform's built-in functions or language operators -in a condition as long as the expression is valid and returns a boolean result. The following language features are particularly useful when writing condition expressions. - -### Logical Operators - -Use the logical operators `&&` (AND), `||` (OR), and `!` (NOT) to combine multiple conditions together. - -```hcl - condition = var.name != "" && lower(var.name) == var.name -``` - -You can also use arithmetic operators (e.g. `a + b`), equality operators (eg., `a == b`) and comparison operators (e.g., `a < b`). Refer to [Arithmetic and Logical Operators](/terraform/language/expressions/operators) for details. - -### `contains` Function - -Use the [`contains` function](/terraform/language/functions/contains) to test whether a given value is one of a set of predefined valid values. - -```hcl - condition = contains(["STAGE", "PROD"], var.environment) -``` - -### `length` Function - -Use the [`length` function](/terraform/language/functions/length) to test a collection's length and require a non-empty list or map. - -```hcl - condition = length(var.items) != 0 -``` -This is a better approach than directly comparing with another collection using `==` or `!=`. This is because the comparison operators can only return `true` if both operands have exactly the same type, which is often ambiguous for empty collections. - -### `for` Expressions - -Use [`for` expressions](/terraform/language/expressions/for) in conjunction with the functions `alltrue` and `anytrue` to test whether a condition holds for all or for any elements of a collection. - -```hcl - condition = alltrue([ - for v in var.instances : contains(["t2.micro", "m3.medium"], v.type) - ]) -``` - -### `can` Function - -Use the [`can` function](/terraform/language/functions/can) to concisely use the validity of an expression as a condition. It returns `true` if its given expression evaluates successfully and `false` if it returns any error, so you can use various other functions that typically return errors as a part of your condition expressions. - -For example, you can use `can` with `regex` to test if a string matches a particular pattern because `regex` returns an error when given a non-matching string. - -```hcl - condition = can(regex("^[a-z]+$", var.name)) -``` - -You can also use `can` with the type conversion functions to test whether a value is convertible to a type or type constraint. - -```hcl - # This remote output value must have a value that can - # be used as a string, which includes strings themselves - # but also allows numbers and boolean values. - condition = can(tostring(data.terraform_remote_state.example.outputs["name"])) -``` - -```hcl - # This remote output value must be convertible to a list - # type of with element type. - condition = can(tolist(data.terraform_remote_state.example.outputs["items"])) -``` - -You can also use `can` with attribute access or index operators to test whether a collection or structural value has a particular element or index. - -```hcl - # var.example must have an attribute named "foo" - condition = can(var.example.foo) -``` - -```hcl - # var.example must be a sequence with at least one element - condition = can(var.example[0]) - # (although it would typically be clearer to write this as a - # test like length(var.example) > 0 to better represent the - # intent of the condition.) -``` - -### `self` Object - -Use the `self` object in postcondition blocks to refer to attributes of the instance under evaluation. - -```hcl -resource "aws_instance" "example" { - instance_type = "t2.micro" - ami = "ami-abc123" - - lifecycle { - postcondition { - condition = self.instance_state == "running" - error_message = "EC2 instance must be running." - } - } -} -``` - -### `each` and `count` Objects - -In blocks where [`for_each`](/terraform/language/meta-arguments/for_each) or [`count`](/terraform/language/meta-arguments/count) are set, use `each` and `count` objects to refer to other resources that are expanded in a chain. - -```hcl -variable "vpc_cidrs" { - type = set(string) -} - -data "aws_vpc" "example" { - for_each = var.vpc_cidrs - - filter { - name = "cidr" - values = [each.key] - } -} - -resource "aws_internet_gateway" "example" { - for_each = data.aws_vpc.example - vpc_id = each.value.id - - lifecycle { - precondition { - condition = data.aws_vpc.example[each.key].state == "available" - error_message = "VPC ${each.key} must be available." - } - } -} -``` - -## Error Messages - -Input variable validations, preconditions, and postconditions all must include the `error_message` argument. This contains the text that Terraform will include as part of error messages when it detects an unmet condition. - -``` -Error: Resource postcondition failed - - with data.aws_ami.example, - on ec2.tf line 19, in data "aws_ami" "example": - 72: condition = self.tags["Component"] == "nomad-server" - |---------------- - | self.tags["Component"] is "consul-server" - -The selected AMI must be tagged with the Component value "nomad-server". -``` - -The `error_message` argument can be any expression that evaluates to a string. -This includes literal strings, heredocs, and template expressions. You can use the [`format` function](/terraform/language/functions/format) to convert items of `null`, `list`, or `map` types into a formatted string. Multi-line -error messages are supported, and lines with leading whitespace will not be -word wrapped. - -We recommend writing error messages as one or more full sentences in a -style similar to Terraform's own error messages. Terraform will show the -message alongside the name of the resource that detected the problem and any -external values included in the condition expression. - -## Conditions Checked Only During Apply - -Terraform evaluates custom conditions as early as possible. - -Input variable validations can only refer to the variable value, so Terraform always evaluates them immediately. Check assertions, preconditions, and postconditions depend on Terraform evaluating whether the value(s) associated with the condition are known before or after applying the configuration. - -- **Known before apply:** Terraform checks the condition during the planning phase. For example, Terraform can know the value of an image ID during planning as long as it is not generated from another resource. -- **Known after apply:** Terraform delays checking that condition until the apply phase. For example, AWS only assigns the root volume ID when it starts an EC2 instance, so Terraform cannot know this value until apply. - -During the apply phase, a failed _precondition_ -will prevent Terraform from implementing planned actions for the associated resource. However, a failed _postcondition_ will halt processing after Terraform has already implemented these actions. The failed postcondition prevents any further downstream actions that rely on the resource, but does not undo the actions Terraform has already taken. - -Terraform typically has less information during the initial creation of a -full configuration than when applying subsequent changes. Therefore, Terraform may check conditions during apply for initial creation and then check them during planning for subsequent updates. - diff --git a/website/docs/language/expressions/dynamic-blocks.mdx b/website/docs/language/expressions/dynamic-blocks.mdx deleted file mode 100644 index 3c9dc3e7a4..0000000000 --- a/website/docs/language/expressions/dynamic-blocks.mdx +++ /dev/null @@ -1,161 +0,0 @@ ---- -page_title: Dynamic Blocks - Configuration Language -description: >- - Dynamic blocks automatically construct multi-level, nested block structures. - Learn to configure dynamic blocks and understand their 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `dynamic` Blocks - -Within top-level block constructs like resources, expressions can usually be -used only when assigning a value to an argument using the `name = expression` -form. This covers many uses, but some resource types include repeatable _nested -blocks_ in their arguments, which typically represent separate objects that -are related to (or embedded within) the containing object: - -```hcl -resource "aws_elastic_beanstalk_environment" "tfenvtest" { - name = "tf-test-name" # can use expressions here - - setting { - # but the "setting" block is always a literal block - } -} -``` - -You can dynamically construct repeatable nested blocks like `setting` using a -special `dynamic` block type, which is supported inside `resource`, `data`, -`provider`, and `provisioner` blocks: - -```hcl -resource "aws_elastic_beanstalk_environment" "tfenvtest" { - name = "tf-test-name" - application = aws_elastic_beanstalk_application.tftest.name - solution_stack_name = "64bit Amazon Linux 2018.03 v2.11.4 running Go 1.12.6" - - dynamic "setting" { - for_each = var.settings - content { - namespace = setting.value["namespace"] - name = setting.value["name"] - value = setting.value["value"] - } - } -} -``` - -A `dynamic` block acts much like a [`for` expression](/terraform/language/expressions/for), but produces -nested blocks instead of a complex typed value. It iterates over a given -complex value, and generates a nested block for each element of that complex -value. - -- The label of the dynamic block (`"setting"` in the example above) specifies - what kind of nested block to generate. -- The `for_each` argument provides the complex value to iterate over. -- The `iterator` argument (optional) sets the name of a temporary variable - that represents the current element of the complex value. If omitted, the name - of the variable defaults to the label of the `dynamic` block (`"setting"` in - the example above). -- The `labels` argument (optional) is a list of strings that specifies the block - labels, in order, to use for each generated block. You can use the temporary - iterator variable in this value. -- The nested `content` block defines the body of each generated block. You can - use the temporary iterator variable inside this block. - -Since the `for_each` argument accepts any collection or structural value, -you can use a `for` expression or splat expression to transform an existing -collection. - -The iterator object (`setting` in the example above) has two attributes: - -- `key` is the map key or list element index for the current element. If the - `for_each` expression produces a _set_ value then `key` is identical to - `value` and should not be used. -- `value` is the value of the current element. - -A `dynamic` block can only generate arguments that belong to the resource type, -data source, provider or provisioner being configured. It is _not_ possible -to generate meta-argument blocks such as `lifecycle` and `provisioner` -blocks, since Terraform must process these before it is safe to evaluate -expressions. - -The `for_each` value must be a collection with one element per desired -nested block. If you need to declare resource instances based on a nested -data structure or combinations of elements from multiple data structures you -can use Terraform expressions and functions to derive a suitable value. -For some common examples of such situations, see the -[`flatten`](/terraform/language/functions/flatten) -and -[`setproduct`](/terraform/language/functions/setproduct) -functions. - -## Multi-level Nested Block Structures - -Some providers define resource types that include multiple levels of blocks -nested inside one another. You can generate these nested structures dynamically -when necessary by nesting `dynamic` blocks in the `content` portion of other -`dynamic` blocks. - -For example, a module might accept a complex data structure like the following: - -```hcl -variable "load_balancer_origin_groups" { - type = map(object({ - origins = set(object({ - hostname = string - })) - })) -} -``` - -If you were defining a resource whose type expects a block for each origin -group and then nested blocks for each origin within a group, you could ask -Terraform to generate that dynamically using the following nested `dynamic` -blocks: - -```hcl - dynamic "origin_group" { - for_each = var.load_balancer_origin_groups - content { - name = origin_group.key - - dynamic "origin" { - for_each = origin_group.value.origins - content { - hostname = origin.value.hostname - } - } - } - } -``` - -When using nested `dynamic` blocks it's particularly important to pay attention -to the iterator symbol for each block. In the above example, -`origin_group.value` refers to the current element of the outer block, while -`origin.value` refers to the current element of the inner block. - -If a particular resource type defines nested blocks that have the same type -name as one of their parents, you can use the `iterator` argument in each of -`dynamic` blocks to choose a different iterator symbol that makes the two -easier to distinguish. - -## Best Practices for `dynamic` Blocks - -Overuse of `dynamic` blocks can make configuration hard to read and maintain, so -we recommend using them only when you need to hide details in order to build a -clean user interface for a re-usable module. Always write nested blocks out -literally where possible. - -If you find yourself defining most or all of a `resource` block's arguments and -nested blocks using directly-corresponding attributes from an input variable -then that might suggest that your module is not creating a useful abstraction. -It may be better for the calling module to define the resource itself then -pass information about it into your module. For more information on this design -tradeoff, see [When to Write a Module](/terraform/language/modules/develop#when-to-write-a-module) -and [Module Composition](/terraform/language/modules/develop/composition). diff --git a/website/docs/language/expressions/for.mdx b/website/docs/language/expressions/for.mdx deleted file mode 100644 index 72d3fc828a..0000000000 --- a/website/docs/language/expressions/for.mdx +++ /dev/null @@ -1,213 +0,0 @@ ---- -page_title: For Expressions - Configuration Language -description: >- - For expressions transform complex input values into complex output values. - Learn how to filter inputs and how to group results. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `for` Expressions - -A _`for` expression_ creates a complex type value by transforming -another complex type value. Each element in the input value -can correspond to either one or zero values in the result, and an arbitrary -expression can be used to transform each input element into an output element. - -For example, if `var.list` were a list of strings, then the following expression -would produce a tuple of strings with all-uppercase letters: - -```hcl -[for s in var.list : upper(s)] -``` - -This `for` expression iterates over each element of `var.list`, and then -evaluates the expression `upper(s)` with `s` set to each respective element. -It then builds a new tuple value with all of the results of executing that -expression in the same order. - -## Input Types - -A `for` expression's input (given after the `in` keyword) can be a list, -a set, a tuple, a map, or an object. - -The above example showed a `for` expression with only a single temporary -symbol `s`, but a `for` expression can optionally declare a pair of temporary -symbols in order to use the key or index of each item too: - -```hcl -[for k, v in var.map : length(k) + length(v)] -``` - -For a map or object type, like above, the `k` symbol refers to the key or -attribute name of the current element. You can also use the two-symbol form -with lists and tuples, in which case the additional symbol is the index -of each element starting from zero, which conventionally has the symbol name -`i` or `idx` unless it's helpful to choose a more specific name: - -```hcl -[for i, v in var.list : "${i} is ${v}"] -``` - -The index or key symbol is always optional. If you specify only a single -symbol after the `for` keyword then that symbol will always represent the -_value_ of each element of the input collection. - -## Result Types - -The type of brackets around the `for` expression decide what type of result -it produces. - -The above example uses `[` and `]`, which produces a tuple. If you use `{` and -`}` instead, the result is an object and you must provide two result -expressions that are separated by the `=>` symbol: - -```hcl -{for s in var.list : s => upper(s)} -``` - -This expression produces an object whose attributes are the original elements -from `var.list` and their corresponding values are the uppercase versions. -For example, the resulting value might be as follows: - -```hcl -{ - foo = "FOO" - bar = "BAR" - baz = "BAZ" -} -``` - -A `for` expression alone can only produce either an object value or a tuple -value, but Terraform's automatic type conversion rules mean that you can -typically use the results in locations where lists, maps, and sets are expected. - -## Filtering Elements - -A `for` expression can also include an optional `if` clause to filter elements -from the source collection, producing a value with fewer elements than -the source value: - -```hcl -[for s in var.list : upper(s) if s != ""] -``` - -One common reason for filtering collections in `for` expressions is to split -a single source collection into two separate collections based on some -criteria. For example, if the input `var.users` is a map of objects where the -objects each have an attribute `is_admin` then you may wish to produce separate -maps with admin vs non-admin objects: - -```hcl -variable "users" { - type = map(object({ - is_admin = bool - })) -} - -locals { - admin_users = { - for name, user in var.users : name => user - if user.is_admin - } - regular_users = { - for name, user in var.users : name => user - if !user.is_admin - } -} -``` - -## Element Ordering - -Because `for` expressions can convert from unordered types (maps, objects, sets) -to ordered types (lists, tuples), Terraform must choose an implied ordering -for the elements of an unordered collection. - -For maps and objects, Terraform sorts the elements by key or attribute name, -using lexical sorting. - -For sets of strings, Terraform sorts the elements by their value, using -lexical sorting. - -For sets of other types, Terraform uses an arbitrary ordering that may change in future versions. We recommend converting the expression result into a set to make it clear elsewhere in the configuration that the result is unordered. You can use [the `toset` function](/terraform/language/functions/toset) -to concisely convert a `for` expression result to be of a set type. - -```hcl -toset([for e in var.set : e.example]) -``` - -## Grouping Results - -If the result type is an object (using `{` and `}` delimiters) then normally -the given key expression must be unique across all elements in the result, -or Terraform will return an error. - -Sometimes the resulting keys are _not_ unique, and so to support that situation -Terraform supports a special _grouping mode_ which changes the result to support -multiple elements per key. - -To activate grouping mode, add the symbol `...` after the value expression. -For example: - -```hcl -variable "users" { - type = map(object({ - role = string - })) -} - -locals { - users_by_role = { - for name, user in var.users : user.role => name... - } -} -``` - -The above represents a situation where a module expects a map describing -various users who each have a single "role", where the map keys are usernames. -The usernames are guaranteed unique because they are map keys in the input, -but many users may all share a single role name. - -The `local.users_by_role` expression inverts the input map so that the keys -are the role names and the values are usernames, but the expression is in -grouping mode (due to the `...` after `name`) and so the result will be a -map of lists of strings, such as the following: - -```hcl -{ - "admin": [ - "ps", - ], - "maintainer": [ - "am", - "jb", - "kl", - "ma", - ], - "viewer": [ - "st", - "zq", - ], -} -``` - -Due to [the element ordering rules](#element-ordering), Terraform will sort -the users lexically by username as part of evaluating the `for` expression, -and so the usernames associated with each role will be lexically sorted -after grouping. - -## Repeated Configuration Blocks - -The `for` expressions mechanism is for constructing collection values from -other collection values within expressions, which you can then assign to -individual resource arguments that expect complex values. - -Some resource types also define _nested block types_, which typically represent -separate objects that belong to the containing resource in some way. You can't -dynamically generate nested blocks using `for` expressions, but you _can_ -generate nested blocks for a resource dynamically using -[`dynamic` blocks](/terraform/language/expressions/dynamic-blocks). diff --git a/website/docs/language/expressions/function-calls.mdx b/website/docs/language/expressions/function-calls.mdx deleted file mode 100644 index 7e0fed8726..0000000000 --- a/website/docs/language/expressions/function-calls.mdx +++ /dev/null @@ -1,120 +0,0 @@ ---- -page_title: Function Calls - Configuration Language -description: >- - Functions transform and combine values. Learn about Terraform's built-in - functions. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Function Calls - -> **Hands-on:** Try the [Perform Dynamic Operations with Functions](/terraform/tutorials/configuration-language/functions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -The Terraform language has a number of -[built-in functions](/terraform/language/functions) that can be used -in expressions to transform and combine values. These -are similar to the operators but all follow a common syntax: - -```hcl -(, ) -``` - -The function name specifies which function to call. Each defined function -expects a specific number of arguments with specific value types, and returns a -specific value type as a result. - -Some functions take an arbitrary number of arguments. For example, the `min` -function takes any amount of number arguments and returns the one that is -numerically smallest: - -```hcl -min(55, 3453, 2) -``` - -A function call expression evaluates to the function's return value. - -## Available Functions - -For a full list of available functions, see -[the function reference](/terraform/language/functions). - -## Expanding Function Arguments - -If the arguments to pass to a function are available in a list or tuple value, -that value can be _expanded_ into separate arguments. Provide the list value as -an argument and follow it with the `...` symbol: - -```hcl -min([55, 2453, 2]...) -``` - -The expansion symbol is three periods (`...`), not a Unicode ellipsis character -(`…`). Expansion is a special syntax that is only available in function calls. - -## Using Sensitive Data as Function Arguments - -When using sensitive data, such as [an input variable](/terraform/language/values/variables#suppressing-values-in-cli-output) -or [an output defined](/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output) as sensitive -as function arguments, the result of the function call will be marked as sensitive. - -This is a conservative behavior that is true irrespective of the function being -called. For example, passing an object containing a sensitive input variable to -the `keys()` function will result in a list that is sensitive: - -```shell -> local.baz -{ - "a" = (sensitive value) - "b" = "dog" -} -> keys(local.baz) -(sensitive value) -``` - -## When Terraform Calls Functions - -Most of Terraform's built-in functions are, in programming language terms, -[pure functions](https://en.wikipedia.org/wiki/Pure_function). This means that -their result is based only on their arguments and so it doesn't make any -practical difference when Terraform would call them. - -However, a small subset of functions interact with outside state and so for -those it can be helpful to know when Terraform will call them in relation to -other events that occur in a Terraform run. - -The small set of special functions includes -[`file`](/terraform/language/functions/file), -[`templatefile`](/terraform/language/functions/templatefile), -[`timestamp`](/terraform/language/functions/timestamp), -and [`uuid`](/terraform/language/functions/uuid). -If you are not working with these functions then you don't need -to read this section, although the information here may still be interesting -background information. - -The `file` and `templatefile` functions are intended for reading files that -are included as a static part of the configuration and so Terraform will -execute these functions as part of initial configuration validation, before -taking any other actions with the configuration. That means you cannot use -either function to read files that your configuration might generate -dynamically on disk as part of the plan or apply steps. - -The `timestamp` function returns a representation of the current system time -at the point when Terraform calls it, and the `uuid` function returns a random -result which differs on each call. Without any special behavior, these would -both cause the final configuration during the apply step not to match the -actions shown in the plan, which violates the Terraform execution model. - -For that reason, Terraform arranges for both of those functions to produce -[unknown value](/terraform/language/expressions/references#values-not-yet-known) results during the -plan step, with the real result being decided only during the apply step. -For `timestamp` in particular, this means that the recorded time will be -the instant when Terraform began applying the change, rather than when -Terraform _planned_ the change. - -For more details on the behavior of these functions, refer to their own -documentation pages. diff --git a/website/docs/language/expressions/index.mdx b/website/docs/language/expressions/index.mdx deleted file mode 100644 index 77bac58ec4..0000000000 --- a/website/docs/language/expressions/index.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -page_title: Expressions - Configuration Language -description: >- - An overview of expressions to reference or compute values in Terraform - configurations, including types, operators, and functions. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Expressions - -> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -_Expressions_ refer to or compute values within a configuration. -The simplest expressions are just literal values, like `"hello"` or `5`, -but the Terraform language also allows more complex expressions such as -references to data exported by resources, arithmetic, conditional evaluation, -and a number of built-in functions. - -Expressions can be used in a number of places in the Terraform language, -but some contexts limit which expression constructs are allowed, -such as requiring a literal value of a particular type or forbidding -[references to resource attributes](/terraform/language/expressions/references#references-to-resource-attributes). -Each language feature's documentation describes any restrictions it places on -expressions. - -You can experiment with the behavior of Terraform's expressions from -the Terraform expression console, by running -[the `terraform console` command](/terraform/cli/commands/console). - -The other pages in this section describe the features of Terraform's -expression syntax. - -- [Types and Values](/terraform/language/expressions/types) - documents the data types that Terraform expressions can resolve to, and the - literal syntaxes for values of those types. - -- [Strings and Templates](/terraform/language/expressions/strings) - documents the syntaxes for string literals, including interpolation sequences - and template directives. - -- [References to Values](/terraform/language/expressions/references) - documents how to refer to named values like variables and resource attributes. - -- [Operators](/terraform/language/expressions/operators) - documents the arithmetic, comparison, and logical operators. - -- [Function Calls](/terraform/language/expressions/function-calls) - documents the syntax for calling Terraform's built-in functions. - -- [Conditional Expressions](/terraform/language/expressions/conditionals) - documents the ` ? : ` expression, which - chooses between two values based on a bool condition. - -- [For Expressions](/terraform/language/expressions/for) - documents expressions like `[for s in var.list : upper(s)]`, which can - transform a complex type value into another complex type value. - -- [Splat Expressions](/terraform/language/expressions/splat) - documents expressions like `var.list[*].id`, which can extract simpler - collections from more complicated expressions. - -- [Dynamic Blocks](/terraform/language/expressions/dynamic-blocks) - documents a way to create multiple repeatable nested blocks within a resource - or other construct. - -- [Custom Conditions](/terraform/language/expressions/custom-conditions) - documents conditions, checks blocks, and resource preconditions and postconditions. - -- [Type Constraints](/terraform/language/expressions/type-constraints) - documents the syntax for referring to a type, rather than a value of that - type. Input variables expect this syntax in their `type` argument. - -- [Version Constraints](/terraform/language/expressions/version-constraints) - documents the syntax of special strings that define a set of allowed software - versions. Terraform uses version constraints in several places. diff --git a/website/docs/language/expressions/operators.mdx b/website/docs/language/expressions/operators.mdx deleted file mode 100644 index 14cd10c765..0000000000 --- a/website/docs/language/expressions/operators.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -page_title: Operators - Configuration Language -description: >- - Operators transform or combine expressions. Learn about arithmetic, logical, - equality, and comparison operators. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Arithmetic and Logical Operators - -An _operator_ is a type of expression that transforms or combines one or more -other expressions. Operators either combine two values in some way to -produce a third result value, or transform a single given value to -produce a single result. - -Operators that work on two values place an operator symbol between the two -values, similar to mathematical notation: `1 + 2`. Operators that work on -only one value place an operator symbol before that value, like -`!true`. - -The Terraform language has a set of operators for both arithmetic and logic, -which are similar to operators in programming languages such as JavaScript -or Ruby. - -When multiple operators are used together in an expression, they are evaluated -in the following order of operations: - -1. `!`, `-` (multiplication by `-1`) -1. `*`, `/`, `%` -1. `+`, `-` (subtraction) -1. `>`, `>=`, `<`, `<=` -1. `==`, `!=` -1. `&&` -1. `||` - -Use parentheses to override the default order of operations. Without -parentheses, higher levels will be evaluated first, so Terraform will interpret -`1 + 2 * 3` as `1 + (2 * 3)` and _not_ as `(1 + 2) * 3`. - -The different operators can be gathered into a few different groups with -similar behavior, as described below. Each group of operators expects its -given values to be of a particular type. Terraform will attempt to convert -values to the required type automatically, or will produce an error message -if automatic conversion is impossible. - -The `?` character combined with the `:` character is part of a conditional expression in Terraform and is not considered an operator. For more information, refer to [Conditional Expressions](/terraform/language/expressions/conditionals#conditional-expressions). - -## Arithmetic Operators - -The arithmetic operators all expect number values and produce number values -as results: - -* `a + b` returns the result of adding `a` and `b` together. -* `a - b` returns the result of subtracting `b` from `a`. -* `a * b` returns the result of multiplying `a` and `b`. -* `a / b` returns the result of dividing `a` by `b`. -* `a % b` returns the remainder of dividing `a` by `b`. This operator is - generally useful only when used with whole numbers. -* `-a` returns the result of multiplying `a` by `-1`. - -Terraform supports some other less-common numeric operations as -[functions](/terraform/language/expressions/function-calls). For example, you can calculate exponents -using -[the `pow` function](/terraform/language/functions/pow). - -## Equality Operators - -The equality operators both take two values of any type and produce boolean -values as results. - -* `a == b` returns `true` if `a` and `b` both have the same type and the same - value, or `false` otherwise. -* `a != b` is the opposite of `a == b`. - -Because the equality operators require both arguments to be of exactly the -same type in order to decide equality, we recommend using these operators only -with values of primitive types or using explicit type conversion functions -to indicate which type you are intending to use for comparison. - -Comparisons between structural types may produce surprising results if you -are not sure about the types of each of the arguments. For example, -`var.list == []` may seem like it would return `true` if `var.list` were an -empty list, but `[]` actually builds a value of type `tuple([])` and so the -two values can never match. In this situation it's often clearer to write -`length(var.list) == 0` instead. - -## Comparison Operators - -The comparison operators all expect number values and produce boolean values -as results. - -* `a < b` returns `true` if `a` is less than `b`, or `false` otherwise. -* `a <= b` returns `true` if `a` is less than or equal to `b`, or `false` - otherwise. -* `a > b` returns `true` if `a` is greater than `b`, or `false` otherwise. -* `a >= b` returns `true` if `a` is greater than or equal to `b`, or `false` otherwise. - -## Logical Operators - -The logical operators all expect bool values and produce bool values as results. - -* `a || b` returns `true` if either `a` or `b` is `true`, or `false` if both are `false`. -* `a && b` returns `true` if both `a` and `b` are `true`, or `false` if either one is `false`. -* `!a` returns `true` if `a` is `false`, and `false` if `a` is `true`. - -Terraform does not have an operator for the "exclusive OR" operation. If you -know that both operators are boolean values then exclusive OR is equivalent -to the `!=` ("not equal") operator. diff --git a/website/docs/language/expressions/references.mdx b/website/docs/language/expressions/references.mdx deleted file mode 100644 index dff7909962..0000000000 --- a/website/docs/language/expressions/references.mdx +++ /dev/null @@ -1,364 +0,0 @@ ---- -page_title: References to Values - Configuration Language -description: >- - Reference values in configurations, including resources, input variables, - local and block-local values, module outputs, data sources, and workspace - 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# References to Named Values - -> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -Terraform makes several kinds of named values available. Each of these names is -an expression that references the associated value. You can use them as -standalone expressions, or combine them with other expressions to compute new -values. - -## Types of Named Values - -The main kinds of named values available in Terraform are: - -* Resources -* Input variables -* Local values -* Child module outputs -* Data sources -* Filesystem and workspace info -* Block-local values - -The sections below explain each kind of named value in detail. - -Although many of these names use dot-separated paths that resemble -[attribute notation](/terraform/language/expressions/types#indices-and-attributes) for elements of object values, they are not -implemented as real objects. This means you must use them exactly as written: -you cannot use square-bracket notation to replace the dot-separated paths, and -you cannot iterate over the "parent object" of a named entity; for example, you -cannot use `aws_instance` in a `for` expression to iterate over every AWS -instance resource. - -### Resources - -`.` represents a [managed resource](/terraform/language/resources) of -the given type and name. - -The value of a resource reference can vary, depending on whether the resource -uses `count` or `for_each`: - -* If the resource doesn't use `count` or `for_each`, the reference's value is an - object. The resource's attributes are elements of the object, and you can - access them using [dot or square bracket notation](/terraform/language/expressions/types#indices-and-attributes). -* If the resource has the `count` argument set, the reference's value is a - _list_ of objects representing its instances. -* If the resource has the `for_each` argument set, the reference's value is a - _map_ of objects representing its instances. - -Any named value that does not match another pattern listed below -will be interpreted by Terraform as a reference to a managed resource. - -For more information about how to use resource references, see -[references to resource attributes](#references-to-resource-attributes) below. - -### Input Variables - -`var.` is the value of the [input variable](/terraform/language/values/variables) of the given name. - -If the variable has a type constraint (`type` argument) as part of its -declaration, Terraform will automatically convert the caller's given value -to conform to the type constraint. - -For that reason, you can safely assume that a reference using `var.` will -always produce a value that conforms to the type constraint, even if the caller -provided a value of a different type that was automatically converted. - -In particular, note that if you define a variable as being of an object type -with particular attributes then only _those specific attributes_ will be -available in expressions elsewhere in the module, even if the caller actually -passed in a value with additional attributes. You must define in the type -constraint all of the attributes you intend to use elsewhere in your module. - -### Local Values - -`local.` is the value of the [local value](/terraform/language/values/locals) of the given name. - -Local values can refer to other local values, even within the same `locals` -block, as long as you don't introduce circular dependencies. - -### Child Module Outputs - -`module.` is an value representing the results of -[a `module` block](/terraform/language/modules/syntax). - -If the corresponding `module` block does not have either `count` nor `for_each` -set then the value will be an object with one attribute for each output value -defined in the child module. To access one of the module's -[output values](/terraform/language/values/outputs), use `module..`. - -If the corresponding `module` uses `for_each` then the value will be a map -of objects whose keys correspond with the keys in the `for_each` expression, -and whose values are each objects with one attribute for each output value -defined in the child module, each representing one module instance. - -If the corresponding module uses `count` then the result is similar to for -`for_each` except that the value is a _list_ with the requested number of -elements, each one representing one module instance. - -### Data Sources - -`data..` is an object representing a -[data resource](/terraform/language/data-sources) of the given data -source type and name. If the resource has the `count` argument set, the value -is a list of objects representing its instances. If the resource has the `for_each` -argument set, the value is a map of objects representing its instances. - -For more information, see -[References to Resource Attributes](#references-to-resource-attributes), which -also applies to data resources aside from the addition of the `data.` prefix -to mark the reference as for a data resource. - -### Filesystem and Workspace Info - -The following values are available: - -- `path.module` is the filesystem path of the module where the expression is placed. - We do not recommend using `path.module` in write operations because it can produce - different behavior depending on whether you use remote or local module sources. - Multiple invocations of local modules use the same source directory, overwriting - the data in `path.module` during each call. This can lead to race conditions and - unexpected results. -- `path.root` is the filesystem path of the root module of the configuration. -- `path.cwd` is the filesystem path of the original working directory from where you - ran Terraform before applying any `-chdir` argument. This path is an absolute path - that includes details about the filesystem structure. It is also useful in some - advanced cases where Terraform is run from a directory other than the root module - directory. We recommend using `path.root` or `path.module` over `path.cwd` where - possible. -- `terraform.workspace` is the name of the currently selected - [workspace](/terraform/language/state/workspaces). - -Use the values in this section carefully, because they include information -about the context in which a configuration is being applied and so may -inadvertently hurt the portability or composability of a module. - -For example, if you use `path.cwd` directly to populate a path into a resource -argument then later applying the same configuration from a different directory -or on a different computer with a different directory structure will cause -the provider to consider the change of path to be a change to be applied, even -if the path still refers to the same file. - -Similarly, if you use any of these values as a form of namespacing in a shared -module, such as using `terraform.workspace` as a prefix for globally-unique -object names, it may not be possible to call your module more than once in -the same configuration. - -Aside from `path.module`, we recommend using the values in this section only -in the root module of your configuration. If you are writing a shared module -which needs a prefix to help create unique names, define an input variable -for your module and allow the calling module to define the prefix. The -calling module can then use `terraform.workspace` to define it if appropriate, -or some other value if not: - -```hcl -module "example" { - # ... - - name_prefix = "app-${terraform.workspace}" -} -``` - -### Block-Local Values - -Within the bodies of certain blocks, or in some other specific contexts, -there are other named values available beyond the global values listed above. -These local names are described in the documentation for the specific contexts -where they appear. Some of most common local names are: - -* `count.index`, in resources that use - [the `count` meta-argument](/terraform/language/meta-arguments/count). -* `each.key` / `each.value`, in resources that use - [the `for_each` meta-argument](/terraform/language/meta-arguments/for_each). -* `self`, in [provisioner](/terraform/language/resources/provisioners/syntax) and - [connection](/terraform/language/resources/provisioners/connection) blocks. - --> **Note:** Local names are often referred to as _variables_ or -_temporary variables_ in their documentation. These are not [input -variables](/terraform/language/values/variables); they are just arbitrary names -that temporarily represent a value. - -The names in this section relate to top-level configuration blocks only. -If you use [`dynamic` blocks](/terraform/language/expressions/dynamic-blocks) to dynamically generate -resource-type-specific _nested_ blocks within `resource` and `data` blocks then -you'll refer to the key and value of each element differently. See the -`dynamic` blocks documentation for details. - -## Named Values and Dependencies - -Constructs like resources and module calls often use references to named values -in their block bodies, and Terraform analyzes these expressions to automatically -infer dependencies between objects. For example, an expression in a resource -argument that refers to another managed resource creates an implicit dependency -between the two resources. - -## References to Resource Attributes - -The most common reference type is a reference to an attribute of a resource -which has been declared either with a `resource` or `data` block. Because -the contents of such blocks can be quite complicated themselves, expressions -referring to these contents can also be complicated. - -Consider the following example resource block: - -```hcl -resource "aws_instance" "example" { - ami = "ami-abc123" - instance_type = "t2.micro" - - ebs_block_device { - device_name = "sda2" - volume_size = 16 - } - ebs_block_device { - device_name = "sda3" - volume_size = 20 - } -} -``` - -The documentation for [`aws_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) -lists all of the arguments and nested blocks supported for this resource type, -and also lists a number of attributes that are _exported_ by this resource -type. All of these different resource type schema constructs are available -for use in references, as follows: - -* The `ami` argument set in the configuration can be used elsewhere with - the reference expression `aws_instance.example.ami`. -* The `id` attribute exported by this resource type can be read using the - same syntax, giving `aws_instance.example.id`. -* The arguments of the `ebs_block_device` nested blocks can be accessed using - a [splat expression](/terraform/language/expressions/splat). For example, to obtain a list of - all of the `device_name` values, use - `aws_instance.example.ebs_block_device[*].device_name`. -* The nested blocks in this particular resource type do not have any exported - attributes, but if `ebs_block_device` were to have a documented `id` - attribute then a list of them could be accessed similarly as - `aws_instance.example.ebs_block_device[*].id`. -* Sometimes nested blocks are defined as taking a logical key to identify each - block, which serves a similar purpose as the resource's own name by providing - a convenient way to refer to that single block in expressions. If `aws_instance` - had a hypothetical nested block type `device` that accepted such a key, it - would look like this in configuration: - - ```hcl - device "foo" { - size = 2 - } - device "bar" { - size = 4 - } - ``` - - Arguments inside blocks with _keys_ can be accessed using index syntax, such - as `aws_instance.example.device["foo"].size`. - - To obtain a map of values of a particular argument for _labelled_ nested - block types, use a [`for` expression](/terraform/language/expressions/for): - `{for k, device in aws_instance.example.device : k => device.size}`. - -When a resource has the -[`count`](/terraform/language/meta-arguments/count) -argument set, the resource itself becomes a _list_ of instance objects rather than -a single object. In that case, access the attributes of the instances using -either [splat expressions](/terraform/language/expressions/splat) or index syntax: - -* `aws_instance.example[*].id` returns a list of all of the ids of each of the - instances. -* `aws_instance.example[0].id` returns just the id of the first instance. - -When a resource has the -[`for_each`](/terraform/language/meta-arguments/for_each) -argument set, the resource itself becomes a _map_ of instance objects rather than -a single object, and attributes of instances must be specified by key, or can -be accessed using a [`for` expression](/terraform/language/expressions/for). - -* `aws_instance.example["a"].id` returns the id of the "a"-keyed resource. -* `[for value in aws_instance.example: value.id]` returns a list of all of the ids - of each of the instances. - -Note that unlike `count`, splat expressions are _not_ directly applicable to resources managed with `for_each`, as splat expressions must act on a list value. However, you can use the `values()` function to extract the instances as a list and use that list value in a splat expression: - -* `values(aws_instance.example)[*].id` - -### Sensitive Resource Attributes - -When defining the schema for a resource type, a provider developer can mark -certain attributes as _sensitive_, in which case Terraform will show a -placeholder marker `(sensitive value)` instead of the actual value when rendering -a plan involving that attribute. - -A provider attribute marked as sensitive behaves similarly to -[an input variable declared as sensitive](/terraform/language/values/variables#suppressing-values-in-cli-output), -where Terraform will hide the value in the plan and apply messages and will -also hide any other values you derive from it as sensitive. -However, there are some limitations to that behavior as described in -[Cases where Terraform may disclose a sensitive variable](/terraform/language/values/variables#cases-where-terraform-may-disclose-a-sensitive-variable). - -If you use a sensitive value from a resource attribute as part of an -[output value](/terraform/language/values/outputs) then Terraform will require -you to also mark the output value itself as sensitive, to confirm that you -intended to export it. - -Terraform will still record sensitive values in the [state](/terraform/language/state), -and so anyone who can access the state data will have access to the sensitive -values in cleartext. For more information, see -[_Sensitive Data in State_](/terraform/language/state/sensitive-data). - --> **Note:** Treating values derived from a sensitive resource attribute as -sensitive themselves was introduced in Terraform v0.15. Earlier versions of -Terraform will obscure the direct value of a sensitive resource attribute, -but will _not_ automatically obscure other values derived from sensitive -resource attributes. - -### Values Not Yet Known - -When Terraform is planning a set of changes that will apply your configuration, -some resource attribute values cannot be populated immediately because their -values are decided dynamically by the remote system. For example, if a -particular remote object type is assigned a generated unique id on creation, -Terraform cannot predict the value of this id until the object has been created. - -Terraform uses special unknown value placeholders for information that it -cannot predict during the plan phase. The Terraform language automatically -handles unknown values in expressions. For example, adding a known value to an -unknown value automatically produces an unknown value as a result. - -However, there are some situations where unknown values _do_ have a significant -effect: - -* The `count` meta-argument for resources cannot be unknown, since it must - be evaluated during the plan phase to determine how many instances are to - be created. - -* If unknown values are used in the configuration of a data resource, that - data resource cannot be read during the plan phase and so it will be deferred - until the apply phase. In this case, the results of the data resource will - _also_ be unknown values. - -* If an unknown value is assigned to an argument inside a `module` block, - any references to the corresponding input variable within the child module - will use that unknown value. - -* If an unknown value is used in the `value` argument of an output value, - any references to that output value in the parent module will use that - unknown value. - -* Terraform will attempt to validate that unknown values are of suitable - types where possible, but incorrect use of such values may not be detected - until the apply phase, causing the apply to fail. - -Unknown values appear in the `terraform plan` output as `(known after apply)`. diff --git a/website/docs/language/expressions/splat.mdx b/website/docs/language/expressions/splat.mdx deleted file mode 100644 index 0f489b7db9..0000000000 --- a/website/docs/language/expressions/splat.mdx +++ /dev/null @@ -1,134 +0,0 @@ ---- -page_title: Splat Expressions - Configuration Language -description: >- - Splat expressions concisely represent common operations. In Terraform, they - also transform single, non-null values into a single-element tuple. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Splat Expressions - -> **Hands-on:** Try the [Create Dynamic Expressions](/terraform/tutorials/configuration-language/expressions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -A _splat expression_ provides a more concise way to express a common -operation that could otherwise be performed with a `for` expression. - -If `var.list` is a list of objects that all have an attribute `id`, then -a list of the ids could be produced with the following `for` expression: - -```hcl -[for o in var.list : o.id] -``` - -This is equivalent to the following _splat expression:_ - -```hcl -var.list[*].id -``` - -The special `[*]` symbol iterates over all of the elements of the list given -to its left and accesses from each one the attribute name given on its -right. A splat expression can also be used to access attributes and indexes -from lists of complex types by extending the sequence of operations to the -right of the symbol: - -```hcl -var.list[*].interfaces[0].name -``` - -The above expression is equivalent to the following `for` expression: - -```hcl -[for o in var.list : o.interfaces[0].name] -``` - -## Splat Expressions with Maps - -The splat expression patterns shown above apply only to lists, sets, and -tuples. To get a similar result with a map or object value you must use -[`for` expressions](/terraform/language/expressions/for). - -Resources that use the `for_each` argument will appear in expressions as a map -of objects, so you can't use splat expressions with those resources. -For more information, see -[Referring to Resource Instances](/terraform/language/meta-arguments/for_each#referring-to-instances). - -## Single Values as Lists - -Splat expressions have a special behavior when you apply them to a value that -isn't a list, set, or tuple. - -If the value is anything other than a null value then the splat expression will -transform it into a single-element list, or more accurately a single-element -tuple value. If the value is _null_ then the splat expression will return an -empty tuple. - -This special behavior can be useful for modules that accept optional input -variables whose default value is `null` to represent the absence of any value. This allows the module to adapt the variable value for Terraform language features designed to work with collections. For example: - -```hcl -variable "website_setting" { - type = object({ - index_document = string - error_document = string - }) - default = null -} - -resource "aws_s3_bucket" "example" { - # ... - - dynamic "website" { - for_each = var.website_setting[*] - content { - index_document = website.value.index_document - error_document = website.value.error_document - } - } -} -``` - -The above example uses a [`dynamic` block](/terraform/language/expressions/dynamic-blocks), which -generates zero or more nested blocks based on a collection value. The input -variable `var.website_setting` is defined as a single object that might be null, -so the `dynamic` block's `for_each` expression uses `[*]` to ensure that -there will be one block if the module caller sets the website argument, or -zero blocks if the caller leaves it set to null. - -This special behavior of splat expressions is not obvious to an unfamiliar -reader, so we recommend using it only in `for_each` arguments and similar -situations where the context implies working with a collection. Otherwise, -the meaning of the expression may be unclear to future readers. - -## Legacy (Attribute-only) Splat Expressions - -Earlier versions of the Terraform language had a slightly different version -of splat expressions, which Terraform continues to support for backward -compatibility. This older variant is less useful than the modern form described -above, and so we recommend against using it in new configurations. - -The legacy "attribute-only" splat expressions use the sequence `.*`, instead of -`[*]`: - -``` -var.list.*.interfaces[0].name -``` - -This form has a subtly different behavior, equivalent to the following -`for` expression: - -``` -[for o in var.list : o.interfaces][0].name -``` - -Notice that with the attribute-only splat expression the index operation -`[0]` is applied to the result of the iteration, rather than as part of -the iteration itself. Only the attribute lookups apply to each element of -the input. This limitation was confusing some people using older versions of -Terraform and so we recommend always using the new-style splat expressions, -with `[*]`, to get the more consistent behavior. diff --git a/website/docs/language/expressions/strings.mdx b/website/docs/language/expressions/strings.mdx deleted file mode 100644 index 0bd617b99e..0000000000 --- a/website/docs/language/expressions/strings.mdx +++ /dev/null @@ -1,234 +0,0 @@ ---- -page_title: Strings and Templates - Configuration Language -description: >- - String literals and template sequences interpolate values and manipulate text. - Learn about both quoted and heredoc string syntax. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Strings and Templates - -String literals are the most complex kind of literal expression in -Terraform, and also the most commonly used. - -Terraform supports both a quoted syntax and a "heredoc" syntax for strings. -Both of these syntaxes support template sequences for interpolating values and -manipulating text. - -## Quoted Strings - -A quoted string is a series of characters delimited by straight double-quote -characters (`"`). - -``` -"hello" -``` - -### Escape Sequences - -In quoted strings, the backslash character serves as an escape -sequence, with the following characters selecting the escape behavior: - -| Sequence | Replacement | -| ------------ | ----------------------------------------------------------------------------- | -| `\n` | Newline | -| `\r` | Carriage Return | -| `\t` | Tab | -| `\"` | Literal quote (without terminating the string) | -| `\\` | Literal backslash | -| `\uNNNN` | Unicode character from the basic multilingual plane (NNNN is four hex digits) | -| `\UNNNNNNNN` | Unicode character from supplementary planes (NNNNNNNN is eight hex digits) | - -There are also two special escape sequences that do not use backslashes: - -| Sequence | Replacement | -| -------- | -------------------------------------------------------------- | -| `$${` | Literal `${`, without beginning an interpolation sequence. | -| `%%{` | Literal `%{`, without beginning a template directive sequence. | - -## Heredoc Strings - -Terraform supports a "heredoc" style of string literal inspired by Unix -shell languages, which allows multi-line strings to be expressed more clearly. - -```hcl -< - -Don't use "heredoc" strings to generate JSON or YAML. Instead, use -[the `jsonencode` function](/terraform/language/functions/jsonencode) or -[the `yamlencode` function](/terraform/language/functions/yamlencode) so that Terraform -can be responsible for guaranteeing valid JSON or YAML syntax. - - - -```hcl -example = jsonencode({ - a = 1 - b = "hello" -}) -``` - - - - -### Indented Heredocs - -The standard heredoc form (shown above) treats all space characters as literal -spaces. If you don't want each line to begin with spaces, then each line must be -flush with the left margin, which can be awkward for expressions in an -indented block: - -```hcl -block { - value = <}`/`%{else}`/`%{endif}` directive chooses between two templates based - on the value of a bool expression: - - ```hcl - "Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!" - ``` - - The `else` portion may be omitted, in which case the result is an empty - string if the condition expression returns `false`. - -- The `%{for in }` / `%{endfor}` directive iterates over the - elements of a given collection or structural value and evaluates a given - template once for each element, concatenating the results together: - - ```hcl - <- - Learn how to use type constraints to validate user inputs to modules and - 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Type Constraints - -Terraform module authors and provider developers can use detailed type -constraints to validate user-provided values for their input variables and -resource arguments. This requires some additional knowledge about Terraform's -type system, but allows you to build a more resilient user interface for your -modules and resources. - -## Type Keywords and Constructors - -Type constraints are expressed using a mixture of _type keywords_ and -function-like constructs called _type constructors._ - -* Type keywords are unquoted symbols that represent a static type. -* Type constructors are unquoted symbols followed by a pair of - parentheses, which contain an argument that specifies more information about - the type. Without its argument, a type constructor does not fully - represent a type; instead, it represents a _kind_ of similar types. - -Type constraints look like other kinds of Terraform -[expressions](/terraform/language/expressions), but are a special syntax. Within the -Terraform language, they are only valid in the `type` argument of an -[input variable](/terraform/language/values/variables). - -## Primitive Types - -A _primitive_ type is a simple type that isn't made from any other types. All -primitive types in Terraform are represented by a type keyword. The available -primitive types are: - -* `string`: a sequence of Unicode characters representing some text, such - as `"hello"`. -* `number`: a numeric value. The `number` type can represent both whole - numbers like `15` and fractional values such as `6.283185`. -* `bool`: either `true` or `false`. `bool` values can be used in conditional - logic. - -### Conversion of Primitive Types - -The Terraform language will automatically convert `number` and `bool` values -to `string` values when needed, and vice-versa as long as the string contains -a valid representation of a number or boolean value. - -* `true` converts to `"true"`, and vice-versa -* `false` converts to `"false"`, and vice-versa -* `15` converts to `"15"`, and vice-versa - -## Complex Types - -A _complex_ type is a type that groups multiple values into a single value. -Complex types are represented by type constructors, but several of them -also have shorthand keyword versions. - -There are two categories of complex types: collection types (for grouping -similar values), and structural types (for grouping potentially dissimilar -values). - -### Collection Types - -A _collection_ type allows multiple values of _one_ other type to be grouped -together as a single value. The type of value _within_ a collection is called -its _element type._ All collection types must have an element type, which is -provided as the argument to their constructor. - -For example, the type `list(string)` means "list of strings", which is a -different type than `list(number)`, a list of numbers. All elements of a -collection must always be of the same type. - -The three kinds of collection type in the Terraform language are: - -* `list(...)`: a sequence of values identified by consecutive whole numbers - starting with zero. - - The keyword `list` is a shorthand for `list(any)`, which accepts any - element type as long as every element is the same type. This is for - compatibility with older configurations; for new code, we recommend using - the full form. -* `map(...)`: a collection of values where each is identified by a string label. - - The keyword `map` is a shorthand for `map(any)`, which accepts any - element type as long as every element is the same type. This is for - compatibility with older configurations; for new code, we recommend using - the full form. - - You can use the following characters to define maps: - - `{}` - - `:` - - `=` - For example, `{ "foo": "bar", "bar": "baz" }` and `{ foo = "bar", bar = "baz" }` define the same map. - You must place map keys in quotation marks when a key starts with a number, contains spaces, or contains special characters. Otherwise, you can omit them. - You must place commas between keys-value pairs in single-line maps. - You can place key-value pairs in multi-line maps on new lines. - - -> **Note:** Although colons are valid delimiters between keys and values, `terraform fmt` ignores them. In contrast, `terraform fmt` attempts to vertically align equals signs. - -* `set(...)`: a collection of unique values that do not have any secondary - identifiers or ordering. - -### Structural Types - -A _structural_ type allows multiple values of _several distinct types_ to be -grouped together as a single value. Structural types require a _schema_ as an -argument, to specify which types are allowed for which elements. - -The two kinds of structural type in the Terraform language are: - -* `object(...)`: a collection of named attributes that each have their own type. - - The schema for object types is `{ = , = , ... }` — a - pair of curly braces containing a comma-separated series of ` = ` - pairs. Values that match the object type must contain _all_ of the specified - keys, and the value for each key must match its specified type. (Values with - _additional_ keys can still match an object type, but the extra attributes - are discarded during type conversion.) -* `tuple(...)`: a sequence of elements identified by consecutive whole - numbers starting with zero, where each element has its own type. - - The schema for tuple types is `[, , ...]` — a pair of square - brackets containing a comma-separated series of types. Values that match the - tuple type must have _exactly_ the same number of elements (no more and no - fewer), and the value in each position must match the specified type for - that position. - -For example: an object type of `object({ name=string, age=number })` would match -a value like the following: - -```hcl -{ - name = "John" - age = 52 -} -``` - -Also, an object type of `object({ id=string, cidr_block=string })` would match -the object produced by a reference to an `aws_vpc` resource, like -`aws_vpc.example_vpc`; although the resource has additional attributes, they -would be discarded during type conversion. - -Finally, a tuple type of `tuple([string, number, bool])` would match a value -like the following: - -```hcl -["a", 15, true] -``` - -### Complex Type Literals - -The Terraform language has literal expressions for creating tuple and object -values, which are described in -[Expressions: Literal Expressions](/terraform/language/expressions/types#literal-expressions) as -"list/tuple" literals and "map/object" literals, respectively. - -Terraform does _not_ provide any way to directly represent lists, maps, or sets. -However, due to the automatic conversion of complex types (described below), the -difference between similar complex types is almost never relevant to a normal -user, and most of the Terraform documentation conflates lists with tuples and -maps with objects. The distinctions are only useful when restricting input -values for a module or resource. - -### Conversion of Complex Types - -Similar kinds of complex types (list/tuple/set and map/object) can usually be -used interchangeably within the Terraform language, and most of Terraform's -documentation glosses over the differences between the kinds of complex type. -This is due to two conversion behaviors: - -* Whenever possible, Terraform converts values between similar kinds of complex - types if the provided value is not the exact type requested. "Similar kinds" - is defined as follows: - * Objects and maps are similar. - * A map (or a larger object) can be converted to an object if it has - _at least_ the keys required by the object schema. Any additional - attributes are discarded during conversion, which means map -> object - -> map conversions can be lossy. - * Tuples and lists are similar. - * A list can only be converted to a tuple if it has _exactly_ the - required number of elements. - * Sets are _almost_ similar to both tuples and lists: - * When a list or tuple is converted to a set, duplicate values are - discarded and the ordering of elements is lost. - * When a `set` is converted to a list or tuple, the elements will be - in an arbitrary order. If the set's elements were strings, they will - be in lexicographical order; sets of other element types do not - guarantee any particular order of elements. -* Whenever possible, Terraform converts _element values_ within a complex type, - either by converting complex-typed elements recursively or as described above - in [Conversion of Primitive Types](#conversion-of-primitive-types). - -For example: if a module argument requires a value of type `list(string)` and a -user provides the tuple `["a", 15, true]`, Terraform will internally transform -the value to `["a", "15", "true"]` by converting the elements to the required -`string` element type. Later, if the module uses those elements to set different -resource arguments that require a string, a number, and a bool (respectively), -Terraform will automatically convert the second and third strings back to the -required types at that time, since they contain valid representations of a -number and a bool. - -On the other hand, automatic conversion will fail if the provided value -(including any of its element values) is incompatible with the required type. If -an argument requires a type of `map(string)` and a user provides the object -`{name = ["Kristy", "Claudia", "Mary Anne", "Stacey"], age = 12}`, Terraform -will raise a type mismatch error, since a tuple cannot be converted to a string. - -## Dynamic Types: The "any" Constraint - -~> **Warning:** `any` is very rarely the correct type constraint to use. -**Do not use `any` just to avoid specifying a type constraint**. Always write an -exact type constraint unless you are truly handling dynamic data. - -The keyword `any` is a special construct that serves as a placeholder for a -type yet to be decided. `any` is not _itself_ a type: when interpreting a -value against a type constraint containing `any`, Terraform will attempt to -find a single actual type that could replace the `any` keyword to produce -a valid result. - -The only situation where it's appropriate to use `any` is if you will pass -the given value directly to some other system without directly accessing its -contents. For example, it's okay to use a variable of type `any` if you use -it only with `jsonencode` to pass the full value directly to a resource, as -shown in the following example: - -```hcl -variable "settings" { - type = any -} - -resource "aws_s3_object" "example" { - # ... - - # This is a reasonable use of "any" because this module - # just writes any given data to S3 as JSON, without - # inspecting it further or applying any constraints - # to its type or value. - content = jsonencode(var.settings) -} -``` - -If any part of your module accesses elements or attributes of the value, or -expects it to be a string or number, or any other non-opaque treatment, it -is _incorrect_ to use `any`. Write the exact type that your module is expecting -instead. - -### `any` with Collection Types - -All of the elements of a collection must have the same type, so if you use -`any` as the placeholder for the element type of a collection then Terraform -will attempt to find a single exact element type to use for the resulting -collection. - -For example, given the type constraint `list(any)`, Terraform will examine -the given value and try to choose a replacement for the `any` that would -make the result valid. - -If the given value were `["a", "b", "c"]` -- whose physical type is -`tuple([string, string, string])` -- Terraform analyzes this as follows: - -* Tuple types and list types are _similar_ per the previous section, so the - tuple-to-list conversion rule applies. -* All of the elements in the tuple are strings, so the type constraint - `string` would be valid for all of the list elements. -* Therefore in this case the `any` argument is replaced with `string`, - and the final concrete value type is `list(string)`. - -If the elements of the given tuple are not all of the same type then Terraform -will attempt to find a single type that they can all convert to. Terraform -will consider various conversion rules as described in earlier sections. - -* If the given value were instead `["a", 1, "b"]` then Terraform would still - select `list(string)`, because of the primitive type conversion rules, and - the resulting value would be `["a", "1", "b"]` due to the string conversion - implied by that type constraint. -* If the given value were instead `["a", [], "b"]` then the value cannot - conform to the type constraint: there is no single type that both a string - and an empty tuple can convert to. Terraform would reject this value, - complaining that all elements must have the same type. - -Although the above examples use `list(any)`, a similar principle applies to -`map(any)` and `set(any)`. - -## Optional Object Type Attributes - -Terraform typically returns an error when it does not receive a value for specified object attributes. When you mark an attribute as optional, Terraform instead inserts a default value for the missing attribute. This allows the receiving module to describe an appropriate fallback behavior. - -To mark attributes as optional, use the `optional` modifier in the object type constraint. The following example creates optional attribute `b` and optional attribute with a default value `c`. - -```hcl -variable "with_optional_attribute" { - type = object({ - a = string # a required attribute - b = optional(string) # an optional attribute - c = optional(number, 127) # an optional attribute with default value - }) -} -``` - -The `optional` modifier takes one or two arguments. -- **Type:** (Required) The first argument -specifies the type of the attribute. -- **Default:** (Optional) The second argument defines the default value that Terraform should use if the attribute is not present. This must be compatible with the attribute type. If not specified, Terraform uses a `null` value of the appropriate type as the default. - -An optional attribute with a non-`null` default value is guaranteed to never have the value `null` within the receiving module. Terraform will substitute the default value both when a caller omits the attribute altogether and when a caller explicitly sets it to `null`, thereby avoiding the need for additional checks to handle a possible null value. - -Terraform applies object attribute defaults top-down in nested variable types. This means that Terraform applies the default value you specify in the `optional` modifier first and then later applies any nested default values to that attribute. - -### Example: Nested Structures with Optional Attributes and Defaults - -The following example defines a variable for storage buckets that host a website. This variable type uses several optional attributes, including `website`, which is itself an optional `object` type that has optional attributes and defaults. - -```hcl -variable "buckets" { - type = list(object({ - name = string - enabled = optional(bool, true) - website = optional(object({ - index_document = optional(string, "index.html") - error_document = optional(string, "error.html") - routing_rules = optional(string) - }), {}) - })) -} -``` - -The following example `terraform.tfvars` file specifies three bucket configurations for `var.buckets`. - -- `production` sets the routing rules to add a redirect -- `archived` uses default configuration, but is disabled -- `docs` overrides the index and error documents to use text files - -The `production` bucket does not specify the index and error documents, and the `archived` bucket omits the website configuration entirely. Terraform will use the default values specified in the `bucket` type constraint. - -```hcl -buckets = [ - { - name = "production" - website = { - routing_rules = <<-EOT - [ - { - "Condition" = { "KeyPrefixEquals": "img/" }, - "Redirect" = { "ReplaceKeyPrefixWith": "images/" } - } - ] - EOT - } - }, - { - name = "archived" - enabled = false - }, - { - name = "docs" - website = { - index_document = "index.txt" - error_document = "error.txt" - } - }, -] -``` - -This configuration produces the following variable values. - -- For the `production` and `docs` buckets, Terraform sets `enabled` to `true`. Terraform also supplies default values for `website`, and then the values specified in `docs` override those defaults. -- For the `archived` and `docs` buckets, Terraform sets `routing_rules` to a `null` value. When Terraform does not receive optional attributes and there are no specified defaults, Terraform populates those attributes with a `null` value. -- For the `archived` bucket, Terraform populates the `website` attribute with the default values specified in the `buckets` type constraint. - -```hcl -tolist([ - { - "enabled" = true - "name" = "production" - "website" = { - "error_document" = "error.html" - "index_document" = "index.html" - "routing_rules" = <<-EOT - [ - { - "Condition" = { "KeyPrefixEquals": "img/" }, - "Redirect" = { "ReplaceKeyPrefixWith": "images/" } - } - ] - - EOT - } - }, - { - "enabled" = false - "name" = "archived" - "website" = { - "error_document" = "error.html" - "index_document" = "index.html" - "routing_rules" = tostring(null) - } - }, - { - "enabled" = true - "name" = "docs" - "website" = { - "error_document" = "error.txt" - "index_document" = "index.txt" - "routing_rules" = tostring(null) - } - }, -]) -``` - -### Example: Conditionally setting an optional attribute - -Sometimes the decision about whether or not to set a value for an optional argument needs to be made dynamically based on some other data. In that case, the calling `module` block can use a conditional expression with `null` as one of its result arms to represent dynamically leaving the argument unset. - -With the `variable "buckets"` declaration shown in the previous section, the following example conditionally overrides the `index_document` and `error_document` settings in the `website` object based on a new variable `var.legacy_filenames`: - -```hcl -variable "legacy_filenames" { - type = bool - default = false - nullable = false -} - -module "buckets" { - source = "./modules/buckets" - - buckets = [ - { - name = "maybe_legacy" - website = { - error_document = var.legacy_filenames ? "ERROR.HTM" : null - index_document = var.legacy_filenames ? "INDEX.HTM" : null - } - }, - ] -} -``` - -When `var.legacy_filenames` is set to `true`, the call will override the document filenames. When it is `false`, the call will leave the two filenames unspecified, thereby allowing the module to use its specified default values. diff --git a/website/docs/language/expressions/types.mdx b/website/docs/language/expressions/types.mdx deleted file mode 100644 index fb11551f80..0000000000 --- a/website/docs/language/expressions/types.mdx +++ /dev/null @@ -1,194 +0,0 @@ ---- -page_title: Types and Values - Configuration Language -description: >- - Learn about value types and syntax, including string, number, bool, list, and - map. Also learn about complex types and type conversion. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Types and Values - -The result of an expression is a _value_. All values have a _type_, which -dictates where that value can be used and what transformations can be -applied to it. - -## Types - -The Terraform language uses the following types for its values: - -* `string`: a sequence of Unicode characters representing some text, like - `"hello"`. -* `number`: a numeric value. The `number` type can represent both whole - numbers like `15` and fractional values like `6.283185`. -* `bool`: a boolean value, either `true` or `false`. `bool` values can be used in conditional - logic. -* `list` (or `tuple`): a sequence of values, like `["us-west-1a", "us-west-1c"]`. Identify elements in a list with consecutive whole numbers, starting with zero. -* `set`: a collection of unique values that do not have any secondary identifiers or ordering. -* `map` (or `object`): a group of values identified by named labels, like - `{name = "Mabel", age = 52}`. - -Strings, numbers, and bools are sometimes called _primitive types._ -Lists/tuples and maps/objects are sometimes called _complex types,_ _structural -types,_ or _collection types._ See -[Type Constraints](/terraform/language/expressions/type-constraints) for a more detailed -description of complex types. - -Finally, there is one special value that has _no_ type: - -* `null`: a value that represents _absence_ or _omission._ If you set an - argument of a resource to `null`, Terraform behaves as though you - had completely omitted it — it will use the argument's default value if it has - one, or raise an error if the argument is mandatory. `null` is most useful in - conditional expressions, so you can dynamically omit an argument if a - condition isn't met. - -## Literal Expressions - -A _literal expression_ is an expression that directly represents a particular -constant value. Terraform has a literal expression syntax for each of the value -types described above. - -### Strings - -Strings are usually represented by a double-quoted sequence of Unicode -characters, `"like this"`. There is also a "heredoc" syntax for more complex -strings. - -String literals are the most complex kind of literal expression in -Terraform, and have their own page of documentation. See [Strings](/terraform/language/expressions/strings) -for information about escape sequences, the heredoc syntax, interpolation, and -template directives. - -### Numbers - -Numbers are represented by unquoted sequences of digits with or without a -decimal point, like `15` or `6.283185`. - -### Bools - -Bools are represented by the unquoted symbols `true` and `false`. - -### Null - -The null value is represented by the unquoted symbol `null`. - -### Lists/Tuples - -Lists/tuples are represented by a pair of square brackets containing a -comma-separated sequence of values, like `["a", 15, true]`. - -List literals can be split into multiple lines for readability, but always -require a comma between values. A comma after the final value is allowed, -but not required. Values in a list can be arbitrary expressions. - -Lists and tuples each have different constraints on the types they allow. For more information on the types that each allows, refer to [tuples](/terraform/language/expressions/type-constraints#tuple) and [lists](/terraform/language/expressions/type-constraints#list). - -### Sets - -Terraform does not support directly accessing elements of a set by index because sets are unordered collections. To access elements in a set by index, first convert the set to a list. - - -1. Define a set. The following example specifies a set name `example_set`: - - ```hcl - variable "example_set" { - type = set(string) - default = ["foo", "bar"] - } - ``` - -1. Use the `tolist` function to convert the set to a list. The following example stores the converted list as a local variable called `example_list`: - - ```hcl - locals { - example_list = tolist(var.example_set) - } - ``` - -1. You can then reference an element in the list: - - ```hcl - output "first_element" { - value = local.example_list[0] - } - output "second_element" { - value = local.example_list[1] - } - ``` - -### Maps/Objects - -Maps/objects are represented by a pair of curly braces containing a series of -` = ` pairs: - -```hcl -{ - name = "John" - age = 52 -} -``` - -Key/value pairs can be separated by either a comma or a line break. - -The values in a map -can be arbitrary expressions. - -The keys in a map must be strings; they can be left unquoted if -they are a valid [identifier](/terraform/language/syntax/configuration#identifiers), but must be quoted -otherwise. You can use a non-literal string expression as a key by wrapping it in -parentheses, like `(var.business_unit_tag_name) = "SRE"`. - -## Indices and Attributes - -[inpage-index]: #indices-and-attributes - -Elements of list/tuple and map/object values can be accessed using -the square-bracket index notation, like `local.list[3]`. The expression within -the brackets must be a whole number for list and tuple values or a string -for map and object values. - -Map/object attributes with names that are valid identifiers can also be accessed -using the dot-separated attribute notation, like `local.object.attrname`. -In cases where a map might contain arbitrary user-specified keys, we recommend -using only the square-bracket index notation (`local.map["keyname"]`). - -## More About Complex Types - -In most situations, lists and tuples behave identically, as do maps and objects. -Whenever the distinction isn't relevant, the Terraform documentation uses each -pair of terms interchangeably (with a historical preference for "list" and -"map"). - -However, module authors and provider developers should understand the -differences between these similar types (and the related `set` type), since they -offer different ways to restrict the allowed values for input variables and -resource arguments. - -For complete details about these types (and an explanation of why the difference -usually doesn't matter), see [Type Constraints](/terraform/language/expressions/type-constraints). - -## Type Conversion - -Expressions are most often used to set values for the arguments of resources and -child modules. In these cases, the argument has an expected type and the given -expression must produce a value of that type. - -Where possible, Terraform automatically converts values from one type to -another to produce the expected type. If this conversion is impossible, Terraform -produces a type mismatch error and you must update the configuration with a -more suitable expression. Automatic type conversion does not occur when using -the [equality operator](/terraform/language/expressions/operators.mdx#equality-operators). - -Terraform automatically converts number and bool values to strings when needed. -It also converts strings to numbers or bools, as long as the string contains a -valid representation of a number or bool value. - -* `true` converts to `"true"`, and vice-versa -* `false` converts to `"false"`, and vice-versa -* `15` converts to `"15"`, and vice-versa - diff --git a/website/docs/language/expressions/version-constraints.mdx b/website/docs/language/expressions/version-constraints.mdx deleted file mode 100644 index 9c305465f5..0000000000 --- a/website/docs/language/expressions/version-constraints.mdx +++ /dev/null @@ -1,104 +0,0 @@ ---- -page_title: Version Constraints - Configuration Language -description: >- - Version constraint strings specify a range of acceptable versions for modules, - providers, and Terraform itself. Learn version constraint syntax and 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Version constraints - -This topic provides reference information about the version constraints syntax in Terraform configuration language. - -## Introduction - -Terraform lets you specify a range of acceptable versions for -components you define in the configuration. Terraform expects a specially-formatted string to constrain the versions of the component. You can specify version constraints when configuring the following components: - -- [Modules](/terraform/language/modules) -- [Provider requirements](/terraform/language/providers/requirements) -- [The `required_version` setting](/terraform/language/terraform#terraform-required_version) in the `terraform` block. - -## Version constraint syntax - -A version constraint is a [string literal](/terraform/language/expressions/strings) -containing one or more conditions separated by commas. - -Each condition consists of an operator and a version number. - -Version numbers are a series of numbers separated by periods, for example `1.2.0`. It is optional, but you can include a suffix to indicate a beta release. Refer to [Specify a pre-release version](#specify-a-pre-release-version) for additional information. - -Use the following syntax to specify version constraints: - -```hcl -version = " " -``` - -In the following example, Terraform installs a versions `1.2.0` and newer, as well as version older than `2.0.0`: - -```hcl -version = ">= 1.2.0, < 2.0.0" -``` - -## Operators - -The following table describes the operators you can use to configure version constraints: - -| Operator | Description | -| --- | --- | -| `=`,
no operator | Allows only one exact version number. Cannot be combined with other conditions. | -| `!=` | Excludes an exact version number. | -| `>`,
`>=`,
`<`,
`<=` | Compares to a specified version. Terraform allows versions that resolve to `true`. The `>` and `>=` operators request newer versions. The `<` and `<=` operators request older versions. | -| `~>` | Allows only the right-most version component to increment. Examples:
  • `~> 1.0.4`: Allows Terraform to install `1.0.5` and `1.0.10` but not `1.1.0`.
  • `~> 1.1`: Allows Terraform to install `1.2` and `1.10` but not `2.0`.
| - -## Version constraint behavior - -Terraform uses versions that meet all applicable constraints. - -Terraform consults version constraints to determine whether it has acceptable -versions of itself, any required provider plugins, and any required modules. For -plugins and modules, Terraform uses the newest installed version that meets the -applicable constraints. - -When Terraform does not have an acceptable version of a required plugin or module, -it attempts to download the newest version that meets the applicable -constraints. - -When Terraform is unable to obtain acceptable versions of external dependencies -or if it does not have an acceptable version of itself, then it does not proceed with any -`terraform plan`, `terraform apply`, or `terraform state` operations. - -The root module and any child modules can constrain the Terraform version and any provider versions the modules use. Terraform considers these constraints -equal, and only proceeds if all are met. - -### Specify a pre-release version - -A pre-release version is a version number that contains a suffix introduced by -a dash, for example `1.2.0-beta`. To configure Terraform to select a pre-release version, set the exact version number using the `=` operator. You can also omit the operator and specify the exact pre-release version. Terraform does not match pre-release versions on `>`, `>=`, `<`, `<=`, or `~>` operators. - -## Best practices - -We recommend implementing the following best practices when configuration version constraints. - -### Module versions - -- Require specific versions to ensure that updates only happen when convenient to you when your infrastructure depends on third-party modules. - -- Specify version ranges when your organization consistently uses semantic versioning for modules it maintains. - -- Specify version ranges when your organization follows a well-defined release process that avoids unwanted updates. - -### Terraform core and provider versions - -- Reusable modules should constrain only their minimum allowed versions of - Terraform and providers, such as `>= 0.12.0`. This helps avoid known - incompatibilities, while allowing the user of the module flexibility to - upgrade to newer versions of Terraform without altering the module. - -- Root modules should use a `~>` constraint to set both a lower and upper bound - on versions for each provider they depend on. diff --git a/website/docs/language/files/dependency-lock.mdx b/website/docs/language/files/dependency-lock.mdx deleted file mode 100644 index 3ba2fa4d2f..0000000000 --- a/website/docs/language/files/dependency-lock.mdx +++ /dev/null @@ -1,425 +0,0 @@ ---- -page_title: Dependency Lock File (.terraform.lock.hcl) - Configuration Language -description: >- - Terraform uses the dependency lock file .teraform.lock.hcl to track and select - provider versions. Learn about dependency installation and lock file changes. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Lock File - --> **Note:** This page is about a feature of Terraform 0.14 and later. Prior -versions of Terraform did not track dependency selections at all, so the -information here is not relevant to those versions. - -> **Hands-on:** Try the [Lock and Upgrade Provider Versions](/terraform/tutorials/configuration-language/provider-versioning?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -A Terraform configuration may refer to two different kinds of external -dependency that come from outside of its own codebase: - -- [Providers](/terraform/language/providers/requirements), which are plugins for Terraform - that extend it with support for interacting with various external systems. -- [Modules](/terraform/language/modules), which allow - splitting out groups of Terraform configuration constructs (written in the - Terraform language) into reusable abstractions. - -Both of these dependency types can be published and updated independently from -Terraform itself and from the configurations that depend on them. For that -reason, Terraform must determine which versions of those dependencies are -potentially compatible with the current configuration and which versions are -currently selected for use. - -[Version constraints](/terraform/language/expressions/version-constraints) within the configuration -itself determine which versions of dependencies are _potentially_ compatible, -but after selecting a specific version of each dependency Terraform remembers -the decisions it made in a _dependency lock file_ so that it can (by default) -make the same decisions again in future. - -At present, the dependency lock file tracks only _provider_ dependencies. -Terraform does not remember version selections for remote modules, and so -Terraform will always select the newest available module version that meets -the specified version constraints. You can use an _exact_ version constraint -to ensure that Terraform will always select the same module version. - -## Lock File Location - -The dependency lock file is a file that belongs to the configuration as a -whole, rather than to each separate module in the configuration. For that reason -Terraform creates it and expects to find it in your current working directory -when you run Terraform, which is also the directory containing the `.tf` files -for the root module of your configuration. - -The lock file is always named `.terraform.lock.hcl`, and this name is intended -to signify that it is a lock file for various items that Terraform caches in -the `.terraform` subdirectory of your working directory. - -Terraform automatically creates or updates the dependency lock file each time -you run [the `terraform init` command](/terraform/cli/commands/init). You should -include this file in your version control repository so that you can discuss -potential changes to your external dependencies via code review, just as you -would discuss potential changes to your configuration itself. - -The dependency lock file uses the same low-level syntax as the main Terraform -language, but the dependency lock file is not itself a Terraform language -configuration file. It is named with the suffix `.hcl` instead of `.tf` in -order to signify that difference. - -## Dependency Installation Behavior - -When `terraform init` is working on installing all of the providers needed for -a configuration, Terraform considers both the version constraints in the -configuration _and_ the version selections recorded in the lock file. - -If a particular provider has no existing recorded selection, Terraform will -select the newest available version that matches the given version constraint, -and then update the lock file to include that selection. - -If a particular provider already has a selection recorded in the lock file, -Terraform will always re-select that version for installation, even if a -newer version has become available. You can override that behavior by adding -the `-upgrade` option when you run `terraform init`, in which case Terraform -will disregard the existing selections and once again select the newest -available version matching the version constraint. - -If a particular `terraform init` call makes changes to the lock file, Terraform -will mention that as part of its output: - -``` -Terraform has made some changes to the provider dependency selections recorded -in the .terraform.lock.hcl file. Review those changes and commit them to your -version control system if they represent changes you intended to make. -``` - -When you see this message, you can use your version control system to -[review the changes Terraform has proposed in the file](#understanding-lock-file-changes), -and if they represent changes you made intentionally you can send the change -through your team's usual code review process. - -### Checksum verification - -Terraform will also verify that each package it installs matches at least one -of the checksums it previously recorded in the lock file, if any, returning an -error if none of the checksums match: - -``` -Error: Failed to install provider - -Error while installing hashicorp/azurerm v2.1.0: the current package for -registry.terraform.io/hashicorp/azurerm 2.1.0 doesn't match any of the -checksums previously recorded in the dependency lock file. -``` - -This checksum verification is intended to represent a -_[trust on first use](https://en.wikipedia.org/wiki/Trust_on_first_use)_ -approach. When you add a new provider for the first time you can verify it -in whatever way you choose or any way you are required to by relevant -regulations, and then trust that Terraform will raise an error if a future -run of `terraform init` encounters a non-matching package for the same -provider version. - -There are two special considerations with the "trust on first use" model: - -- If you install a provider from an origin registry which provides checksums - that are signed with a cryptographic signature, Terraform will treat all - of the signed checksums as valid as long as one checksum matches. The lock - file will therefore include checksums for both the package you installed for - your current platform _and_ any other packages that might be available for - other platforms. - - In this case, the `terraform init` output will include the fingerprint of - the key that signed the checksums, with a message like - `(signed by a HashiCorp partner, key ID DC9FC6B1FCE47986)`. You may wish to - confirm that you trust the holder of the given key before committing the - lock file containing the signed checksums, or to retrieve and verify the - full set of available packages for the given provider version. - -- If you install a provider for the first time using an alternative - installation method, such as a filesystem or network mirror, Terraform will - not be able to verify the checksums for any platform other than the one - where you ran `terraform init`, and so it will not record the checksums - for other platforms and so the configuration will not be usable on any other - platform. - - To avoid this problem you can pre-populate checksums for a variety of - different platforms in your lock file using - [the `terraform providers lock` command](/terraform/cli/commands/providers/lock), - which will then allow future calls to `terraform init` to verify that the - packages available in your chosen mirror match the official packages from - the provider's origin registry. - -## Understanding Lock File Changes - -Because the dependency lock file is primarily maintained automatically by -Terraform itself, rather than being updated manually by you or your team, -your version control system may show you that the file has changed. - -There are a few different types of changes that Terraform can potentially make -to your lock file, which you may need to understand in order to review the -proposed changes. The following sections will describe these common situations. - -### Dependency on a new provider - -If you add a new entry to the -[provider requirements](/terraform/language/providers/requirements) for any module in your -configuration, or if you add an external module that includes a new provider -dependency itself, `terraform init` will respond to that by selecting the -newest version of that provider which meets all of the version constraints -in the configuration, and it will record its decision as a new `provider` -block in the dependency lock file. - -```diff ---- .terraform.lock.hcl 2020-10-07 16:12:07.539570634 -0700 -+++ .terraform.lock.hcl 2020-10-07 16:12:15.267487237 -0700 -@@ -6,6 +6,26 @@ - ] - } - -+provider "registry.terraform.io/hashicorp/azurerm" { -+ version = "2.30.0" -+ constraints = "~> 2.12" -+ hashes = [ -+ "h1:FJwsuowaG5CIdZ0WQyFZH9r6kIJeRKts9+GcRsTz1+Y=", -+ "h1:c/ntSXrDYM1mUir2KufijYebPcwKqS9CRGd3duDSGfY=", -+ "h1:yre4Ph76g9H84MbuhZ2z5MuldjSA4FsrX6538O7PCcY=", -+ "zh:04f0a50bb2ba92f3bea6f0a9e549ace5a4c13ef0cbb6975494cac0ef7d4acb43", -+ "zh:2082e12548ebcdd6fd73580e83f626ed4ed13f8cdfd51205d8696ffe54f30734", -+ "zh:246bcc449e9a92679fb30f3c0a77f05513886565e2dcc66b16c4486f51533064", -+ "zh:24de3930625ac9014594d79bfa42d600eca65e9022b9668b54bfd0d924e21d14", -+ "zh:2a22893a576ff6f268d9bf81cf4a56406f7ba79f77826f6df51ee787f6d2840a", -+ "zh:2b27485e19c2aaa9f15f29c4cff46154a9720647610171e30fc6c18ddc42ec28", -+ "zh:435f24ce1fb2b63f7f02aa3c84ac29c5757cd29ec4d297ed0618423387fe7bd4", -+ "zh:7d99725923de5240ff8b34b5510569aa4ebdc0bdb27b7bac2aa911a8037a3893", -+ "zh:7e3b5d0af3b7411dd9dc65ec9ab6caee8c191aee0fa7f20fc4f51716e67f50c0", -+ "zh:da0af4552bef5a29b88f6a0718253f3bf71ce471c959816eb7602b0dadb469ca", -+ ] -+} -+ - provider "registry.terraform.io/newrelic/newrelic" { - version = "2.1.2" - constraints = "~> 2.1.1" -``` - -The new lock file entry records several pieces of information: - -- `version`: the exact version that Terraform selected based on the version - constraints in the configuration. -- `constraints`: all of the version constraints that Terraform considered when - making this selection. (Terraform doesn't actually use this information to - make installation decisions, but includes it to help explain to human readers - how the previous decision was made.) -- `hashes`: a number of checksums that are all considered to be valid for - packages implementing the selected version of this provider on different - platforms. The meaning of these hashes is explained more under - _[New provider package checksums](#new-provider-package-checksums)_ below. - -### New version of an existing provider - -If you run `terraform init -upgrade` to ask Terraform to consider newer provider -versions that still match the configured version constraints, Terraform may -then select a newer version for a provider and update its existing `provider` -block to reflect that change. - -```diff ---- .terraform.lock.hcl 2020-10-07 16:44:25.819579509 -0700 -+++ .terraform.lock.hcl 2020-10-07 16:43:42.785665945 -0700 -@@ -7,22 +7,22 @@ - } - - provider "registry.terraform.io/hashicorp/azurerm" { -- version = "2.1.0" -- constraints = "~> 2.1.0" -+ version = "2.0.0" -+ constraints = "2.0.0" - hashes = [ -- "h1:EOJImaEaVThWasdqnJjfYc6/P8N/MRAq1J7avx5ZbV4=", -- "zh:0015b491cf9151235e57e35ea6b89381098e61bd923f56dffc86026d58748880", -- "zh:4c5682ba1e0fc7e2e602d3f103af1638f868c31fe80cc1a884a97f6dad6e1c11", -- "zh:57bac885b108c91ade4a41590062309c832c9ab6bf6a68046161636fcaef1499", -- "zh:5810d48f574c0e363c969b3f45276369c8f0a35b34d6202fdfceb7b85b3ac597", -- "zh:5c6e37a44462b8662cf9bdd29ce30523712a45c27c5d4711738705be0785db41", -- "zh:64548940a3387aa3a752e709ee9eb9982fa820fe60eb60e5f212cc1d2c58549e", -- "zh:7f46749163da17330bbb5293dc825333c86304baa0a7c6256650ac536b4567c8", -- "zh:8f8970f2df75ac43ffdd112055ee069d8bd1030f7eb4367cc4cf494a1fa802c3", -- "zh:9ad693d00dc5d7d455d06faba70e716bce727c6706f7293288e87fd7956b8fe0", -- "zh:b6e3cb55e6aec62b47edd0d2bd5e14bd6a2bcfdac65930a6e9e819934734c57b", -- "zh:d6a3f3b9b05c28ecf3919e9e7afa185805a6d7442fc4b3eedba749c2731d1f0e", -- "zh:d81fb624a357c57c7ea457ce543d865b39b12f26c2edd58a2f7cd43326c91010", -+ "h1:bigGXBoRbp7dv79bEEn+aaju8575qEXHQ57XHVPJeB8=", -+ "zh:09c603c8904ca4a5bc19e82335afbc2837dcc4bee81e395f9daccef2f2cba1c8", -+ "zh:194a919d4836d6c6d4ce598d0c66cce00ddc0d0b5c40d01bb32789964d818b42", -+ "zh:1f269627df4e266c4e0ef9ee2486534caa3c8bea91a201feda4bca525005aa0a", -+ "zh:2bae3071bd5f8e553355c4b3a547d6efe1774a828142b762e9a4e85f79be7f63", -+ "zh:6c98dfa5c3468e8d02e2b3af7c4a8a14a5d469ce5a642909643b413a17ca338b", -+ "zh:7af78f61666fd45fbf428161c061ea2623162d601b79dc71d6a5158756853ffa", -+ "zh:883c2df86ae9ba2a5c167cf5c2c7deca0239171a224d6d335f0fd6dd9c283830", -+ "zh:a2028379078577d8ff5ecfca6e8a8b25a25ffb1686de0ee52a7fe8011783488b", -+ "zh:abe6ef399552fd3861a454a839cd978c1d15735658fdc00f9054435aff0f4620", -+ "zh:c30b1bf14077913c3cdf34979b1434dbb1353cb5995eb3956b191c50538b64a9", -+ "zh:ca64ae2ad9793e5631e3b0b9327f7cb22cb5d8e9de57be7d85821791b1d5a375", -+ "zh:fffe56904a38109bb8d613b02808a177c3ddfac19f03b3aac799281fea38f475", - ] - } -``` - -The primary effect of selecting a new provider version is to change the -value of `version` in the `provider` block. If the upgrade came along with -a change to the configured version constraints, Terraform will also record -that change in the `constraints` value. - -Because each version has its own set of distribution packages, switching to -a new version will also tend to replace all of the values in `hashes`, to -reflect the checksums of the packages for the new version. - -### New provider package checksums - -A more subtle change you may see in a `provider` block is the addition of -new checksums that were not previously recorded, even though nothing else -in the `provider` block has changed: - -```diff ---- .terraform.lock.hcl 2020-10-07 17:24:23.397892140 -0700 -+++ .terraform.lock.hcl 2020-10-07 17:24:57.423130253 -0700 -@@ -10,6 +10,7 @@ - version = "2.1.0" - constraints = "~> 2.1.0" - hashes = [ -+ "h1:1xvaS5D8B8t6J6XmXxX8spo97tAzjhacjedFX1B47Fk=", - "h1:EOJImaEaVThWasdqnJjfYc6/P8N/MRAq1J7avx5ZbV4=", - "zh:0015b491cf9151235e57e35ea6b89381098e61bd923f56dffc86026d58748880", - "zh:4c5682ba1e0fc7e2e602d3f103af1638f868c31fe80cc1a884a97f6dad6e1c11", -``` - -The addition of a new checksum into the `hashes` value represents Terraform -gradually transitioning between different _hashing schemes_. The `h1:` and -`zh:` prefixes on these values represent different hashing schemes, each -of which represents calculating a checksum using a different algorithm. -We may occasionally introduce new hashing schemes if we learn of limitations -in the existing schemes or if a new scheme offers some considerable -additional benefit. - -The two hashing schemes currently supported are: - -- `zh:`: a mnemonic for "zip hash", this is a legacy hash format which is - part of the Terraform provider registry protocol and is therefore used for - providers that you install directly from an origin registry. - - This hashing scheme captures a SHA256 hash of each of the official `.zip` - packages indexed in the origin registry. This is an effective scheme for - verifying the official release packages when installed from a registry, but - it's not suitable for verifying packages that come from other - [provider installation methods](/terraform/cli/config/config-file#provider-installation), - such as filesystem mirrors using the unpacked directory layout. - -- `h1:`: a mnemonic for "hash scheme 1", which is the current preferred hashing - scheme. - - Hash scheme 1 is also a SHA256 hash, but is one computed from the _contents_ - of the provider distribution package, rather than of the `.zip` archive - it's contained within. This scheme therefore has the advantage that it can - be calculated for an official `.zip` file, an unpacked directory with the - same contents, or a recompressed `.zip` file which contains the same files - but potentially different metadata or compression schemes. - - Due to the limited scope of the `zh:` scheme, Terraform will - opportunistically add in the corresponding `h1:` checksums as it learns - of them, which is what caused the addition of a second `h1:` checksum - in the example change shown above. - -Terraform will add a new hash to an existing provider only if the hash is -calculated from a package that _also_ matches one of the existing hashes. In -the above example, Terraform installed a `hashicorp/azurerm` package for a -different platform than that which produced the original `h1:` checksum, but was -able to match it against one of the `zh:` checksums recorded previously. -After confirming the `zh:` checksum match, Terraform then recorded the -corresponding `h1:` checksum in order to gradually migrate from the old scheme -to the new scheme. - -When installing a particular provider for the first time (where there is no -existing `provider` block for it), Terraform will pre-populate the `hashes` -value with any checksums that are covered by the provider developer's -cryptographic signature, which usually covers all of the available packages -for that provider version across all supported platforms. However, because -the provider registry protocol still uses the `zh:` scheme, the initial set -will consist primarily of hashes using that scheme, which Terraform will then -upgrade opportunistically as you install the packages on different platforms. - -If you wish to avoid ongoing additions of new `h1:` hashes as you work with -your configuration on new target platforms, or if you are installing providers -from a mirror that therefore can't provide official signed checksums, you -can ask Terraform to pre-populate hashes for a chosen set of platforms -using -[the `terraform providers lock` command](/terraform/cli/commands/providers/lock): - -``` -terraform providers lock \ - -platform=linux_arm64 \ - -platform=linux_amd64 \ - -platform=darwin_amd64 \ - -platform=windows_amd64 -``` - -The above command will download and verify the official packages for all of -the required providers across all four of the given platforms, and then record -both `zh:` and `h1:` checksums for each of them in the lock file, thus avoiding -the case where Terraform will learn about a `h1:` equivalent only at a later -time. See the `terraform providers lock` documentation for more information on -this command. - -### Providers that are no longer required - -To determine whether there still exists a dependency on a given provider, -Terraform uses two sources of truth: the configuration itself, and the state. -If you remove the last dependency on a particular provider from both your -configuration and state, then `terraform init` will remove any existing lock -file entry for that provider. - -```diff ---- .terraform.lock.hcl 2020-10-07 16:12:07.539570634 -0700 -+++ .terraform.lock.hcl 2020-10-07 16:12:15.267487237 -0700 -@@ -6,26 +6,6 @@ - ] - } - --provider "registry.terraform.io/hashicorp/azurerm" { -- version = "2.30.0" -- constraints = "~> 2.12" -- hashes = [ -- "h1:FJwsuowaG5CIdZ0WQyFZH9r6kIJeRKts9+GcRsTz1+Y=", -- "h1:c/ntSXrDYM1mUir2KufijYebPcwKqS9CRGd3duDSGfY=", -- "h1:yre4Ph76g9H84MbuhZ2z5MuldjSA4FsrX6538O7PCcY=", -- "zh:04f0a50bb2ba92f3bea6f0a9e549ace5a4c13ef0cbb6975494cac0ef7d4acb43", -- "zh:2082e12548ebcdd6fd73580e83f626ed4ed13f8cdfd51205d8696ffe54f30734", -- "zh:246bcc449e9a92679fb30f3c0a77f05513886565e2dcc66b16c4486f51533064", -- "zh:24de3930625ac9014594d79bfa42d600eca65e9022b9668b54bfd0d924e21d14", -- "zh:2a22893a576ff6f268d9bf81cf4a56406f7ba79f77826f6df51ee787f6d2840a", -- "zh:2b27485e19c2aaa9f15f29c4cff46154a9720647610171e30fc6c18ddc42ec28", -- "zh:435f24ce1fb2b63f7f02aa3c84ac29c5757cd29ec4d297ed0618423387fe7bd4", -- "zh:7d99725923de5240ff8b34b5510569aa4ebdc0bdb27b7bac2aa911a8037a3893", -- "zh:7e3b5d0af3b7411dd9dc65ec9ab6caee8c191aee0fa7f20fc4f51716e67f50c0", -- "zh:da0af4552bef5a29b88f6a0718253f3bf71ce471c959816eb7602b0dadb469ca", -- ] --} -- - provider "registry.terraform.io/newrelic/newrelic" { - version = "2.1.2" - constraints = "~> 2.1.1" -``` - -If you add a new requirement for the same provider at a later date and run -`terraform init` again, Terraform will treat it as if it were -[an entirely new provider](#dependency-on-a-new-provider) -and so will not necessarily select the same version that was previously -selected and will not be able to verify that the checksums remained unchanged. - --> **Note:** In Terraform v1.0 and earlier, `terraform init` does not -automatically remove now-unneeded providers from the lock file, and instead -just ignores them. If you removed a provider dependency while using an -earlier version of Terraform and then upgraded to Terraform v1.1 or later -then you may see the error "missing or corrupted provider plugins", referring to -the stale lock file entries. If so, run `terraform init` with the new Terraform -version to tidy those unneeded entries and then retry the previous operation. diff --git a/website/docs/language/files/index.mdx b/website/docs/language/files/index.mdx deleted file mode 100644 index dceda31f9d..0000000000 --- a/website/docs/language/files/index.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -page_title: Files and Directories - Configuration Language -description: >- - Learn how to name, organize, and store Terraform configuration files. Also - learn how Terraform evaluates 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Files and Directories - -## File Extension - -Code in the Terraform language is stored in plain text files with the `.tf` file -extension. There is also -[a JSON-based variant of the language](/terraform/language/syntax/json) that is named with -the `.tf.json` file extension. - -Files containing Terraform code are often called _configuration files._ - -## Text Encoding - -Configuration files must always use UTF-8 encoding, and by convention -usually use Unix-style line endings (LF) rather than Windows-style -line endings (CRLF), though both are accepted. - -## Directories and Modules - -A _module_ is a collection of `.tf` and/or `.tf.json` files kept together in a -directory. - -A Terraform module only consists of the top-level configuration files in a -directory; nested directories are treated as completely separate modules, and -are not automatically included in the configuration. - -Terraform evaluates all of the configuration files in a module, effectively -treating the entire module as a single document. Separating various blocks into -different files is purely for the convenience of readers and maintainers, and -has no effect on the module's behavior. - -A Terraform module can use [module calls](/terraform/language/modules) to -explicitly include other modules into the configuration. These child modules can -come from local directories (nested in the parent module's directory, or -anywhere else on disk), or from external sources like the -[Terraform Registry](https://registry.terraform.io). - -## The Root Module - -Terraform always runs in the context of a single _root module._ A complete -_Terraform configuration_ consists of a root module and the tree of child -modules (which includes the modules called by the root module, any modules -called by those modules, etc.). - -- In Terraform CLI, the root module is the working directory where Terraform is - invoked. (You can use command line options to specify a root module outside - the working directory, but in practice this is rare.) -- In HCP Terraform and Terraform Enterprise, the root module for a workspace - defaults to the top level of the configuration directory (supplied via version - control repository or direct upload), but the workspace settings can specify a - subdirectory to use instead. diff --git a/website/docs/language/files/override.mdx b/website/docs/language/files/override.mdx deleted file mode 100644 index a99fe74582..0000000000 --- a/website/docs/language/files/override.mdx +++ /dev/null @@ -1,166 +0,0 @@ ---- -page_title: Override Files - Configuration Language -description: >- - Override files merge additional settings into existing configuration objects. - Learn how to use override files and about merging 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Override Files - -Terraform normally loads all of the `.tf` and `.tf.json` files within a -directory and expects each one to define a distinct set of configuration -objects. If two files attempt to define the same object, Terraform returns -an error. - -In some rare cases, it is convenient to be able to override specific portions -of an existing configuration object in a separate file. For example, a -human-edited configuration file in the Terraform language native syntax -could be partially overridden using a programmatically-generated file -in JSON syntax. - -For these rare situations, Terraform has special handling of any configuration -file whose name ends in `_override.tf` or `_override.tf.json`. This special -handling also applies to a file named literally `override.tf` or -`override.tf.json`. - -Terraform initially skips these _override files_ when loading configuration, -and then afterwards processes each one in turn (in lexicographical order). For -each top-level block defined in an override file, Terraform attempts to find -an already-defined object corresponding to that block and then merges the -override block contents into the existing object. - -Use override files only in special circumstances. Over-use of override files -hurts readability, since a reader looking only at the original files cannot -easily see that some portions of those files have been overridden without -consulting all of the override files that are present. When using override -files, use comments in the original files to warn future readers about which -override files apply changes to each block. - -## Example - -If you have a Terraform configuration `example.tf` with the following contents: - -```hcl -resource "aws_instance" "web" { - instance_type = "t2.micro" - ami = "ami-408c7f28" -} -``` - -...and you created a file `override.tf` containing the following: - -```hcl -resource "aws_instance" "web" { - ami = "foo" -} -``` - -Terraform will merge the latter into the former, behaving as if the original -configuration had been as follows: - -```hcl -resource "aws_instance" "web" { - instance_type = "t2.micro" - ami = "foo" -} -``` - -## Merging Behavior - -The merging behavior is slightly different for each block type, and some -special constructs within certain blocks are merged in a special way. - -The general rule, which applies in most cases, is: - -* A top-level block in an override file merges with a block in a normal - configuration file that has the same block header. The block _header_ is the - block type and any quoted labels that follow it. - -* Within a top-level block, an attribute argument within an override block - replaces any argument of the same name in the original block. - -* Within a top-level block, any nested blocks within an override block replace - _all_ blocks of the same type in the original block. Any block types that - do not appear in the override block remain from the original block. - -* The contents of nested configuration blocks are not merged. - -* The resulting _merged block_ must still comply with any validation rules - that apply to the given block type. - -If more than one override file defines the same top-level block, the overriding -effect is compounded, with later blocks taking precedence over earlier blocks. -Overrides are processed in order first by filename (in lexicographical order) -and then by position in each file. - -The following sections describe the special merging behaviors that apply to -specific arguments within certain top-level block types. - -### Merging `resource` and `data` blocks - -Within a `resource` block, the contents of any `lifecycle` nested block are -merged on an argument-by-argument basis. For example, if an override block -sets only the `create_before_destroy` argument then any `ignore_changes` -argument in the original block will be preserved. - -If an overriding `resource` block contains one or more `provisioner` blocks -then any `provisioner` blocks in the original block are ignored. - -If an overriding `resource` block contains a `connection` block then it -completely overrides any `connection` block present in the original block. - -The `depends_on` meta-argument may not be used in override blocks, and will -produce an error. - -### Merging `variable` blocks - -The arguments within a `variable` block are merged in the standard way -described above, but some special considerations apply due to the interactions -between the `type` and `default` arguments. - -If the original block defines a `default` value and an override block changes -the variable's `type`, Terraform attempts to convert the default value to -the overridden type, producing an error if this conversion is not possible. - -Conversely, if the original block defines a `type` and an override block changes -the `default`, the overridden default value must be compatible with the -original type specification. - -### Merging `output` blocks - -The `depends_on` meta-argument may not be used in override blocks, and will -produce an error. - -### Merging `locals` blocks - -Each `locals` block defines a number of named values. Overrides are applied -on a value-by-value basis, ignoring which `locals` block they are defined in. - -### Merging `terraform` blocks - -The settings within `terraform` blocks are considered individually when -merging. - -If the `required_providers` argument is set, its value is merged on an -element-by-element basis, which allows an override block to adjust the -constraint for a single provider without affecting the constraints for -other providers. - -In both the `required_version` and `required_providers` settings, each override -constraint entirely replaces the constraints for the same component in the -original block. If both the base block and the override block both set -`required_version` then the constraints in the base block are entirely ignored. - -The presence of a block defining a backend (either `cloud` or `backend`) in an override -file always takes precedence over a block defining a backend in the original configuration. -That is, if a `cloud` block is set within the original configuration and a `backend` block is -set in the override file, Terraform will use the `backend` block specified in the override file upon merging. -Similarly, if a `backend` block is set within the original configuration and a `cloud` block -is set in the override file, Terraform will use the `cloud` block specified in the override -file upon merging. diff --git a/website/docs/language/files/tests.mdx b/website/docs/language/files/tests.mdx deleted file mode 100644 index 954c415847..0000000000 --- a/website/docs/language/files/tests.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -page_title: Test Files - Configuration Language -description: >- - Learn how to write test files for validating your configuration and 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Test Files - -Specific Terraform commands, such as `test`, `init`, and `validate`, load Terraform test files for your configuration. - -Test files contain specifications for Terraform test executions. For more information about the Terraform `test` command, refer to [Command: `test`](/terraform/cli/commands/test). For more information about the syntax and Terraform test file language, refer to [Tests](/terraform/language/tests). - -## File Extension - -Terraform test files use the file extensions `.tftest.hcl` and `.tftest.json`. - -## Test File Locations - -Terraform loads all test files within your root configuration directory. - -Terraform also loads the test files within the testing directory. You can override the location of the testing directory by appending the `-test-directory` flag to commands that load test files. The default testing directory is `tests` relative to your configuration directory. diff --git a/website/docs/language/functions/abs.mdx b/website/docs/language/functions/abs.mdx deleted file mode 100644 index 1b49335d3e..0000000000 --- a/website/docs/language/functions/abs.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -page_title: abs - Functions - Configuration Language -description: The abs function returns the absolute value of the given number. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `abs` function reference - -This topic provides reference information about the `abs` function. The `abs` function returns the absolute value of the given number. - -## Introduction - -The `abs` function returns the absolute value of the given number. If the number is zero or positive, the function returns the value as-is, but if it is negative, it is multiplied by -1 to make it positive before returning it. - -## Syntax - -Use the `abs` function with the following syntax: - -```hcl -abs(number) -``` - -The `number` argument is the number you want the absolute value of. - -In the following example, the function returns the absolute value of `23`, `0`, and `-12.4`. - -```hcl hideClipboard -$ abs(23) -23 -$ abs(0) -0 -$ abs(-12.4) -12.4 -``` - -## Example use case - -The following example defines a variable `num` that is negative. The function outputs the absolute value of `num`, which is `10`. - -```hcl -variable "num" { - default = -10 -} - -output "absolute_value" { - value = abs(var.num) -} -``` - -## Related Functions - -- [`signum`](/terraform/language/functions/signum) determines the sign of a number, returning a number between -1 and 1 to represent the sign diff --git a/website/docs/language/functions/abspath.mdx b/website/docs/language/functions/abspath.mdx deleted file mode 100644 index 06861534f9..0000000000 --- a/website/docs/language/functions/abspath.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -page_title: abspath - Functions - Configuration Language -description: The abspath function converts the argument to an absolute filesystem path. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `abspath` Function - -`abspath` takes a string containing a filesystem path and converts it -to an absolute path. That is, if the path is not absolute, it will be joined -with the current working directory. - -Referring directly to filesystem paths in resource arguments may cause -spurious diffs if the same configuration is applied from multiple systems or on -different host operating systems. We recommend using filesystem paths only -for transient values, such as the argument to [`file`](/terraform/language/functions/file) (where -only the contents are then stored) or in `connection` and `provisioner` blocks. - -## Examples - -``` -> abspath(path.root) -/home/user/some/terraform/root -``` diff --git a/website/docs/language/functions/alltrue.mdx b/website/docs/language/functions/alltrue.mdx deleted file mode 100644 index 710fe207fb..0000000000 --- a/website/docs/language/functions/alltrue.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: alltrue - Functions - Configuration Language -description: |- - The alltrue function determines whether all elements of a collection - are true or "true". If the collection is empty, it returns true. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `alltrue` Function - --> **Note:** This function is available in Terraform 0.14 and later. - -`alltrue` returns `true` if all elements in a given collection are `true` -or `"true"`. It also returns `true` if the collection is empty. - -```hcl -alltrue(list) -``` - -## Examples - -```command -> alltrue(["true", true]) -true -> alltrue([true, false]) -false -``` diff --git a/website/docs/language/functions/anytrue.mdx b/website/docs/language/functions/anytrue.mdx deleted file mode 100644 index 1e5503617c..0000000000 --- a/website/docs/language/functions/anytrue.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -page_title: anytrue - Functions - Configuration Language -description: |- - The anytrue function determines whether any element of a collection - is true or "true". If the collection is empty, it returns false. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `anytrue` Function - --> **Note:** This function is available in Terraform 0.14 and later. - -`anytrue` returns `true` if any element in a given collection is `true` -or `"true"`. It also returns `false` if the collection is empty. - -```hcl -anytrue(list) -``` - -## Examples - -```command -> anytrue(["true"]) -true -> anytrue([true]) -true -> anytrue([true, false]) -true -> anytrue([]) -false -``` diff --git a/website/docs/language/functions/base64decode.mdx b/website/docs/language/functions/base64decode.mdx deleted file mode 100644 index f16b935060..0000000000 --- a/website/docs/language/functions/base64decode.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -page_title: base64decode - Functions - Configuration Language -description: The base64decode function decodes a string containing a base64 sequence. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `base64decode` Function - -`base64decode` takes a string containing a Base64 character sequence and -returns the original string. - -Terraform uses the "standard" Base64 alphabet as defined in -[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -Strings in the Terraform language are sequences of unicode characters rather -than bytes, so this function will also interpret the resulting bytes as -UTF-8. If the bytes after Base64 decoding are _not_ valid UTF-8, this function -produces an error. - -While we do not recommend manipulating large, raw binary data in the Terraform -language, Base64 encoding is the standard way to represent arbitrary byte -sequences, and so resource types that accept or return binary data will use -Base64 themselves, which avoids the need to encode or decode it directly in -most cases. Various other functions with names containing "base64" can generate -or manipulate Base64 data directly. - -`base64decode` is, in effect, a shorthand for calling -[`textdecodebase64`](/terraform/language/functions/textdecodebase64) with the encoding name set to -`UTF-8`. - -## Examples - -``` -> base64decode("SGVsbG8gV29ybGQ=") -Hello World -``` - -## Related Functions - -* [`base64encode`](/terraform/language/functions/base64encode) performs the opposite operation, - encoding the UTF-8 bytes for a string as Base64. -* [`textdecodebase64`](/terraform/language/functions/textdecodebase64) is a more general function that - supports character encodings other than UTF-8. -* [`base64gzip`](/terraform/language/functions/base64gzip) applies gzip compression to a string - and returns the result with Base64 encoding. -* [`filebase64`](/terraform/language/functions/filebase64) reads a file from the local filesystem - and returns its raw bytes with Base64 encoding. diff --git a/website/docs/language/functions/base64encode.mdx b/website/docs/language/functions/base64encode.mdx deleted file mode 100644 index efe3d9a575..0000000000 --- a/website/docs/language/functions/base64encode.mdx +++ /dev/null @@ -1,54 +0,0 @@ ---- -page_title: base64encode - Functions - Configuration Language -description: The base64encode function applies Base64 encoding to a string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `base64encode` Function - -`base64encode` applies Base64 encoding to a string. - -Terraform uses the "standard" Base64 alphabet as defined in -[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -Strings in the Terraform language are sequences of unicode characters rather -than bytes, so this function will first encode the characters from the string -as UTF-8, and then apply Base64 encoding to the result. - -The Terraform language applies Unicode normalization to all strings, and so -passing a string through `base64decode` and then `base64encode` may not yield -the original result exactly. - -While we do not recommend manipulating large, raw binary data in the Terraform -language, Base64 encoding is the standard way to represent arbitrary byte -sequences, and so resource types that accept or return binary data will use -Base64 themselves, and so this function exists primarily to allow string -data to be easily provided to resource types that expect Base64 bytes. - -`base64encode` is, in effect, a shorthand for calling -[`textencodebase64`](/terraform/language/functions/textencodebase64) with the encoding name set to -`UTF-8`. - -## Examples - -``` -> base64encode("Hello World") -SGVsbG8gV29ybGQ= -``` - -## Related Functions - -* [`base64decode`](/terraform/language/functions/base64decode) performs the opposite operation, - decoding Base64 data and interpreting it as a UTF-8 string. -* [`textencodebase64`](/terraform/language/functions/textencodebase64) is a more general function that - supports character encodings other than UTF-8. -* [`base64gzip`](/terraform/language/functions/base64gzip) applies gzip compression to a string - and returns the result with Base64 encoding all in one operation. -* [`filebase64`](/terraform/language/functions/filebase64) reads a file from the local filesystem - and returns its raw bytes with Base64 encoding, without creating an - intermediate Unicode string. diff --git a/website/docs/language/functions/base64gzip.mdx b/website/docs/language/functions/base64gzip.mdx deleted file mode 100644 index 517091a405..0000000000 --- a/website/docs/language/functions/base64gzip.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -page_title: base64gzip function reference - Functions - Configuration Language -description: |- - The base64encode function compresses an HCL string using gzip, and then encodes it using Base64 encoding. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `base64gzip` function reference - -This topic provides reference information about the `base64gzip` function. -The `base64gzip` function compresses an HCL string using gzip and then encodes the string using Base64 encoding. - -## Introduction - -You can use the `base64gzip` function to compress an HCL string and then encode it in the Base64 format. -Terraform uses the standard Base64 alphabet that is defined in [RFC 4648](https://datatracker.ietf.org/doc/html/rfc4648#section-4). - -While HashiCorp does not recommend manipulating large, raw binary data in HCL, Base64 encoding can be an effective way to represent small binary objects in memory when you need to pass them as values, rather than referring to files on disk. -For example, you could use the `base64gzip` function to compress a large JSON string so that you can upload it to S3. - -Because HCL strings are sequences of unicode characters rather than bytes, `base64gzip` first encodes the characters in the string as UTF-8. -Then it applies gzip compression and encodes the string using Base64 format. - -## Syntax - -Use the `base64gzip` function with the following syntax: - -```hcl -base64gzip(ARGS) -``` - -The argument is the string that you want to compress and encode. - -In the following example, the function compresses the string at `local.my_data` and encodes it using the Base64 format. - -```hcl -base64gzip(local.my_data) -``` - -## Example use case - -The following example defines a local value `my_data` that contains the string you want to compress and encode. -The `base64gzip` function compresses and encodes the string, and then it is used to populate an S3 bucket. - -```hcl -resource "aws_s3_object" "example" { - bucket = "my_bucket" - key = "example.txt" - content_base64 = base64gzip(local.my_data) - content_encoding = "gzip" -} -``` - -## Related functions - -* [`base64encode`](/terraform/language/functions/base64encode) applies Base64 encoding to an HCL string without using gzip compression. -* [`filebase64`](/terraform/language/functions/filebase64) reads a file from the local filesystem and encodes its raw bits using the Base64 format. diff --git a/website/docs/language/functions/base64sha256.mdx b/website/docs/language/functions/base64sha256.mdx deleted file mode 100644 index 2baf272535..0000000000 --- a/website/docs/language/functions/base64sha256.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: base64sha256 - Functions - Configuration Language -description: |- - The base64sha256 function computes the SHA256 hash of a given string and - encodes it with Base64. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `base64sha256` Function - -`base64sha256` computes the SHA256 hash of a given string and encodes it with -Base64. This is not equivalent to `base64encode(sha256("test"))` since `sha256()` -returns hexadecimal representation. - -The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied -as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is -then encoded with Base64 before returning. Terraform uses the "standard" Base64 -alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -## Examples - -``` -> base64sha256("hello world") -uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek= -``` - -## Related Functions - -* [`filebase64sha256`](/terraform/language/functions/filebase64sha256) calculates the same hash from - the contents of a file rather than from a string value. -* [`sha256`](/terraform/language/functions/sha256) calculates the same hash but returns the result - in a more-verbose hexadecimal encoding. diff --git a/website/docs/language/functions/base64sha512.mdx b/website/docs/language/functions/base64sha512.mdx deleted file mode 100644 index 4ddc7e1664..0000000000 --- a/website/docs/language/functions/base64sha512.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: base64sha512 - Functions - Configuration Language -description: |- - The base64sha512 function computes the SHA512 hash of a given string and - encodes it with Base64. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `base64sha512` Function - -`base64sha512` computes the SHA512 hash of a given string and encodes it with -Base64. This is not equivalent to `base64encode(sha512("test"))` since `sha512()` -returns hexadecimal representation. - -The given string is first encoded as UTF-8 and then the SHA512 algorithm is applied -as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is -then encoded with Base64 before returning. Terraform uses the "standard" Base64 -alphabet as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -## Examples - -``` -> base64sha512("hello world") -MJ7MSJwS1utMxA9QyQLytNDtd+5RGnx6m808qG1M2G+YndNbxf9JlnDaNCVbRbDP2DDoH2Bdz33FVC6TrpzXbw== -``` - -## Related Functions - -* [`filebase64sha512`](/terraform/language/functions/filebase64sha512) calculates the same hash from - the contents of a file rather than from a string value. -* [`sha512`](/terraform/language/functions/sha512) calculates the same hash but returns the result - in a more-verbose hexadecimal encoding. diff --git a/website/docs/language/functions/basename.mdx b/website/docs/language/functions/basename.mdx deleted file mode 100644 index c911a18155..0000000000 --- a/website/docs/language/functions/basename.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -page_title: basename - Functions - Configuration Language -description: |- - The basename function removes all except the last portion from a filesystem - path. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `basename` Function - -`basename` takes a string containing a filesystem path and removes all except -the last portion from it. - -This function works only with the path string and does not access the -filesystem itself. It is therefore unable to take into account filesystem -features such as symlinks. - -If the path is empty then the result is `"."`, representing the current -working directory. - -The behavior of this function depends on the host platform. On Windows systems, -it uses backslash `\` as the path segment separator. On Unix systems, the slash -`/` is used. - -Referring directly to filesystem paths in resource arguments may cause -spurious diffs if the same configuration is applied from multiple systems or on -different host operating systems. We recommend using filesystem paths only -for transient values, such as the argument to [`file`](/terraform/language/functions/file) (where -only the contents are then stored) or in `connection` and `provisioner` blocks. - -## Examples - -``` -> basename("foo/bar/baz.txt") -baz.txt -``` - -## Related Functions - -* [`dirname`](/terraform/language/functions/dirname) returns all of the segments of a filesystem path - _except_ the last, discarding the portion that would be returned by - `basename`. diff --git a/website/docs/language/functions/bcrypt.mdx b/website/docs/language/functions/bcrypt.mdx deleted file mode 100644 index d040ab96fd..0000000000 --- a/website/docs/language/functions/bcrypt.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -page_title: bcrypt - Functions - Configuration Language -description: |- - The bcrypt function computes a hash of the given string using the Blowfish - cipher. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `bcrypt` Function - -`bcrypt` computes a hash of the given string using the Blowfish cipher, -returning a string in -[the _Modular Crypt Format_](https://passlib.readthedocs.io/en/stable/modular_crypt_format.html) -usually expected in the shadow password file on many Unix systems. - -```hcl -bcrypt(string, cost) -``` - -The `cost` argument is optional and will default to 10 if unspecified. - -Since a bcrypt hash value includes a randomly selected salt, each call to this -function will return a different value, even if the given string and cost are -the same. Using this function directly with resource arguments will therefore -cause spurious diffs. We recommend using this function only in `provisioner` -blocks, or in data resources whose results are only used in `provisioner` -blocks. - -The version prefix on the generated string (e.g. `$2a$`) may change in future -versions of Terraform. - -## Examples - -``` -> bcrypt("hello world") -$2a$10$D5grTTzcsqyvAeIAnY/mYOIqliCoG7eAMX0/oFcuD.iErkksEbcAa -``` diff --git a/website/docs/language/functions/can.mdx b/website/docs/language/functions/can.mdx deleted file mode 100644 index d3d159bb77..0000000000 --- a/website/docs/language/functions/can.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -page_title: can - Functions - Configuration Language -description: |- - The can function tries to evaluate an expression given as an argument and - indicates whether the evaluation succeeded. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `can` Function - -`can` evaluates the given expression and returns a boolean value indicating -whether the expression produced a result without any errors. - -This is a special function that is able to catch errors produced when evaluating -its argument. For most situations where you could use `can` it's better to use -[`try`](/terraform/language/functions/try) instead, because it allows for more concise definition of -fallback values for failing expressions. - -The primary purpose of `can` is to turn an error condition into a boolean -validation result when writing -[custom variable validation rules](/terraform/language/values/variables#custom-validation-rules). -For example: - -```hcl -variable "timestamp" { - type = string - - validation { - # formatdate fails if the second argument is not a valid timestamp - condition = can(formatdate("", var.timestamp)) - error_message = "The timestamp argument requires a valid RFC 3339 timestamp." - } -} -``` - -The `can` function can only catch and handle _dynamic_ errors resulting from -access to data that isn't known until runtime. It will not catch errors -relating to expressions that can be proven to be invalid for any input, such -as a malformed resource reference. - -~> **Warning:** The `can` function is intended only for simple tests in -variable validation rules. Although it can technically accept any sort of -expression and be used elsewhere in the configuration, we recommend against -using it in other contexts. For error handling elsewhere in the configuration, -prefer to use [`try`](/terraform/language/functions/try). - -## Examples - -``` -> local.foo -{ - "bar" = "baz" -} -> can(local.foo.bar) -true -> can(local.foo.boop) -false -``` - -The `can` function will _not_ catch errors relating to constructs that are -provably invalid even before dynamic expression evaluation, such as a malformed -reference or a reference to a top-level object that has not been declared: - -``` -> can(local.nonexist) - -Error: Reference to undeclared local value - -A local value with the name "nonexist" has not been declared. -``` - -## Related Functions - -* [`try`](/terraform/language/functions/try), which tries evaluating a sequence of expressions and - returns the result of the first one that succeeds. diff --git a/website/docs/language/functions/ceil.mdx b/website/docs/language/functions/ceil.mdx deleted file mode 100644 index 7d663c1b9f..0000000000 --- a/website/docs/language/functions/ceil.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -page_title: ceil - Functions - Configuration Language -description: |- - The ceil function returns the closest whole number greater than or equal to - the given value. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `ceil` Function - -`ceil` returns the closest whole number that is greater than or equal to the -given value, which may be a fraction. - -## Examples - -``` -> ceil(5) -5 -> ceil(5.1) -6 -``` - -## Related Functions - -* [`floor`](/terraform/language/functions/floor), which rounds to the nearest whole number _less than_ - or equal. diff --git a/website/docs/language/functions/chomp.mdx b/website/docs/language/functions/chomp.mdx deleted file mode 100644 index ae6c6b08da..0000000000 --- a/website/docs/language/functions/chomp.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: chomp - Functions - Configuration Language -description: The chomp function removes newline characters at the end of a string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `chomp` Function - -`chomp` removes newline characters at the end of a string. - -This can be useful if, for example, the string was read from a file that has -a newline character at the end. - -## Examples - -``` -> chomp("hello\n") -hello -> chomp("hello\r\n") -hello -> chomp("hello\n\n") -hello -``` - -## Related Functions - -* [`trimspace`](/terraform/language/functions/trimspace), which removes all types of whitespace from - both the start and the end of a string. diff --git a/website/docs/language/functions/chunklist.mdx b/website/docs/language/functions/chunklist.mdx deleted file mode 100644 index a4a6b097d4..0000000000 --- a/website/docs/language/functions/chunklist.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -page_title: chunklist - Functions - Configuration Language -description: |- - The chunklist function splits a single list into fixed-size chunks, returning - a list of lists. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `chunklist` Function - -`chunklist` splits a single list into fixed-size chunks, returning a list -of lists. - -```hcl -chunklist(list, chunk_size) -``` - -## Examples - -``` -> chunklist(["a", "b", "c", "d", "e"], 2) -[ - [ - "a", - "b", - ], - [ - "c", - "d", - ], - [ - "e", - ], -] -> chunklist(["a", "b", "c", "d", "e"], 1) -[ - [ - "a", - ], - [ - "b", - ], - [ - "c", - ], - [ - "d", - ], - [ - "e", - ], -] -``` diff --git a/website/docs/language/functions/cidrhost.mdx b/website/docs/language/functions/cidrhost.mdx deleted file mode 100644 index 421f9235ce..0000000000 --- a/website/docs/language/functions/cidrhost.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -page_title: cidrhost - Functions - Configuration Language -description: |- - The cidrhost function calculates a full host IP address within a given - IP network address prefix. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `cidrhost` Function - -`cidrhost` calculates a full host IP address for a given host number within -a given IP network address prefix. - -```hcl -cidrhost(prefix, hostnum) -``` - -`prefix` must be given in CIDR notation, as defined in -[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1). - -`hostnum` is a whole number that can be represented as a binary integer with -no more than the number of digits remaining in the address after the given -prefix. If `hostnum` is negative, the count starts from the end of the range. -For example, `cidrhost("10.0.0.0/8", 2)` returns `10.0.0.2` and -`cidrhost("10.0.0.0/8", -2)` returns `10.255.255.254`. - -For more details on how this function interprets CIDR prefixes and -populates host numbers, see the worked example for -[`cidrsubnet`](/terraform/language/functions/cidrsubnet). - -Conventionally host number zero is used to represent the address of the -network itself and the host number that would fill all the host bits with -binary 1 represents the network's broadcast address. These numbers should -generally not be used to identify individual hosts except in unusual -situations, such as point-to-point links. - -This function accepts both IPv6 and IPv4 prefixes, and the result always uses -the same addressing scheme as the given prefix. - --> **Note:** As a historical accident, this function interprets IPv4 address -octets that have leading zeros as decimal numbers, which is contrary to some -other systems which interpret them as octal. We have preserved this behavior -for backward compatibility, but recommend against relying on this behavior. - -## Examples - -``` -> cidrhost("10.12.112.0/20", 16) -10.12.112.16 -> cidrhost("10.12.112.0/20", 268) -10.12.113.12 -> cidrhost("fd00:fd12:3456:7890:00a2::/72", 34) -fd00:fd12:3456:7890::22 -``` - -## Related Functions - -* [`cidrsubnet`](/terraform/language/functions/cidrsubnet) calculates a subnet address under a given - network address prefix. diff --git a/website/docs/language/functions/cidrnetmask.mdx b/website/docs/language/functions/cidrnetmask.mdx deleted file mode 100644 index 4d1ed437f3..0000000000 --- a/website/docs/language/functions/cidrnetmask.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -page_title: cidrnetmask - Functions - Configuration Language -description: |- - The cidrnetmask function converts an IPv4 address prefix given in CIDR - notation into a subnet mask address. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `cidrnetmask` Function - -`cidrnetmask` converts an IPv4 address prefix given in CIDR notation into -a subnet mask address. - -```hcl -cidrnetmask(prefix) -``` - -`prefix` must be given in IPv4 CIDR notation, as defined in -[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1). - -The result is a subnet address formatted in the conventional dotted-decimal -IPv4 address syntax, as expected by some software. - -The `cidrnetmask` function only accepts IPv4 addresses in CIDR notation. -If you use an IPv6 address, `cidrnetmask` returns an error. - --> **Note:** As a historical accident, this function interprets IPv4 address -octets that have leading zeros as decimal numbers, which is contrary to some -other systems which interpret them as octal. We have preserved this behavior -for backward compatibility, but recommend against relying on this behavior. - -## Examples - -``` -> cidrnetmask("172.16.0.0/12") -255.240.0.0 -``` diff --git a/website/docs/language/functions/cidrsubnet.mdx b/website/docs/language/functions/cidrsubnet.mdx deleted file mode 100644 index 58e704642e..0000000000 --- a/website/docs/language/functions/cidrsubnet.mdx +++ /dev/null @@ -1,177 +0,0 @@ ---- -page_title: cidrsubnet - Functions - Configuration Language -description: |- - The cidrsubnet function calculates a subnet address within a given IP network - address prefix. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `cidrsubnet` Function - -`cidrsubnet` calculates a subnet address within given IP network address prefix. - -```hcl -cidrsubnet(prefix, newbits, netnum) -``` - -`prefix` must be given in CIDR notation, as defined in -[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1). - -`newbits` is the number of additional bits with which to extend the prefix. -For example, if given a prefix ending in `/16` and a `newbits` value of -`4`, the resulting subnet address will have length `/20`. - -`netnum` is a whole number that can be represented as a binary integer with -no more than `newbits` binary digits, which will be used to populate the -additional bits added to the prefix. - -This function accepts both IPv6 and IPv4 prefixes, and the result always uses -the same addressing scheme as the given prefix. - -Unlike the related function [`cidrsubnets`](/terraform/language/functions/cidrsubnets), `cidrsubnet` -allows you to give a specific network number to use. `cidrsubnets` can allocate -multiple network addresses at once, but numbers them automatically starting -with zero. - --> **Note:** As a historical accident, this function interprets IPv4 address -octets that have leading zeros as decimal numbers, which is contrary to some -other systems which interpret them as octal. We have preserved this behavior -for backward compatibility, but recommend against relying on this behavior. - -## Examples - -``` -> cidrsubnet("172.16.0.0/12", 4, 2) -172.18.0.0/16 -> cidrsubnet("10.1.2.0/24", 4, 15) -10.1.2.240/28 -> cidrsubnet("fd00:fd12:3456:7890::/56", 16, 162) -fd00:fd12:3456:7800:a200::/72 -``` - -## Netmasks and Subnets - -Using `cidrsubnet` requires familiarity with some network addressing concepts. - -The most important idea is that an IP address (whether IPv4 or IPv6) is -fundamentally constructed from binary digits, even though we conventionally -represent it as either four decimal octets (for IPv4) or a sequence of 16-bit -hexadecimal numbers (for IPv6). - -Taking our example above of `cidrsubnet("10.1.2.0/24", 4, 15)`, the function -will first convert the given IP address string into an equivalent binary -representation: - -``` - 10 . 1 . 2 . 0 -00001010 00000001 00000010 | 00000000 - network | host -``` - -The `/24` at the end of the prefix string specifies that the first 24 -bits -- or, the first three octets -- of the address identify the network -while the remaining bits (32 - 24 = 8 bits in this case) identify hosts -within the network. - -The CLI tool [`ipcalc`](https://gitlab.com/ipcalc/ipcalc) is useful for -visualizing CIDR prefixes as binary numbers. We can confirm the conversion -above by providing the same prefix string to `ipcalc`: - -``` -$ ipcalc 10.1.2.0/24 -Address: 10.1.2.0 00001010.00000001.00000010. 00000000 -Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000 -Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111 -=> -Network: 10.1.2.0/24 00001010.00000001.00000010. 00000000 -HostMin: 10.1.2.1 00001010.00000001.00000010. 00000001 -HostMax: 10.1.2.254 00001010.00000001.00000010. 11111110 -Broadcast: 10.1.2.255 00001010.00000001.00000010. 11111111 -Hosts/Net: 254 Class A, Private Internet -``` - -This gives us some additional information but also confirms (using a slightly -different notation) the conversion from decimal to binary and shows the range -of possible host addresses in this network. - -While [`cidrhost`](/terraform/language/functions/cidrhost) allows calculating single host IP addresses, -`cidrsubnet` on the other hand creates a new network prefix _within_ the given -network prefix. In other words, it creates a subnet. - -When we call `cidrsubnet` we also pass two additional arguments: `newbits` and -`netnum`. `newbits` decides how much longer the resulting prefix will be in -bits; in our example here we specified `4`, which means that the resulting -subnet will have a prefix length of 24 + 4 = 28 bits. We can imagine these -bits breaking down as follows: - -``` - 10 . 1 . 2 . ? 0 -00001010 00000001 00000010 | XXXX | 0000 - parent network | netnum | host -``` - -Four of the eight bits that were originally the "host number" are now being -repurposed as the subnet number. The network prefix no longer falls on an -exact octet boundary, so in effect we are now splitting the last decimal number -in the IP address into two parts, using half of it to represent the subnet -number and the other half to represent the host number. - -The `netnum` argument then decides what number value to encode into those -four new subnet bits. In our current example we passed `15`, which is -represented in binary as `1111`, allowing us to fill in the `XXXX` segment -in the above: - -``` - 10 . 1 . 2 . 15 0 -00001010 00000001 00000010 | 1111 | 0000 - parent network | netnum | host -``` - -To convert this back into normal decimal notation we need to recombine the -two portions of the final octet. Converting `11110000` from binary to decimal -gives 240, which can then be combined with our new prefix length of 28 to -produce the result `10.1.2.240/28`. Again we can pass this prefix string to -`ipcalc` to visualize it: - -``` -$ ipcalc 10.1.2.240/28 -Address: 10.1.2.240 00001010.00000001.00000010.1111 0000 -Netmask: 255.255.255.240 = 28 11111111.11111111.11111111.1111 0000 -Wildcard: 0.0.0.15 00000000.00000000.00000000.0000 1111 -=> -Network: 10.1.2.240/28 00001010.00000001.00000010.1111 0000 -HostMin: 10.1.2.241 00001010.00000001.00000010.1111 0001 -HostMax: 10.1.2.254 00001010.00000001.00000010.1111 1110 -Broadcast: 10.1.2.255 00001010.00000001.00000010.1111 1111 -Hosts/Net: 14 Class A, Private Internet -``` - -The new subnet has four bits available for host numbering, which means -that there are 14 host addresses available for assignment once we subtract -the network's own address and the broadcast address. You can thus use -[`cidrhost`](/terraform/language/functions/cidrhost) function to calculate those host addresses by -providing it a value between 1 and 14: - -``` -> cidrhost("10.1.2.240/28", 1) -10.1.2.241 -> cidrhost("10.1.2.240/28", 14) -10.1.2.254 -``` - -For more information on CIDR notation and subnetting, see -[Classless Inter-domain Routing](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). - -## Related Functions - -* [`cidrhost`](/terraform/language/functions/cidrhost) calculates the IP address for a single host - within a given network address prefix. -* [`cidrnetmask`](/terraform/language/functions/cidrnetmask) converts an IPv4 network prefix in CIDR - notation into netmask notation. -* [`cidrsubnets`](/terraform/language/functions/cidrsubnets) can allocate multiple consecutive - addresses under a prefix at once, numbering them automatically. diff --git a/website/docs/language/functions/cidrsubnets.mdx b/website/docs/language/functions/cidrsubnets.mdx deleted file mode 100644 index b5e384224c..0000000000 --- a/website/docs/language/functions/cidrsubnets.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -page_title: cidrsubnets - Functions - Configuration Language -description: |- - The cidrsubnets function calculates a sequence of consecutive IP address - ranges within a particular CIDR prefix. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `cidrsubnets` Function - -`cidrsubnets` calculates a sequence of consecutive IP address ranges within -a particular CIDR prefix. - -```hcl -cidrsubnets(prefix, newbits...) -``` - -`prefix` must be given in CIDR notation, as defined in -[RFC 4632 section 3.1](https://tools.ietf.org/html/rfc4632#section-3.1). - -The remaining arguments, indicated as `newbits` above, each specify the number -of additional network prefix bits for one returned address range. The return -value is therefore a list with one element per `newbits` argument, each -a string containing an address range in CIDR notation. - -For more information on IP addressing concepts, see the documentation for the -related function [`cidrsubnet`](/terraform/language/functions/cidrsubnet). `cidrsubnet` calculates -a single subnet address within a prefix while allowing you to specify its -subnet number, while `cidrsubnets` can calculate many at once, potentially of -different sizes, and assigns subnet numbers automatically. - -When using this function to partition an address space as part of a network -address plan, you must not change any of the existing arguments once network -addresses have been assigned to real infrastructure, or else later address -assignments will be invalidated. However, you _can_ append new arguments to -existing calls safely, as long as there is sufficient address space available. - -This function accepts both IPv6 and IPv4 prefixes, and the result always uses -the same addressing scheme as the given prefix. - --> **Note:** As a historical accident, this function interprets IPv4 address -octets that have leading zeros as decimal numbers, which is contrary to some -other systems which interpret them as octal. We have preserved this behavior -for backward compatibility, but recommend against relying on this behavior. - --> **Note:** [The Terraform module `hashicorp/subnets/cidr`](https://registry.terraform.io/modules/hashicorp/subnets/cidr) -wraps `cidrsubnets` to provide additional functionality for assigning symbolic -names to your networks and skipping prefixes for obsolete allocations. Its -documentation includes usage examples for several popular cloud virtual network -platforms. - -## Examples - -``` -> cidrsubnets("10.1.0.0/16", 4, 4, 8, 4) -[ - "10.1.0.0/20", - "10.1.16.0/20", - "10.1.32.0/24", - "10.1.48.0/20", -] - -> cidrsubnets("fd00:fd12:3456:7890::/56", 16, 16, 16, 32) -[ - "fd00:fd12:3456:7800::/72", - "fd00:fd12:3456:7800:100::/72", - "fd00:fd12:3456:7800:200::/72", - "fd00:fd12:3456:7800:300::/88", -] -``` - -You can use nested `cidrsubnets` calls with -[`for` expressions](/terraform/language/expressions/for) -to concisely allocate groups of network address blocks: - -``` -> [for cidr_block in cidrsubnets("10.0.0.0/8", 8, 8, 8, 8) : cidrsubnets(cidr_block, 4, 4)] -[ - [ - "10.0.0.0/20", - "10.0.16.0/20", - ], - [ - "10.1.0.0/20", - "10.1.16.0/20", - ], - [ - "10.2.0.0/20", - "10.2.16.0/20", - ], - [ - "10.3.0.0/20", - "10.3.16.0/20", - ], -] -``` - -## Related Functions - -* [`cidrhost`](/terraform/language/functions/cidrhost) calculates the IP address for a single host - within a given network address prefix. -* [`cidrnetmask`](/terraform/language/functions/cidrnetmask) converts an IPv4 network prefix in CIDR - notation into netmask notation. -* [`cidrsubnet`](/terraform/language/functions/cidrsubnet) calculates a single subnet address, allowing - you to specify its network number. diff --git a/website/docs/language/functions/coalesce.mdx b/website/docs/language/functions/coalesce.mdx deleted file mode 100644 index 1aaa34e5a8..0000000000 --- a/website/docs/language/functions/coalesce.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -page_title: coalesce - Functions - Configuration Language -description: |- - The coalesce function takes any number of arguments and returns the - first one that isn't null nor empty. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `coalesce` Function - -`coalesce` takes any number of arguments and returns the first one -that isn't null or an empty string. - -All of the arguments must be of the same type. Terraform will try to -convert mismatched arguments to the most general of the types that all -arguments can convert to, or return an error if the types are incompatible. -The result type is the same as the type of all of the arguments. - -## Examples - -``` -> coalesce("a", "b") -a -> coalesce("", "b") -b -> coalesce(1,2) -1 -``` - -To perform the `coalesce` operation with a list of strings, use the `...` -symbol to expand the list as arguments: - -``` -> coalesce(["", "b"]...) -b -``` - -Terraform attempts to select a result type that all of the arguments can -convert to, so mixing argument types may produce surprising results due to -Terraform's automatic type conversion rules: - -``` -> coalesce(1, "hello") -"1" -> coalesce(true, "hello") -"true" -> coalesce({}, "hello") - -Error: Error in function call - -Call to function "coalesce" failed: all arguments must have the same type. -``` - -## Related Functions - -* [`coalescelist`](/terraform/language/functions/coalescelist) performs a similar operation with - list arguments rather than individual arguments. diff --git a/website/docs/language/functions/coalescelist.mdx b/website/docs/language/functions/coalescelist.mdx deleted file mode 100644 index 95c8ded788..0000000000 --- a/website/docs/language/functions/coalescelist.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: coalescelist - Functions - Configuration Language -description: |- - The coalescelist function takes any number of list arguments and returns the - first one that isn't empty. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `coalescelist` Function - -`coalescelist` takes any number of list arguments and returns the first one -that isn't empty. - -## Examples - -``` -> coalescelist(["a", "b"], ["c", "d"]) -[ - "a", - "b", -] -> coalescelist([], ["c", "d"]) -[ - "c", - "d", -] -``` - -To perform the `coalescelist` operation with a list of lists, use the `...` -symbol to expand the outer list as arguments: - -``` -> coalescelist([[], ["c", "d"]]...) -[ - "c", - "d", -] -``` - -## Related Functions - -* [`coalesce`](/terraform/language/functions/coalesce) performs a similar operation with string - arguments rather than list arguments. diff --git a/website/docs/language/functions/compact.mdx b/website/docs/language/functions/compact.mdx deleted file mode 100644 index 03dad3cbf5..0000000000 --- a/website/docs/language/functions/compact.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -page_title: compact - Functions - Configuration Language -description: The compact function removes null or empty string elements from a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `compact` Function - -`compact` takes a list of strings and returns a new list with any null or empty string -elements removed. - -## Examples - -``` -> compact(["a", "", "b", null, "c"]) -[ - "a", - "b", - "c", -] -``` diff --git a/website/docs/language/functions/concat.mdx b/website/docs/language/functions/concat.mdx deleted file mode 100644 index 2d5f1d25e6..0000000000 --- a/website/docs/language/functions/concat.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: concat - Functions - Configuration Language -description: The concat function combines two or more lists into a single list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `concat` Function - -`concat` takes two or more lists and combines them into a single list. - -## Examples - -``` -> concat(["a", ""], ["b", "c"]) -[ - "a", - "", - "b", - "c", -] - -# Can do multiple lists of mixed types, arguments can also be empty lists -concat([], [1, "a"], [[3], "c"]) -[ - 1, - "a", - [ - 3, - ], - "c", -] -``` diff --git a/website/docs/language/functions/contains.mdx b/website/docs/language/functions/contains.mdx deleted file mode 100644 index b06c17da20..0000000000 --- a/website/docs/language/functions/contains.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -page_title: contains - Functions - Configuration Language -description: The contains function determines whether a list or set contains a given value. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `contains` Function - -`contains` determines whether the list, tuple, or set given in its first -argument contains at least one element that is equal to the value in the second -argument, using the same definition of equality as the `==` operator described in -[Equality Operators](/terraform/language/expressions/operators#equality-operators). - -```hcl -contains(list, value) -``` - -## Examples - -``` -> contains(["a", "b", "c"], "a") -true -> contains(["a", "b", "c"], "d") -false -``` diff --git a/website/docs/language/functions/csvdecode.mdx b/website/docs/language/functions/csvdecode.mdx deleted file mode 100644 index ab83c7f7e1..0000000000 --- a/website/docs/language/functions/csvdecode.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -page_title: csvdecode - Functions - Configuration Language -description: The csvdecode function decodes CSV data into a list of maps. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `csvdecode` Function - -`csvdecode` decodes a string containing CSV-formatted data and produces a -list of maps representing that data. - -CSV is _Comma-separated Values_, an encoding format for tabular data. There -are many variants of CSV, but this function implements the format defined -in [RFC 4180](https://tools.ietf.org/html/rfc4180). - -The first line of the CSV data is interpreted as a "header" row: the values -given are used as the keys in the resulting maps. Each subsequent line becomes -a single map in the resulting list, matching the keys from the header row -with the given values by index. All lines in the file must contain the same -number of fields, or this function will produce an error. - -## Examples - -``` -> csvdecode("a,b,c\n1,2,3\n4,5,6") -[ - { - "a" = "1" - "b" = "2" - "c" = "3" - }, - { - "a" = "4" - "b" = "5" - "c" = "6" - } -] -``` - -## Use with the `for_each` meta-argument - -You can use the result of `csvdecode` with -[the `for_each` meta-argument](/terraform/language/meta-arguments/for_each) -to describe a collection of similar objects whose differences are -described by the rows in the given CSV file. - -There must be one column in the CSV file that can serve as a unique id for each -row, which we can then use as the tracking key for the individual instances in -the `for_each` expression. For example: - -```hcl -locals { - # We've included this inline to create a complete example, but in practice - # this is more likely to be loaded from a file using the "file" function. - csv_data = <<-CSV - local_id,instance_type,ami - foo1,t2.micro,ami-54d2a63b - foo2,t2.micro,ami-54d2a63b - foo3,t2.micro,ami-54d2a63b - bar1,m3.large,ami-54d2a63b - CSV - - instances = csvdecode(local.csv_data) -} - -resource "aws_instance" "example" { - for_each = tomap({ for inst in local.instances : inst.local_id => inst }) - - instance_type = each.value.instance_type - ami = each.value.ami -} -``` - -The `for` expression in our `for_each` argument transforms the list produced -by `csvdecode` into a map using the `local_id` as a key, which tells -Terraform to use the `local_id` value to track each instance it creates. -Terraform will create and manage the following instance addresses: - -- `aws_instance.example["foo1"]` -- `aws_instance.example["foo2"]` -- `aws_instance.example["foo3"]` -- `aws_instance.example["bar1"]` - -If you modify a row in the CSV on a subsequent plan, Terraform will interpret -that as an update to the existing object as long as the `local_id` value is -unchanged. If you add or remove rows from the CSV then Terraform will plan to -create or destroy associated instances as appropriate. - -If there is no reasonable value you can use as a unique identifier in your CSV -then you could instead use -[the `count` meta-argument](/terraform/language/meta-arguments/count) -to define an object for each CSV row, with each one identified by its index into -the list returned by `csvdecode`. However, in that case any future updates to -the CSV may be disruptive if they change the positions of particular objects in -the list. We recommend using `for_each` with a unique id column to make -behavior more predictable on future changes. diff --git a/website/docs/language/functions/dirname.mdx b/website/docs/language/functions/dirname.mdx deleted file mode 100644 index 8905e096ff..0000000000 --- a/website/docs/language/functions/dirname.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -page_title: dirname - Functions - Configuration Language -description: The dirname function removes the last portion from a filesystem path. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `dirname` Function - -`dirname` takes a string containing a filesystem path and removes the last -portion from it. - -This function works only with the path string and does not access the -filesystem itself. It is therefore unable to take into account filesystem -features such as symlinks. - -If the path is empty then the result is `"."`, representing the current -working directory. - -The behavior of this function depends on the host platform. On Windows systems, -it uses backslash `\` as the path segment separator. On Unix systems, the slash -`/` is used. The result of this function is normalized, so on a Windows system -any slashes in the given path will be replaced by backslashes before returning. - -Referring directly to filesystem paths in resource arguments may cause -spurious diffs if the same configuration is applied from multiple systems or on -different host operating systems. We recommend using filesystem paths only -for transient values, such as the argument to [`file`](/terraform/language/functions/file) (where -only the contents are then stored) or in `connection` and `provisioner` blocks. - -## Examples - -``` -> dirname("foo/bar/baz.txt") -foo/bar -``` - -## Related Functions - -* [`basename`](/terraform/language/functions/basename) returns _only_ the last portion of a filesystem - path, discarding the portion that would be returned by `dirname`. diff --git a/website/docs/language/functions/distinct.mdx b/website/docs/language/functions/distinct.mdx deleted file mode 100644 index 48d5f7e0ec..0000000000 --- a/website/docs/language/functions/distinct.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -page_title: distinct - Functions - Configuration Language -description: The distinct function removes duplicate elements from a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `distinct` Function - -`distinct` takes a list and returns a new list with any duplicate elements -removed. - -The first occurrence of each value is retained and the relative ordering of -these elements is preserved. - -## Examples - -``` -> distinct(["a", "b", "a", "c", "d", "b"]) -[ - "a", - "b", - "c", - "d", -] -``` diff --git a/website/docs/language/functions/element.mdx b/website/docs/language/functions/element.mdx deleted file mode 100644 index 25ea4a0464..0000000000 --- a/website/docs/language/functions/element.mdx +++ /dev/null @@ -1,51 +0,0 @@ ---- -page_title: element - Functions - Configuration Language -description: The element function retrieves a single element from a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `element` Function - -`element` retrieves a single element from a list. - -```hcl -element(list, index) -``` - -The index is zero-based. This function produces an error if used with an -empty list. The index can be a negative integer. - -Use the built-in index syntax `list[index]` in most cases. Use this function -only for the special additional "wrap-around" behavior described below. - -## Examples - -``` -> element(["a", "b", "c"], 1) -"b" -``` - -If the given index is greater than the length of the list then the index is -"wrapped around" by taking the index modulo the length of the list: - -``` -> element(["a", "b", "c"], 3) -"a" -``` - -To get the last element from the list use the index `-1`: - -``` -> element(["a", "b", "c"], -1) -"c" -``` - -## Related Functions - -* [`index`](/terraform/language/functions/index_function) finds the index for a particular element value. -* [`lookup`](/terraform/language/functions/lookup) retrieves a value from a _map_ given its _key_. diff --git a/website/docs/language/functions/endswith.mdx b/website/docs/language/functions/endswith.mdx deleted file mode 100644 index a03a3b0f90..0000000000 --- a/website/docs/language/functions/endswith.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: endswith - Functions - Configuration Language -description: |- - The endswith function takes two values: a string to check and a suffix string. It returns true if the first string ends with that exact suffix. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `endswith` Function - -`endswith` takes two values: a string to check and a suffix string. The function returns true if the first string ends with that exact suffix. - -```hcl -endswith(string, suffix) -``` - -## Examples - -``` -> endswith("hello world", "world") -true - -> endswith("hello world", "hello") -false -``` - -## Related Functions - -- [`startswith`](/terraform/language/functions/startswith) takes two values: a string to check and a prefix string. The function returns true if the string begins with that exact prefix. diff --git a/website/docs/language/functions/ephemeralasnull.mdx b/website/docs/language/functions/ephemeralasnull.mdx deleted file mode 100644 index 778e04ae30..0000000000 --- a/website/docs/language/functions/ephemeralasnull.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -page_title: ephemeralasnull function reference - Functions - Configuration Language -description: |- - The `ephemeralasnull` function accepts an ephemeral value and returns null. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `ephemeralasnull` function reference - --> **Note**: The `ephemeralasnull` function is available in Terraform v1.10 and later. - -This topic provides reference information about the `ephemeralasnull` function. The `ephemeralasnull` function accepts an ephemeral value and returns `null`. - -## Introduction - -You can use the `ephemeralasnull` function to nullify ephemeral values. For example, if you pass an object with a nested ephemeral value to `ephemeralasnull`,it nullifies any ephemeral values within that object. - -## Syntax - -Use the `ephemeralasnull` function with the following syntax: - -```hcl -ephemeralasnull(var.my_ephemeral_value) -``` - -In the following example, you can pass the `ephemeralasnull` function an ephemeral value, and the function returns `null`: - -```hcl -variable "example" { - type = string - default = "test" - ephemeral = true -} - -# This output returns null. -output "example_output" { - value = ephemeralasnull(var.example) -} -``` - -For more information on which Terraform blocks can be ephemeral, refer to ephemeral [inputs](/terraform/language/values/variables#exclude-values-from-state), [outputs](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files), and [resources](/terraform/language/resources/ephemeral). - -## Example use case - -The following example shows how you can use the `ephemeralasnull` function to intake a map that contains some ephemeral values, and output the values that are not ephemeral. - -```hcl -variable "session_token" { - type = string - default = "test" - ephemeral = true -} - -variable "configuration" { - type = map(string) - default = { - "env" = "development" - } -} - -# This is a contrived example, but this pattern works with any object that is a mix of ephemeral and non-ephemeral values. -locals { - configuration_with_token = merge( - var.configuration, - { "session_token" = var.session_token } - ) - ephemeral = true -} - -output "configuration_settings" { -# Using ephemeralasnull enables you to output the non-ephemeral values. - value = ephemeralasnull(local.things_with_token) - description = "Environment setting." -} -``` - -When you apply the above configuration, Terraform returns the `ephemeral` values in `locals.configuration_settings` as `null`. This lets you output the non-ephemeral value `env`. - -```hcl -Outputs: - -configuration_settings = { - "env" = "development" - "session_token" = tostring(null) -} -``` \ No newline at end of file diff --git a/website/docs/language/functions/file.mdx b/website/docs/language/functions/file.mdx deleted file mode 100644 index f3a1b42bd6..0000000000 --- a/website/docs/language/functions/file.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -page_title: file - Functions - Configuration Language -description: |- - The file function reads the contents of the file at the given path and - returns them as a string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `file` Function - -`file` reads the contents of a file at the given path and returns them as -a string. - -```hcl -file(path) -``` - -Strings in the Terraform language are sequences of Unicode characters, so -this function will interpret the file contents as UTF-8 encoded text and -return the resulting Unicode characters. If the file contains invalid UTF-8 -sequences then this function will produce an error. - -This function can be used only with files that already exist on disk -at the beginning of a Terraform run. Functions do not participate in the -dependency graph, so this function cannot be used with files that are generated -dynamically during a Terraform operation. We do not recommend using dynamic -local files in Terraform configurations, but in rare situations where this is -necessary you can use -[the `local_file` data source](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file) -to read files while respecting resource dependencies. - -## Examples - -``` -> file("${path.module}/hello.txt") -Hello World -``` - -## Related Functions - -* [`filebase64`](/terraform/language/functions/filebase64) also reads the contents of a given file, - but returns the raw bytes in that file Base64-encoded, rather than - interpreting the contents as UTF-8 text. -* [`fileexists`](/terraform/language/functions/fileexists) determines whether a file exists - at a given path. -* [`templatefile`](/terraform/language/functions/templatefile) renders using a file from disk as a - template. diff --git a/website/docs/language/functions/filebase64.mdx b/website/docs/language/functions/filebase64.mdx deleted file mode 100644 index c39d9e9334..0000000000 --- a/website/docs/language/functions/filebase64.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -page_title: filebase64 - Functions - Configuration Language -description: |- - The filebase64 function reads the contents of the file at the given path and - returns them as a base64-encoded string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filebase64` Function - -`filebase64` reads the contents of a file at the given path and returns them as -a base64-encoded string. - -```hcl -filebase64(path) -``` - -The result is a Base64 representation of the raw bytes in the given file. -Strings in the Terraform language are sequences of Unicode characters, so -Base64 is the standard way to represent raw binary data that cannot be -interpreted as Unicode characters. Resource types that operate on binary -data will accept this data encoded in Base64, thus avoiding the need to -decode the result of this function. - -Terraform uses the "standard" Base64 alphabet as defined in -[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -This function can be used only with functions that already exist as static -files on disk at the beginning of a Terraform run. Language functions do not -participate in the dependency graph, so this function cannot be used with -files that are generated dynamically during a Terraform operation. - -## Examples - -``` -> filebase64("${path.module}/hello.txt") -SGVsbG8gV29ybGQ= -``` - -## Related Functions - -* [`file`](/terraform/language/functions/file) also reads the contents of a given file, - but interprets the data as UTF-8 text and returns the result directly - as a string, without any further encoding. -* [`base64decode`](/terraform/language/functions/base64decode) can decode a Base64 string representing - bytes in UTF-8, but in practice `base64decode(filebase64(...))` is equivalent - to the shorter expression `file(...)`. diff --git a/website/docs/language/functions/filebase64sha256.mdx b/website/docs/language/functions/filebase64sha256.mdx deleted file mode 100644 index 3664351351..0000000000 --- a/website/docs/language/functions/filebase64sha256.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -page_title: filebase64sha256 - Functions - Configuration Language -description: |- - The filebase64sha256 function computes the SHA256 hash of the contents of - a given file and encodes it with Base64. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filebase64sha256` Function - -`filebase64sha256` is a variant of [`base64sha256`](/terraform/language/functions/base64sha256) -that hashes the contents of a given file rather than a literal string. - -This is similar to `base64sha256(file(filename))`, but -because [`file`](/terraform/language/functions/file) accepts only UTF-8 text it cannot be used to -create hashes for binary files. diff --git a/website/docs/language/functions/filebase64sha512.mdx b/website/docs/language/functions/filebase64sha512.mdx deleted file mode 100644 index 756647b7fd..0000000000 --- a/website/docs/language/functions/filebase64sha512.mdx +++ /dev/null @@ -1,21 +0,0 @@ ---- -page_title: filebase64sha512 - Functions - Configuration Language -description: |- - The filebase64sha512 function computes the SHA512 hash of the contents of - a given file and encodes it with Base64. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filebase64sha512` Function - -`filebase64sha512` is a variant of [`base64sha512`](/terraform/language/functions/base64sha512) -that hashes the contents of a given file rather than a literal string. - -This is similar to `base64sha512(file(filename))`, but -because [`file`](/terraform/language/functions/file) accepts only UTF-8 text it cannot be used to -create hashes for binary files. diff --git a/website/docs/language/functions/fileexists.mdx b/website/docs/language/functions/fileexists.mdx deleted file mode 100644 index 4e9b1494fe..0000000000 --- a/website/docs/language/functions/fileexists.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -page_title: fileexists - Functions - Configuration Language -description: The fileexists function determines whether a file exists at a given path. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `fileexists` Function - -`fileexists` determines whether a file exists at a given path. - -```hcl -fileexists(path) -``` - -Functions are evaluated during configuration parsing rather than at apply time, -so this function can only be used with files that are already present on disk -before Terraform takes any actions. - -This function works only with regular files. If used with a directory, FIFO, -or other special mode, it will return an error. - -## Examples - -``` -> fileexists("${path.module}/hello.txt") -true -``` - -```hcl -fileexists("custom-section.sh") ? file("custom-section.sh") : local.default_content -``` - -## Related Functions - -* [`file`](/terraform/language/functions/file) reads the contents of a file at a given path diff --git a/website/docs/language/functions/filemd5.mdx b/website/docs/language/functions/filemd5.mdx deleted file mode 100644 index 69b476408e..0000000000 --- a/website/docs/language/functions/filemd5.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -page_title: filemd5 - Functions - Configuration Language -description: |- - The filemd5 function computes the MD5 hash of the contents of - a given file and encodes it as hex. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filemd5` Function - -`filemd5` is a variant of [`md5`](/terraform/language/functions/md5) -that hashes the contents of a given file rather than a literal string. - -This is similar to `md5(file(filename))`, but -because [`file`](/terraform/language/functions/file) accepts only UTF-8 text it cannot be used to -create hashes for binary files. - -Collision attacks have been successfully performed against this hashing -function. Before using this function for anything security-sensitive, refer to -[RFC 6151](https://tools.ietf.org/html/rfc6151) for updated security -considerations applying to the MD5 algorithm. diff --git a/website/docs/language/functions/fileset.mdx b/website/docs/language/functions/fileset.mdx deleted file mode 100644 index e01566f02b..0000000000 --- a/website/docs/language/functions/fileset.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -page_title: fileset - Functions - Configuration Language -description: The fileset function enumerates a set of regular file names given a pattern. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `fileset` Function - -`fileset` enumerates a set of regular file names given a path and pattern. -The path is automatically removed from the resulting set of file names and any -result still containing path separators always returns forward slash (`/`) as -the path separator for cross-system compatibility. - -```hcl -fileset(path, pattern) -``` - -Supported pattern matches: - -- `*` - matches any sequence of non-separator characters -- `**` - matches any sequence of characters, including separator characters -- `?` - matches any single non-separator character -- `{alternative1,...}` - matches a sequence of characters if one of the comma-separated alternatives matches -- `[CLASS]` - matches any single non-separator character inside a class of characters (see below) -- `[^CLASS]` - matches any single non-separator character outside a class of characters (see below) - -Note that the doublestar (`**`) must appear as a path component by itself. A -pattern such as /path\*\* is invalid and will be treated the same as /path\*, but -/path\*/\*\* should achieve the desired result. - -Character classes support the following: - -- `[abc]` - matches any single character within the set -- `[a-z]` - matches any single character within the range - -Functions are evaluated during configuration parsing rather than at apply time, -so this function can only be used with files that are already present on disk -before Terraform takes any actions. - -## Examples - -``` -> fileset(path.module, "files/*.txt") -[ - "files/hello.txt", - "files/world.txt", -] - -> fileset(path.module, "files/{hello,world}.txt") -[ - "files/hello.txt", - "files/world.txt", -] - -> fileset("${path.module}/files", "*") -[ - "hello.txt", - "world.txt", -] - -> fileset("${path.module}/files", "**") -[ - "hello.txt", - "world.txt", - "subdirectory/anotherfile.txt", -] -``` - -A common use of `fileset` is to create one resource instance per matched file, using -[the `for_each` meta-argument](/terraform/language/meta-arguments/for_each): - -```hcl -resource "example_thing" "example" { - for_each = fileset(path.module, "files/*") - - # other configuration using each.value -} -``` diff --git a/website/docs/language/functions/filesha1.mdx b/website/docs/language/functions/filesha1.mdx deleted file mode 100644 index 7fadae0711..0000000000 --- a/website/docs/language/functions/filesha1.mdx +++ /dev/null @@ -1,54 +0,0 @@ ---- -page_title: filesha1 - Functions - Configuration Language -description: The filesha1 function computes the SHA1 hash of the contents of a given file and encodes it as hex. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filesha1` function reference -This topic provides reference information about the `filesha1` function, which calculates the SHA-1 hash of a file's contents. - -## Introduction - -The `filesha1` is a variant of [`sha1`](/terraform/language/functions/sha1) that hashes the contents of a given file rather than a literal string. - -Use the `filesha1` function instead of wrapping the `file` function in a `sha1` function, for example `sha1(file(filename))`, because [`file`](/terraform/language/functions/file) accepts only UTF-8 text. As a result, you cannot use `sha1(file(filename))` to create hashes for binary files. - -!> **Security warning**: This hashing function is susceptible to collision attacks. Before using this function for anything security-sensitive, review relevant literature to understand the security implications. - -## Syntax - -Use the filesha1 function with the following syntax: - -```hcl -filesha1(path) -``` - -The `path` is the relative or absolute file path to the file whose SHA-1 hash you want to compute. - -In the following example, the function returns the SHA-1 value. - -```hcl -$ filesha1("example.txt") -d3486ae9136e7856bc42212385ea797094475802 -``` - -## Example use case - -In the following example the `filesha1` function computes the SHA-1 hash of the file `example.txt` located in the current module's directory. The result is a 40-character hexadecimal string representing the SHA-1 hash. - -```hcl -output "file_hash" { - value = filesha1("${path.module}/example.txt") -} -``` - -## Related functions - -- [`sha1`](/terraform/language/functions/sha1) computes the SHA-1 hash of a given string and encodes it with hexadecimal digits. -- [`filesha256`](/terraform/language/functions/filesha256) computes the SHA-256 hash of a given file and encodes it with hexadecimal digits. -- [`filesha512`](/terraform/language/functions/filesha512) computes the SHA-512 hash of a given file and encodes it with hexadecimal digits. diff --git a/website/docs/language/functions/filesha256.mdx b/website/docs/language/functions/filesha256.mdx deleted file mode 100644 index d2a5159071..0000000000 --- a/website/docs/language/functions/filesha256.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -page_title: filesha256 - Functions - Configuration Language -description: |- - The filesha256 function computes the SHA256 hash of the contents of - a given file and encodes it as hex. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filesha256` function reference - -This topic provides reference information about the `filesha256` function, which calculates the SHA-256 hash of a file's contents. - -## Introduction - -The `filesha256` is a variant of [`sha256`](/terraform/language/functions/sha256) -that hashes the contents of a given file rather than a literal string. - -Use the `filesha1` function instead of wrapping the `file` function in a `sha1` function, for example `sha1(file(filename))`, because [`file`](/terraform/language/functions/file) accepts only UTF-8 text. As a result, you cannot use `sha1(file(filename))` to create hashes for binary files. - -## Syntax - -Use the `filesha256` function with the following syntax: - -```hcl -filesha256(path) -``` - -The `path` is the relative or absolute file path to the file whose SHA-256 hash you want to compute. - -In the following example, the function returns the SHA-256 value of `example.txt`. - -```hcl -$ filesha512("example.txt") -a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b0b571d0f6a26f2bb -``` - -## Example use case - -In the following example, the `filesha256` function computes the SHA-256 hash of the file `example.txt` located in the current module's directory. - -```hcl -output "file_hash" { - value = filesha256("example.txt") -} -``` - -## Related functions - -- [`sha256`](/terraform/language/functions/sha256) computes the SHA-1 hash of a given string and encodes it with hexadecimal digits. -- [`filesha512`](/terraform/language/functions/filesha512) computes the SHA-512 hash of a given file and encodes it with hexadecimal digits. -- [`filesha1`](/terraform/language/functions/filesha1)computes the SHA-1 hash of a given file and encodes it with hexadecimal digits. diff --git a/website/docs/language/functions/filesha512.mdx b/website/docs/language/functions/filesha512.mdx deleted file mode 100644 index e41eec2e0b..0000000000 --- a/website/docs/language/functions/filesha512.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -page_title: filesha512 - Functions - Configuration Language -description: |- - The filesha512 function computes the SHA512 hash of the contents of - a given file and encodes it as hex. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `filesha512` function reference - -This topic provides reference information about the `filesha512` function, which calculates the SHA-512 hash of a file's contents. - -## Introduction - -The `filesha512` is a variant of [`sha512`](/terraform/language/functions/sha512) -that hashes the contents of a given file rather than a literal string. - -This is similar to `sha512(file(filename))`, but -because [`file`](/terraform/language/functions/file) accepts only UTF-8 text it cannot be used to -create hashes for binary files. - -## Syntax - -Use the `filesha512` function with the following syntax: - -```hcl -filesha512(path) -``` - -The `path` is the relative or absolute file path to the file whose SHA-512 hash you want to compute. - -In the following example, the function returns the SHA-512 value of `example.txt`. - -```hcl -$ filesha512("example.txt") -861844d6704e8573fec34d967e20bcfe6e061b3348b3b0c7e9b7c6a482f6f15a48bffd0fb928fd8c9f9196f7a8596d5e32b45d5a25488a8499396a67442c1d76 -``` - -## Example use case - -In the following example, the `filesha512` function computes the SHA-512 hash of the file `example.txt` located in the current module's directory. - -```hcl -output "file_hash" { - value = filesha512("example.txt") -} -``` - -## Related functions - -- [`sha512`](/terraform/language/functions/sha512) computes the SHA-512 hash of a given string and encodes it with hexadecimal digits. -- [`filesha256`](/terraform/language/functions/filesha256) computes the SHA-1 hash of a given file and encodes it with hexadecimal digits. -- [`filesha1`](/terraform/language/functions/filesha1)computes the SHA-1 hash of a given file and encodes it with hexadecimal digits. diff --git a/website/docs/language/functions/flatten.mdx b/website/docs/language/functions/flatten.mdx deleted file mode 100644 index 6e84641aca..0000000000 --- a/website/docs/language/functions/flatten.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -page_title: flatten - Functions - Configuration Language -description: The flatten function eliminates nested lists from a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `flatten` Function - -`flatten` takes a list and replaces any elements that are lists with a -flattened sequence of the list contents. - -## Examples - -``` -> flatten([["a", "b"], [], ["c"]]) -["a", "b", "c"] -``` - -If any of the nested lists also contain directly-nested lists, these too are -flattened recursively: - -``` -> flatten([[["a", "b"], []], ["c"]]) -["a", "b", "c"] -``` - -Indirectly-nested lists, such as those in maps, are _not_ flattened. - -## Flattening nested structures for `for_each` - -The -[resource `for_each`](/terraform/language/meta-arguments/for_each) -and -[`dynamic` block](/terraform/language/expressions/dynamic-blocks) -language features both require a collection value that has one element for -each repetition. - -Sometimes your input data structure isn't naturally in a suitable shape for -use in a `for_each` argument, and `flatten` can be a useful helper function -when reducing a nested data structure into a flat one. - -For example, consider a module that declares a variable like the following: - -```hcl -variable "networks" { - type = map(object({ - cidr_block = string - subnets = map(object({ cidr_block = string })) - })) - default = { - "private" = { - cidr_block = "10.1.0.0/16" - subnets = { - "db1" = { - cidr_block = "10.1.0.0/24" - } - "db2" = { - cidr_block = "10.1.1.0/24" - } - } - }, - "public" = { - cidr_block = "10.2.0.0/16" - subnets = { - "webserver" = { - cidr_block = "10.2.1.0/24" - } - "email_server" = { - cidr_block = "10.2.2.0/24" - } - } - } - "dmz" = { - cidr_block = "10.3.0.0/16" - subnets = { - "firewall" = { - cidr_block = "10.3.1.0/24" - } - } - } - } -} - -``` - -The above is a reasonable way to model objects that naturally form a tree, -such as top-level networks and their subnets. The repetition for the top-level -networks can use this variable directly, because it's already in a form -where the resulting instances match one-to-one with map elements: - -```hcl -resource "aws_vpc" "example" { - for_each = var.networks - - cidr_block = each.value.cidr_block -} -``` - -However, in order to declare all of the _subnets_ with a single `resource` -block, we must first flatten the structure to produce a collection where each -top-level element represents a single subnet: - -```hcl -locals { - # flatten ensures that this local value is a flat list of objects, rather - # than a list of lists of objects. - network_subnets = flatten([ - for network_key, network in var.networks : [ - for subnet_key, subnet in network.subnets : { - network_key = network_key - subnet_key = subnet_key - network_id = aws_vpc.example[network_key].id - cidr_block = subnet.cidr_block - } - ] - ]) -} - -resource "aws_subnet" "example" { - # local.network_subnets is a list, so we must now project it into a map - # where each key is unique. We'll combine the network and subnet keys to - # produce a single unique key per instance. - for_each = tomap({ - for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet - }) - - vpc_id = each.value.network_id - availability_zone = each.value.subnet_key - cidr_block = each.value.cidr_block -} -``` - -The above results in one subnet instance per subnet object, while retaining -the associations between the subnets and their containing networks. - -## Related Functions - -* [`setproduct`](/terraform/language/functions/setproduct) finds all of the combinations of multiple - lists or sets of values, which can also be useful when preparing collections - for use with `for_each` constructs. diff --git a/website/docs/language/functions/floor.mdx b/website/docs/language/functions/floor.mdx deleted file mode 100644 index 7abbadb9e5..0000000000 --- a/website/docs/language/functions/floor.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -page_title: floor - Functions - Configuration Language -description: |- - The floor function returns the closest whole number less than or equal to - the given value. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `floor` Function - -`floor` returns the closest whole number that is less than or equal to the -given value, which may be a fraction. - -## Examples - -``` -> floor(5) -5 -> floor(4.9) -4 -``` - -## Related Functions - -* [`ceil`](/terraform/language/functions/ceil), which rounds to the nearest whole number _greater than_ - or equal. diff --git a/website/docs/language/functions/format.mdx b/website/docs/language/functions/format.mdx deleted file mode 100644 index 5a8d8ff2d8..0000000000 --- a/website/docs/language/functions/format.mdx +++ /dev/null @@ -1,158 +0,0 @@ ---- -page_title: format - Functions - Configuration Language -description: |- - The format function produces a string by formatting a number of other values - according to a specification string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `format` Function - -The `format` function produces a string by formatting a number of other values according -to a specification string. It is similar to the `printf` function in C, and -other similar functions in other programming languages. - -```hcl -format(spec, values...) -``` - -## Examples - -``` -> format("Hello, %s!", "Ander") -Hello, Ander! -> format("There are %d lights", 4) -There are 4 lights -``` - -Simple format verbs like `%s` and `%d` behave similarly to template -interpolation syntax, which is often more readable. - -``` -> format("Hello, %s!", var.name) -Hello, Valentina! -> "Hello, ${var.name}!" -Hello, Valentina! -``` - -We can specify an argument position number - -``` -> format("%[1]s%[2]s%[1]s%[3]s", "/", "path", "file.tf") -"/path/file.tf" -``` - -The formatting verb `%#v` accepts a value of any type and presents it using JSON encoding, similar to jsonencode. This can be useful for describing the values given to a module in [custom condition check](/terraform/language/expressions/custom-conditions#error-messages) error messages. - -``` -> format("%#v", "hello") -"\"hello\"" -> format("%#v", true) -"true" -> format("%#v", 1) -"1" -> format("%#v", {a = 1}) -"{\"a\":1}" -> format("%#v", [true]) -"[true]" -> format("%#v", null) -"null" -``` - -The `format` function is most useful when you use more complex format specifications. - -## Specification Syntax - -The specification is a string that includes formatting verbs that are introduced -with the `%` character. The function call must then have one additional argument -for each verb sequence in the specification. The verbs are matched with -consecutive arguments and formatted as directed, as long as each given argument -is convertible to the type required by the format verb. - -By default, `%` sequences consume successive arguments starting with the first. -Introducing a `[n]` sequence immediately before the verb letter, where `n` is a -decimal integer, explicitly chooses a particular value argument by its -one-based index. Subsequent calls without an explicit index will then proceed -with `n`+1, `n`+2, etc. - -The function produces an error if the format string requests an impossible -conversion or access more arguments than are given. An error is produced also -for an unsupported format verb. - -### Verbs - -The specification may contain the following verbs. - -| Verb | Result | -| ----- | ----------------------------------------------------------------------------------------- | -| `%%` | Literal percent sign, consuming no value. | -| `%v` | Default formatting based on the [value type](#default-format-verbs). Accepts all types, including items of `null`, `list`, and `map` types. | -| `%#v` | JSON serialization of the value, as with `jsonencode`. Accepts all types, including items of `null`, `list`, and `map` types. | -| `%t` | Convert to boolean and produce `true` or `false`. | -| `%b` | Convert to integer number and produce binary representation. | -| `%d` | Convert to integer number and produce decimal representation. | -| `%o` | Convert to integer number and produce octal representation. | -| `%x` | Convert to integer number and produce hexadecimal representation with lowercase letters. | -| `%X` | Like `%x`, but use uppercase letters. | -| `%e` | Convert to number and produce scientific notation, like `-1.234456e+78`. | -| `%E` | Like `%e`, but use an uppercase `E` to introduce the exponent. | -| `%f` | Convert to number and produce decimal fraction notation with no exponent, like `123.456`. | -| `%g` | Like `%e` for large exponents or like `%f` otherwise. | -| `%G` | Like `%E` for large exponents or like `%f` otherwise. | -| `%s` | Convert to string and insert the string's characters. | -| `%q` | Convert to string and produce a JSON quoted string representation. | - -### Default Format Verbs - -When `%v` is used, Terraform chooses the appropriate format verb based on the value type. - -| Type | Verb | -| --------- | ----- | -| `string` | `%s` | -| `number` | `%g` | -| `bool` | `%t` | -| any other | `%#v` | - -Null values produce the string `null` if formatted with `%v` or `%#v`, and cause an error for other verbs. - -### Width Modifier - -Use a width modifier with an optional decimal number immediately -preceding the verb letter to specify how many characters will be used to represent the value. You can specify precision after the (optional) width with a period (`.`) followed by a decimal number. If width or precision are omitted, Terraform selects default values based on the given value. - -The following examples demonstrate example use cases for the width modifier. - -| Sequence | Result | -| -------- | ---------------------------- | -| `%f` | Default width and precision. | -| `%9f` | Width 9, default precision. | -| `%.2f` | Default width, precision 2. | -| `%9.2f` | Width 9, precision 2. | - --> **Note:** Width and precision modifiers with non-numeric types such as -strings (`%s`) are interpreted differently. Setting either width or precision to -zero is the same as not including them at all. - -### Additional Format Options - -Use the following symbols immediately after the `%` symbol to set additional formatting requirements. - -| Symbol | Result | -| ------ | -------------------------------------------------------------- | -| space | Leave a space where the sign would be if a number is positive. | -| `+` | Show the sign of a number even if it is positive. | -| `-` | Pad the width with spaces on the right rather than the left. | -| `0` | Pad the width with leading zeros rather than spaces. | - - -## Related Functions - -* [`formatdate`](/terraform/language/functions/formatdate) is a specialized formatting function for - human-readable timestamps. -* [`formatlist`](/terraform/language/functions/formatlist) uses the same specification syntax to - produce a list of strings. diff --git a/website/docs/language/functions/formatdate.mdx b/website/docs/language/functions/formatdate.mdx deleted file mode 100644 index 12405cca23..0000000000 --- a/website/docs/language/functions/formatdate.mdx +++ /dev/null @@ -1,111 +0,0 @@ ---- -page_title: formatdate - Functions - Configuration Language -description: The formatdate function converts a timestamp into a different time format. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `formatdate` Function - -`formatdate` converts a timestamp into a different time format. - -```hcl -formatdate(spec, timestamp) -``` - -In the Terraform language, timestamps are conventionally represented as -strings using [RFC 3339](https://tools.ietf.org/html/rfc3339) -"Date and Time format" syntax. `formatdate` requires the `timestamp` argument -to be a string conforming to this syntax. - -## Examples - -``` -> formatdate("DD MMM YYYY hh:mm ZZZ", "2018-01-02T23:12:01Z") -02 Jan 2018 23:12 UTC -> formatdate("EEEE, DD-MMM-YY hh:mm:ss ZZZ", "2018-01-02T23:12:01Z") -Tuesday, 02-Jan-18 23:12:01 UTC -> formatdate("EEE, DD MMM YYYY hh:mm:ss ZZZ", "2018-01-02T23:12:01-08:00") -Tue, 02 Jan 2018 23:12:01 -0800 -> formatdate("MMM DD, YYYY", "2018-01-02T23:12:01Z") -Jan 02, 2018 -> formatdate("HH:mmaa", "2018-01-02T23:12:01Z") -11:12pm -``` - -## Specification Syntax - -The format specification is a string that includes formatting sequences from -the following table. This function is intended for producing common -_machine-oriented_ timestamp formats such as those defined in RFC822, RFC850, -and RFC1123. It is not suitable for truly human-oriented date formatting -because it is not locale-aware. In particular, it can produce month and day -names only in English. - -The specification may contain the following sequences: - -| Sequence | Result | -| -------- | ----------------------------------------------------------------------- | -| `YYYY` | Four (or more) digit year, like "2006". | -| `YY` | The year modulo 100, zero padded to at least two digits, like "06". | -| `MMMM` | English month name unabbreviated, like "January". | -| `MMM` | English month name abbreviated to three letters, like "Jan". | -| `MM` | Month number zero-padded to two digits, like "01" for January. | -| `M` | Month number with no padding, like "1" for January. | -| `DD` | Day of month number zero-padded to two digits, like "02". | -| `D` | Day of month number with no padding, like "2". | -| `EEEE` | English day of week name unabbreviated, like "Monday". | -| `EEE` | English day of week name abbreviated to three letters, like "Mon". | -| `hh` | 24-hour number zero-padded to two digits, like "02". | -| `h` | 24-hour number unpadded, like "2". | -| `HH` | 12-hour number zero-padded to two digits, like "02". | -| `H` | 12-hour number unpadded, like "2". | -| `AA` | Hour AM/PM marker in uppercase, like "AM". | -| `aa` | Hour AM/PM marker in lowercase, like "am". | -| `mm` | Minute within hour zero-padded to two digits, like "05". | -| `m` | Minute within hour unpadded, like "5". | -| `ss` | Second within minute zero-padded to two digits, like "09". | -| `s` | Second within minute, like "9". | -| `ZZZZZ` | Timezone offset with colon separating hours and minutes, like "-08:00". | -| `ZZZZ` | Timezone offset with just sign and digit, like "-0800". | -| `ZZZ` | Like `ZZZZ` but with a special case "UTC" for UTC. | -| `Z` | Like `ZZZZZ` but with a special case "Z" for UTC. | - -Any non-letter characters, such as punctuation, are reproduced verbatim in the -output. To include literal letters in the format string, enclose them in single -quotes `'`. To include a literal quote, escape it by doubling the quotes. - -``` -> formatdate("h'h'mm", "2018-01-02T23:12:01-08:00") -23h12 -> formatdate("H 'o''clock'", "2018-01-02T23:12:01-08:00") -11 o'clock -``` - -This format specification syntax is intended to make it easy for a reader -to guess which format will result even if they are not experts on the syntax. -Therefore there are no predefined shorthands for common formats, but format -strings for various RFC-specified formats are given below to be copied into your -configuration as needed: - -- [RFC 822](https://tools.ietf.org/html/rfc822#section-5) and - [RFC RFC 2822](https://tools.ietf.org/html/rfc2822#section-3.3): - `"DD MMM YYYY hh:mm ZZZ"` -- [RFC 850](https://tools.ietf.org/html/rfc850#section-2.1.4): - `"EEEE, DD-MMM-YY hh:mm:ss ZZZ"` -- [RFC 1123](https://tools.ietf.org/html/rfc1123#section-5.2.14): - `"EEE, DD MMM YYYY hh:mm:ss ZZZ"` -- [RFC 3339](https://tools.ietf.org/html/rfc3339): - `"YYYY-MM-DD'T'hh:mm:ssZ"` (but this is also the input format, so such a - conversion is redundant.) - -## Related Functions - -- [`format`](/terraform/language/functions/format) is a more general formatting function for arbitrary - data. -- [`timestamp`](/terraform/language/functions/timestamp) returns the current date and time in a format - suitable for input to `formatdate`. diff --git a/website/docs/language/functions/formatlist.mdx b/website/docs/language/functions/formatlist.mdx deleted file mode 100644 index 515bbcd458..0000000000 --- a/website/docs/language/functions/formatlist.mdx +++ /dev/null @@ -1,55 +0,0 @@ ---- -page_title: formatlist - Functions - Configuration Language -description: |- - The formatlist function produces a list of strings by formatting a number of - other values according to a specification string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `formatlist` Function - -`formatlist` produces a list of strings by formatting a number of other -values according to a specification string. - -```hcl -formatlist(spec, values...) -``` - -The specification string uses -[the same syntax as `format`](/terraform/language/functions/format#specification-syntax). - -The given values can be a mixture of list and non-list arguments. Any given -lists must be the same length, which decides the length of the resulting list. - -The list arguments are iterated together in order by index, while the non-list -arguments are used repeatedly for each iteration. The format string is evaluated -once per element of the list arguments. - -## Examples - -``` -> formatlist("Hello, %s!", ["Valentina", "Ander", "Olivia", "Sam"]) -[ - "Hello, Valentina!", - "Hello, Ander!", - "Hello, Olivia!", - "Hello, Sam!", -] -> formatlist("%s, %s!", "Salutations", ["Valentina", "Ander", "Olivia", "Sam"]) -[ - "Salutations, Valentina!", - "Salutations, Ander!", - "Salutations, Olivia!", - "Salutations, Sam!", -] -``` - -## Related Functions - -* [`format`](/terraform/language/functions/format) defines the specification syntax used by this - function and produces a single string as its result. diff --git a/website/docs/language/functions/indent.mdx b/website/docs/language/functions/indent.mdx deleted file mode 100644 index f762a3503b..0000000000 --- a/website/docs/language/functions/indent.mdx +++ /dev/null @@ -1,41 +0,0 @@ ---- -page_title: indent - Functions - Configuration Language -description: |- - The indent function adds spaces to the beginning of each line but the first in a multi-line string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `indent` function reference - -This topic provides reference information about the `indent` function. -You can use the `indent` function to add indentation to the beginning of each line, except the first, in a multi-line string. - -## Introduction - -The `indent` function adds a specified number of spaces to the beginning of each line in a multi-line string, except for the first line. -You can use the `indent` function to help ensure that complex strings are properly formatted, consistent, and readable. -The function can be especially useful when you work with YAML, JSON, Kubernetes, or other formats that require complex, structured text. - -## Syntax - -Use the `indent` function with the following syntax: - -```hcl -indent(num_spaces, string) -``` - -- The first argument is numeric. It specifies the number of spaces you want to add to each line except the first. -- The second argument is a string. It specifies the multi-line string to which you want to add spaces. - -In the following example, the `indent` function adds two spaces to the beginning of each line of the `description` variable to make it easier to read: - -```hcl -output "formatted_description" { - value = indent(2, var.description) -} -``` diff --git a/website/docs/language/functions/index.mdx b/website/docs/language/functions/index.mdx deleted file mode 100644 index f71ce0f99f..0000000000 --- a/website/docs/language/functions/index.mdx +++ /dev/null @@ -1,44 +0,0 @@ ---- -page_title: Functions - Configuration Language -description: >- - An introduction to the built-in functions that you can use to transform and - combine values in 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Built-in Functions - -> **Hands-on:** Try the [Perform Dynamic Operations with Functions](/terraform/tutorials/configuration-language/functions?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -The Terraform language includes a number of built-in functions that you can -call from within expressions to transform and combine values. The general -syntax for function calls is a function name followed by comma-separated -arguments in parentheses: - -```hcl -max(5, 12, 9) -``` - -For more details on syntax, see -[_Function Calls_](/terraform/language/expressions/function-calls) -in the Expressions section. - -The Terraform language does not support user-defined functions, and so only -the functions built in to the language are available for use. The documentation includes a page for all of the available built-in functions. - -You can experiment with the behavior of Terraform's built-in functions from -the Terraform expression console, by running -[the `terraform console` command](/terraform/cli/commands/console): - -``` -> max(5, 12, 9) -12 -``` - -The examples in the documentation for each function use console output to -illustrate the result of calling the function with different parameters. diff --git a/website/docs/language/functions/index_function.mdx b/website/docs/language/functions/index_function.mdx deleted file mode 100644 index 62ba1209b1..0000000000 --- a/website/docs/language/functions/index_function.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -page_title: index - Functions - Configuration Language -description: The index function finds the element index for a given value in a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `index` Function - -`index` finds the first element index for a given value in a list. - -```hcl -index(list, value) -``` - -The returned index is zero-based. This function produces an error if the given -value is not present in the list. - -## Examples - -``` -> index(["a", "b", "c"], "b") -1 -``` - -In this example, the index of the first occurence of `"two"` is returned. - -``` -> index(["one", "two", "two"], "two") -1 -``` - -## Related Functions - -* [`element`](/terraform/language/functions/element) retrieves a particular element from a list given - its index. diff --git a/website/docs/language/functions/issensitive.mdx b/website/docs/language/functions/issensitive.mdx deleted file mode 100644 index 30f5c57e2b..0000000000 --- a/website/docs/language/functions/issensitive.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: issensitive - Functions - Configuration Language -description: The issensitive function true if the value passed is marked as sensitive ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `issensitive` Function - --> **Note:** This function is only available in Terraform v1.8 and later. - -`issensitive` takes any value and returns true if Terraform -treats it as sensitive, with the same meaning and behavior as for -[sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output). - -If a value not marked as sensitive is passed the function returns false. - -See [`sensitive`](/terraform/language/functions/sensitive), [`nonsensitive`](/terraform/language/functions/nonsensitive), and [sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output) for more information on sensitive values. - -## Examples - -``` -> issensitive(sensitive("secret")) -true -> issensitive("hello") -false -> issensitive(var.my-var-with-sensitive-set-to-true) -true -``` diff --git a/website/docs/language/functions/join.mdx b/website/docs/language/functions/join.mdx deleted file mode 100644 index 676eb13003..0000000000 --- a/website/docs/language/functions/join.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: join - Functions - Configuration Language -description: |- - The join function produces a string by concatenating the elements of a list - with a given delimiter. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `join` Function - -`join` produces a string by concatenating all of the elements of the specified -list of strings with the specified separator. - -```hcl -join(separator, list) -``` - -## Examples - -``` -> join("-", ["foo", "bar", "baz"]) -"foo-bar-baz" -> join(", ", ["foo", "bar", "baz"]) -foo, bar, baz -> join(", ", ["foo"]) -foo -``` - -## Related Functions - -* [`split`](/terraform/language/functions/split) performs the opposite operation: producing a list - by separating a single string using a given delimiter. diff --git a/website/docs/language/functions/jsondecode.mdx b/website/docs/language/functions/jsondecode.mdx deleted file mode 100644 index 4db3702d4b..0000000000 --- a/website/docs/language/functions/jsondecode.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -page_title: jsondecode - Functions - Configuration Language -description: |- - The jsondecode function decodes a JSON string into a representation of its - value. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `jsondecode` Function - -`jsondecode` interprets a given string as JSON, returning a representation -of the result of decoding that string. - -The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159). - -This function maps JSON values to -[Terraform language values](/terraform/language/expressions/types) -in the following way: - -| JSON type | Terraform type | -| --------- | ------------------------------------------------------------ | -| String | `string` | -| Number | `number` | -| Boolean | `bool` | -| Object | `object(...)` with attribute types determined per this table | -| Array | `tuple(...)` with element types determined per this table | -| Null | The Terraform language `null` value | - -The Terraform language automatic type conversion rules mean that you don't -usually need to worry about exactly what type is produced for a given value, -and can just use the result in an intuitive way. - -## Examples - -``` -> jsondecode("{\"hello\": \"world\"}") -{ - "hello" = "world" -} -> jsondecode("true") -true -``` - -## Related Functions - -* [`jsonencode`](/terraform/language/functions/jsonencode) performs the opposite operation, _encoding_ - a value as JSON. diff --git a/website/docs/language/functions/jsonencode.mdx b/website/docs/language/functions/jsonencode.mdx deleted file mode 100644 index 2aff4674aa..0000000000 --- a/website/docs/language/functions/jsonencode.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -page_title: jsonencode - Functions - Configuration Language -description: The jsonencode function encodes a given value as a JSON string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `jsonencode` Function - -`jsonencode` encodes a given value to a string using JSON syntax. - -The JSON encoding is defined in [RFC 7159](https://tools.ietf.org/html/rfc7159). - -This function maps -[Terraform language values](/terraform/language/expressions/types) -to JSON values in the following way: - -| Terraform type | JSON type | -| -------------- | --------- | -| `string` | String | -| `number` | Number | -| `bool` | Bool | -| `list(...)` | Array | -| `set(...)` | Array | -| `tuple(...)` | Array | -| `map(...)` | Object | -| `object(...)` | Object | -| Null value | `null` | - -Since the JSON format cannot fully represent all of the Terraform language -types, passing the `jsonencode` result to `jsondecode` will not produce an -identical value, but the automatic type conversion rules mean that this is -rarely a problem in practice. - -When encoding strings, this function escapes some characters using -Unicode escape sequences: replacing `<`, `>`, `&`, `U+2028`, and `U+2029` with -`\u003c`, `\u003e`, `\u0026`, `\u2028`, and `\u2029`. This is to preserve -compatibility with Terraform 0.11 behavior. - -The `jsonencode` command outputs a minified representation of the input. - -## Examples - -``` -> jsonencode({"hello"="world"}) -{"hello":"world"} -``` - -## Related Functions - -* [`jsondecode`](/terraform/language/functions/jsondecode) performs the opposite operation, _decoding_ - a JSON string to obtain its represented value. diff --git a/website/docs/language/functions/keys.mdx b/website/docs/language/functions/keys.mdx deleted file mode 100644 index 32e09cc9c8..0000000000 --- a/website/docs/language/functions/keys.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: keys - Functions - Configuration Language -description: The keys function returns a list of the keys in a given map. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `keys` Function - -`keys` takes a map and returns a list containing the keys from that map. - -The keys are returned in lexicographical order, ensuring that the result will -be identical as long as the keys in the map don't change. - -## Examples - -``` -> keys({a=1, c=2, d=3}) -[ - "a", - "c", - "d", -] -``` - -## Related Functions - -* [`values`](/terraform/language/functions/values) returns a list of the _values_ from a map. diff --git a/website/docs/language/functions/length.mdx b/website/docs/language/functions/length.mdx deleted file mode 100644 index 31114a7ee3..0000000000 --- a/website/docs/language/functions/length.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -page_title: length - Functions - Configuration Language -description: The length function determines the length of a collection or string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `length` Function - -`length` determines the length of a given list, map, or string. - -If given a list or map, the result is the number of elements in that collection. -If given a string, the result is the number of characters in the string. - -## Examples - -``` -> length([]) -0 -> length(["a", "b"]) -2 -> length({"a" = "b"}) -1 -> length("hello") -5 -``` - -When given a string, the result is the number of characters, rather than the -number of bytes or Unicode sequences that form them: - -``` -> length("👾🕹️") -2 -``` - -A "character" is a _grapheme cluster_, as defined by -[Unicode Standard Annex #29](http://unicode.org/reports/tr29/). Note that -remote APIs may have a different definition of "character" for the purpose of -length limits on string arguments; a Terraform provider is responsible for -translating Terraform's string representation into that used by its respective -remote system and applying any additional validation rules to it. diff --git a/website/docs/language/functions/list.mdx b/website/docs/language/functions/list.mdx deleted file mode 100644 index d8da75989e..0000000000 --- a/website/docs/language/functions/list.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: list - Functions - Configuration Language -description: The list function constructs a list from some given elements. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `list` Function - -The `list` function is no longer available. Prior to Terraform v0.12 it was -the only available syntax for writing a literal list inside an expression, -but Terraform v0.12 introduced a new first-class syntax. - -To update an expression like `list(a, b, c)`, write the following instead: - -```hcl -tolist([a, b, c]) -``` - -The `[ ... ]` brackets construct a tuple value, and then the `tolist` function -then converts it to a list. For more information on the value types in the -Terraform language, see [Type Constraints](/terraform/language/expressions/types). - -## Related Functions - -* [`concat`](/terraform/language/functions/concat) produces a new list by concatenating together the - elements from other lists. -* [`tolist`](/terraform/language/functions/tolist) converts a set or tuple value to a list. diff --git a/website/docs/language/functions/log.mdx b/website/docs/language/functions/log.mdx deleted file mode 100644 index 07807188f4..0000000000 --- a/website/docs/language/functions/log.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -page_title: log - Functions - Configuration Language -description: The log function returns the logarithm of a given number in a given base. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `log` Function - -`log` returns the logarithm of a given number in a given base. - -```hcl -log(number, base) -``` - -## Examples - -``` -> log(50, 10) -1.6989700043360185 -> log(16, 2) -4 -``` - -`log` and `ceil` can be used together to find the minimum number of binary -digits required to represent a given number of distinct values: - -``` -> ceil(log(15, 2)) -4 -> ceil(log(16, 2)) -4 -> ceil(log(17, 2)) -5 -``` diff --git a/website/docs/language/functions/lookup.mdx b/website/docs/language/functions/lookup.mdx deleted file mode 100644 index 705ca41b5d..0000000000 --- a/website/docs/language/functions/lookup.mdx +++ /dev/null @@ -1,36 +0,0 @@ ---- -page_title: lookup - Functions - Configuration Language -description: The lookup function retrieves an element value from a map given its key. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `lookup` Function - -`lookup` retrieves the value of a single element from a map, given its key. -If the given key does not exist, the given default value is returned instead. - -```hcl -lookup(map, key, default) -``` - --> For historical reasons, the `default` parameter is actually optional. However, -omitting `default` is deprecated since v0.7 because that would then be -equivalent to the native index syntax, `map[key]`. - -## Examples - -``` -> lookup({a="ay", b="bee"}, "a", "what?") -ay -> lookup({a="ay", b="bee"}, "c", "what?") -what? -``` - -## Related Functions - -* [`element`](/terraform/language/functions/element) retrieves a value from a _list_ given its _index_. diff --git a/website/docs/language/functions/lower.mdx b/website/docs/language/functions/lower.mdx deleted file mode 100644 index 68788592c7..0000000000 --- a/website/docs/language/functions/lower.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: lower - Functions - Configuration Language -description: >- - The lower function converts all cased letters in the given string to - lowercase. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `lower` Function - -`lower` converts all cased letters in the given string to lowercase. - -## Examples - -``` -> lower("HELLO") -hello -> lower("ΓΕΙΑ ΣΟΥ") -"γεια σου" -``` - -This function uses Unicode's definition of letters and of upper- and lowercase. - -## Related Functions - -* [`upper`](/terraform/language/functions/upper) converts letters in a string to _uppercase_. -* [`title`](/terraform/language/functions/title) converts the first letter of each word in a string to uppercase. diff --git a/website/docs/language/functions/map.mdx b/website/docs/language/functions/map.mdx deleted file mode 100644 index f069265ce9..0000000000 --- a/website/docs/language/functions/map.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -page_title: map - Functions - Configuration Language -description: The map function constructs a map from some given elements. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `map` Function - -The `map` function is no longer available. Prior to Terraform v0.12 it was -the only available syntax for writing a literal map inside an expression, -but Terraform v0.12 introduced a new first-class syntax. - -To update an expression like `map("a", "b", "c", "d")`, write the following instead: - -```hcl -tomap({ - a = "b" - c = "d" -}) -``` - -The `{ ... }` braces construct an object value, and then the `tomap` function -then converts it to a map. For more information on the value types in the -Terraform language, see [Type Constraints](/terraform/language/expressions/types). - -## Related Functions - -* [`tomap`](/terraform/language/functions/tomap) converts an object value to a map. -* [`zipmap`](/terraform/language/functions/zipmap) constructs a map dynamically, by taking keys from - one list and values from another list. diff --git a/website/docs/language/functions/matchkeys.mdx b/website/docs/language/functions/matchkeys.mdx deleted file mode 100644 index 0badb2b403..0000000000 --- a/website/docs/language/functions/matchkeys.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -page_title: matchkeys - Functions - Configuration Language -description: |- - The matchkeys function takes a subset of elements from one list by matching - corresponding indexes in another list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `matchkeys` Function - -`matchkeys` constructs a new list by taking a subset of elements from one -list whose indexes match the corresponding indexes of values in another -list. - -```hcl -matchkeys(valueslist, keyslist, searchset) -``` - -`matchkeys` identifies the indexes in `keyslist` that are equal to elements of -`searchset`, and then constructs a new list by taking those same indexes from -`valueslist`. Both `valueslist` and `keyslist` must be the same length. - -The ordering of the values in `valueslist` is preserved in the result. - -## Examples - -``` -> matchkeys(["i-123", "i-abc", "i-def"], ["us-west", "us-east", "us-east"], ["us-east"]) -[ - "i-abc", - "i-def", -] -``` - -If the result ordering is not significant, you can achieve a similar result -using a `for` expression with a map: - -``` -> [for i, z in {"i-123"="us-west","i-abc"="us-east","i-def"="us-east"}: i if z == "us-east"] -[ - "i-def", - "i-abc", -] -``` - -If the keys and values of interest are attributes of objects in a list of -objects then you can also achieve a similar result using a `for` expression -with that list: - -``` -> [for x in [{id="i-123",zone="us-west"},{id="i-abc",zone="us-east"}]: x.id if x.zone == "us-east"] -[ - "i-abc", -] -``` - -For example, the previous form can be used with the list of resource instances -produced by a `resource` block with the `count` meta-attribute set, to filter -the instances by matching one of the resource attributes: - -``` -> [for x in aws_instance.example: x.id if x.availability_zone == "us-east-1a"] -[ - "i-abc123", - "i-def456", -] -``` - -Since the signature of `matchkeys` is complicated and not immediately clear to -the reader when used in configuration, prefer to use `for` expressions where -possible to maximize readability. diff --git a/website/docs/language/functions/max.mdx b/website/docs/language/functions/max.mdx deleted file mode 100644 index db57b12dc9..0000000000 --- a/website/docs/language/functions/max.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: max - Functions - Configuration Language -description: The max function takes one or more numbers and returns the greatest number. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `max` Function - -`max` takes one or more numbers and returns the greatest number from the set. - -## Examples - -``` -> max(12, 54, 3) -54 -``` - -If the numbers are in a list or set value, use `...` to expand the collection -to individual arguments: - -``` -> max([12, 54, 3]...) -54 -``` - -## Related Functions - -* [`min`](/terraform/language/functions/min), which returns the _smallest_ number from a set. diff --git a/website/docs/language/functions/md5.mdx b/website/docs/language/functions/md5.mdx deleted file mode 100644 index 5c2d089049..0000000000 --- a/website/docs/language/functions/md5.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -page_title: md5 - Functions - Configuration Language -description: |- - The md5 function computes the MD5 hash of a given string and encodes it - with hexadecimal digits. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `md5` Function - -`md5` computes the MD5 hash of a given string and encodes it with -hexadecimal digits. - -The given string is first encoded as UTF-8 and then the MD5 algorithm is applied -as defined in [RFC 1321](https://tools.ietf.org/html/rfc1321). The raw hash is -then encoded to lowercase hexadecimal digits before returning. - -Collision attacks have been successfully performed against this hashing -function. Before using this function for anything security-sensitive, refer to -[RFC 6151](https://tools.ietf.org/html/rfc6151) for updated security -considerations applying to the MD5 algorithm. - -## Examples - -``` -> md5("hello world") -5eb63bbbe01eeed093cb22bb8f5acdc3 -``` - -## Related Functions - -* [`filemd5`](/terraform/language/functions/filemd5) calculates the same hash from - the contents of a file rather than from a string value. diff --git a/website/docs/language/functions/merge.mdx b/website/docs/language/functions/merge.mdx deleted file mode 100644 index af89fb1e97..0000000000 --- a/website/docs/language/functions/merge.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -page_title: merge - Functions - Configuration Language -description: |- - The merge function takes an arbitrary number maps or objects, and returns a - single map or object that contains a merged set of elements from all - arguments. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `merge` Function - -`merge` takes an arbitrary number of maps or objects, and returns a single map -or object that contains a merged set of elements from all arguments. - -If more than one given map or object defines the same key or attribute, then -the one that is later in the argument sequence takes precedence. If the -argument types do not match, the resulting type will be an object matching the -type structure of the attributes after the merging rules have been applied. - -## Examples - -``` -> merge({a="b", c="d"}, {e="f", c="z"}) -{ - "a" = "b" - "c" = "z" - "e" = "f" -} -``` - -``` -> merge({a="b"}, {a=[1,2], c="z"}, {d=3}) -{ - "a" = [ - 1, - 2, - ] - "c" = "z" - "d" = 3 -} -``` - -The following example uses the expansion symbol (...) to transform the value into separate arguments. Refer to [Expanding Function Argument](/terraform/language/expressions/function-calls#expanding-function-arguments) for details. - -``` -> merge([{a="b", c="d"}, {}, {e="f", c="z"}]...) -{ - "a" = "b" - "c" = "z" - "e" = "f" -} -``` diff --git a/website/docs/language/functions/min.mdx b/website/docs/language/functions/min.mdx deleted file mode 100644 index bc4fd6981f..0000000000 --- a/website/docs/language/functions/min.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: min - Functions - Configuration Language -description: The min function takes one or more numbers and returns the smallest number. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `min` Function - -`min` takes one or more numbers and returns the smallest number from the set. - -## Examples - -``` -> min(12, 54, 3) -3 -``` - -If the numbers are in a list or set value, use `...` to expand the collection -to individual arguments: - -``` -> min([12, 54, 3]...) -3 -``` - -## Related Functions - -* [`max`](/terraform/language/functions/max), which returns the _greatest_ number from a set. diff --git a/website/docs/language/functions/nonsensitive.mdx b/website/docs/language/functions/nonsensitive.mdx deleted file mode 100644 index 1249d0944f..0000000000 --- a/website/docs/language/functions/nonsensitive.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -page_title: nonsensitive - Functions - Configuration Language -description: >- - The nonsensitive function removes the sensitive marking from a value that - Terraform considers to be sensitive. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `nonsensitive` Function - --> **Note:** This function is only available in Terraform v0.15 and later. - -`nonsensitive` takes a sensitive value and returns a copy of that value with -the sensitive marking removed, thereby exposing the sensitive value. - -~> **Warning:** Using this function indiscriminately will cause values that -Terraform would normally have considered as sensitive to be treated as normal -values and shown clearly in Terraform's output. Use this function only when -you've derived a new value from a sensitive value in a way that eliminates the -sensitive portions of the value. - -Normally Terraform tracks when you use expressions to derive a new value from -a value that is marked as sensitive, so that the result can also be marked -as sensitive. - -However, you may wish to write expressions that derive non-sensitive results -from sensitive values. For example, if you know based on details of your -particular system and its threat model that a SHA256 hash of a particular -sensitive value is safe to include clearly in Terraform output, you could use -the `nonsensitive` function to indicate that, overriding Terraform's normal -conservative behavior: - -```hcl -output "sensitive_example_hash" { - value = nonsensitive(sha256(var.sensitive_example)) -} -``` - -Another example might be if the original value is only partially sensitive and -you've written expressions to separate the sensitive and non-sensitive parts: - -```hcl -variable "mixed_content_json" { - description = "A JSON string containing a mixture of sensitive and non-sensitive values." - type = string - sensitive = true -} - -locals { - # mixed_content is derived from var.mixed_content_json, so it - # is also considered to be sensitive. - mixed_content = jsondecode(var.mixed_content_json) - - # password_from_json is derived from mixed_content, so it's - # also considered to be sensitive. - password_from_json = local.mixed_content["password"] - - # username_from_json would normally be considered to be - # sensitive too, but system-specific knowledge tells us - # that the username is a non-sensitive fragment of the - # original document, and so we can override Terraform's - # determination. - username_from_json = nonsensitive(local.mixed_content["username"]) -} -``` - -When you use this function, it's your responsibility to ensure that the -expression passed as its argument will remove all sensitive content from -the sensitive value it depends on. By passing a value to `nonsensitive` you are -declaring to Terraform that you have done all that is necessary to ensure that -the resulting value has no sensitive content, even though it was derived -from sensitive content. If a sensitive value appears in Terraform's output -due to an inappropriate call to `nonsensitive` in your module, that's a bug in -your module and not a bug in Terraform itself. -**Use this function sparingly and only with due care.** - -`nonsensitive` will make no changes to values that aren't marked as sensitive, even though such a call may be redundant and potentially confusing. -Use `nonsensitive` only after careful consideration and with definite intent. - -Consider including a comment adjacent to your call to explain to future -maintainers what makes the usage safe and thus what invariants they must take -care to preserve under future modifications. - -## Examples - -The following examples are from `terraform console` when running in the -context of the example above with `variable "mixed_content_json"` and -the local value `mixed_content`, with a valid JSON string assigned to -`var.mixed_content_json`. - -``` -> var.mixed_content_json -(sensitive value) -> local.mixed_content -(sensitive value) -> local.mixed_content["password"] -(sensitive value) -> nonsensitive(local.mixed_content["username"]) -"zqb" -> nonsensitive("clear") - -Error: Invalid function argument - -Invalid value for "value" parameter: the given value is not sensitive, so this -call is redundant. -``` - -Note though that it's always your responsibility to use `nonsensitive` only -when it's safe to do so. If you use `nonsensitive` with content that -_ought to be_ considered sensitive then that content will be disclosed: - -``` -> nonsensitive(var.mixed_content_json) -< nonsensitive(local.mixed_content) -{ - "password" = "p4ssw0rd" - "username" = "zqb" -} -> nonsensitive(local.mixed_content["password"]) -"p4ssw0rd" -``` diff --git a/website/docs/language/functions/one.mdx b/website/docs/language/functions/one.mdx deleted file mode 100644 index 57428afa76..0000000000 --- a/website/docs/language/functions/one.mdx +++ /dev/null @@ -1,125 +0,0 @@ ---- -page_title: one - Functions - Configuration Language -description: |- - The 'one' function transforms a list with either zero or one elements into - either a null value or the value of the first element. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `one` Function - --> **Note:** This function is available only in Terraform v0.15 and later. - -`one` takes a list, set, or tuple value with either zero or one elements. -If the collection is empty, `one` returns `null`. Otherwise, `one` returns -the first element. If there are two or more elements then `one` will return -an error. - -This is a specialized function intended for the common situation where a -conditional item is represented as either a zero- or one-element list, where -a module author wishes to return a single value that might be null instead. - -For example: - -```hcl -variable "include_ec2_instance" { - type = bool - default = true -} - -resource "aws_instance" "example" { - count = var.include_ec2_instance ? 1 : 0 - - # (other resource arguments...) -} - -output "instance_ip_address" { - value = one(aws_instance.example[*].private_ip) -} -``` - -Because the `aws_instance` resource above has the `count` argument set to a -conditional that returns either zero or one, the value of -`aws_instance.example` is a list of either zero or one elements. The -`instance_ip_address` output value uses the `one` function as a concise way -to return either the private IP address of a single instance, or `null` if -no instances were created. - -## Relationship to the "Splat" Operator - -The Terraform language has a built-in operator `[*]`, known as -[the _splat_ operator](/terraform/language/expressions/splat), and one of its functions -is to translate a primitive value that might be null into a list of either -zero or one elements: - -```hcl -variable "ec2_instance_type" { - description = "The type of instance to create. If set to null, no instance will be created." - - type = string - default = null -} - -resource "aws_instance" "example" { - count = length(var.ec2_instance_type[*]) - - instance_type = var.ec2_instance_type - # (other resource arguments...) -} - -output "instance_ip_address" { - value = one(aws_instance.example[*].private_ip) -} -``` - -In this case we can see that the `one` function is, in a sense, the opposite -of applying `[*]` to a primitive-typed value. Splat can convert a possibly-null -value into a zero-or-one list, and `one` can reverse that to return to a -primitive value that might be null. - -## Examples - -``` -> one([]) -null -> one(["hello"]) -"hello" -> one(["hello", "goodbye"]) - -Error: Invalid function argument - -Invalid value for "list" parameter: must be a list, set, or tuple value with -either zero or one elements. -``` - -### Using `one` with sets - -The `one` function can be particularly helpful in situations where you have a -set that you know has only zero or one elements. Set values don't support -indexing, so it's not valid to write `var.set[0]` to extract the "first" -element of a set, but if you know that there's only one item then `one` can -isolate and return that single item: - -``` -> one(toset([])) -null -> one(toset(["hello"])) -"hello" -``` - -Don't use `one` with sets that might have more than one element. This function -will fail in that case: - -``` -> one(toset(["hello","goodbye"])) - -Error: Invalid function argument - -Invalid value for "list" parameter: must be a list, set, or tuple value with -either zero or one elements. -``` diff --git a/website/docs/language/functions/parseint.mdx b/website/docs/language/functions/parseint.mdx deleted file mode 100644 index 773077deee..0000000000 --- a/website/docs/language/functions/parseint.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -page_title: parseint - Functions - Configuration Language -description: >- - The parseint function parses the given string as a representation of an - integer. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `parseint` Function - -`parseint` parses the given string as a representation of an integer in -the specified base and returns the resulting number. The base must be between 2 -and 62 inclusive. - -All bases use the arabic numerals 0 through 9 first. Bases between 11 and 36 -inclusive use case-insensitive latin letters to represent higher unit values. -Bases 37 and higher use lowercase latin letters and then uppercase latin -letters. - -If the given string contains any non-digit characters or digit characters that -are too large for the given base then `parseint` will produce an error. - -## Examples - -``` -> parseint("100", 10) -100 - -> parseint("FF", 16) -255 - -> parseint("-10", 16) --16 - -> parseint("1011111011101111", 2) -48879 - -> parseint("aA", 62) -656 - -> parseint("12", 2) - -Error: Invalid function argument - -Invalid value for "number" parameter: cannot parse "12" as a base 2 integer. -``` - -## Related Functions - -* [`format`](/terraform/language/functions/format) can format numbers and other values into strings, - with optional zero padding, alignment, etc. diff --git a/website/docs/language/functions/pathexpand.mdx b/website/docs/language/functions/pathexpand.mdx deleted file mode 100644 index d9e13986f8..0000000000 --- a/website/docs/language/functions/pathexpand.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -page_title: pathexpand - Functions - Configuration Language -description: |- - The pathexpand function expands a leading ~ character to the current user's - home 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `pathexpand` Function - -`pathexpand` takes a filesystem path that might begin with a `~` segment, -and if so it replaces that segment with the current user's home directory -path. - -This function works only with the path string and does not access the -filesystem itself. It is therefore unable to take into account filesystem -features such as symlinks. - -If the leading segment in the path is not `~` then the given path is returned -unmodified. - -Using this function in resource arguments will cause spurious diffs if the -same configuration is run by multiple users with different home directory -paths, or used on different host operating systems. We recommend using this -function only for transient values, such as in `connection` and `provisioner` -blocks to locate SSH keys, etc. - -The rules for determining the "home directory" for the current user vary -depending on host operating system. - -**For Unix systems**, the following sources are consulted, in order of preference: - -* The `HOME` environment variable. -* The result of running `getent passwd` followed by the Terraform process uid. -* The result of running `cd && pwd` in `sh`. - -**For Windows systems**, there is not really the concept of a home directory -in the same sense as on Unix, but the following sources are consulted in -order of preference: - -* The `HOME` environment variable. -* The `HOMEDRIVE` and `HOMEPATH` environment variables, if both are set. -* The `USERPROFILE` environment variable. - -The exact rules employed for each operating system may change in future -releases of Terraform. - -## Examples - -``` -> pathexpand("~/.ssh/id_rsa") -/home/steve/.ssh/id_rsa -> pathexpand("/etc/resolv.conf") -/etc/resolv.conf -``` diff --git a/website/docs/language/functions/plantimestamp.mdx b/website/docs/language/functions/plantimestamp.mdx deleted file mode 100644 index ced42802f0..0000000000 --- a/website/docs/language/functions/plantimestamp.mdx +++ /dev/null @@ -1,60 +0,0 @@ ---- -page_title: plantimestamp - Functions - Configuration Language -description: |- - The plantimestamp functions a string representation of the date and time - during the plan. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `plantimestamp` Function - --> **Note:** This function is only available in Terraform v1.5 and later. - -`plantimestamp` returns a UTC timestamp string in [RFC 3339](https://tools.ietf.org/html/rfc3339) format. - -In the Terraform language, timestamps are conventionally represented as -strings using [RFC 3339](https://tools.ietf.org/html/rfc3339) -"Date and Time format" syntax, and so `plantimestamp` returns a string -in this format. - -The result of this function will change for every plan operation. It is intended -for use within [Custom Conditions](/terraform/language/expressions/custom-conditions) -as a way to validate time sensitive resources such as TLS certificates. - -There are circumstances, such as during a Terraform [Refresh-only](/terraform/cli/commands/plan#planning-modes) plan, where -the value for this function will be recomputed but not propagated to resources -defined within the configuration. As such, it is recommended that this function -only be used to compare against timestamps exported by providers and not against -timestamps generated in the configuration. - -The `plantimestamp` function is not available within the Terraform console. - -## Examples - -``` -> plantimestamp() -2018-05-13T07:44:12Z -``` - -```terraform -check "terraform_io_certificate" { - data "tls_certificate" "terraform_io" { - url = "https://www.terraform.io/" - } - - assert { - condition = timecmp(plantimestamp(), data.tls_certificate.terraform_io.certificates[0].not_after) < 0 - error_message = "terraform.io certificate has expired" - } -} -``` - -## Related Functions - -* [`timestamp`](/terraform/language/functions/timestamp) returns the current timestamp when it is evaluated -during the apply step. \ No newline at end of file diff --git a/website/docs/language/functions/pow.mdx b/website/docs/language/functions/pow.mdx deleted file mode 100644 index bb1ab2f525..0000000000 --- a/website/docs/language/functions/pow.mdx +++ /dev/null @@ -1,23 +0,0 @@ ---- -page_title: pow - Functions - Configuration Language -description: The pow function raises a number to a power. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `pow` Function - -`pow` calculates an exponent, by raising its first argument to the power of the second argument. - -## Examples - -``` -> pow(3, 2) -9 -> pow(4, 0) -1 -``` diff --git a/website/docs/language/functions/range.mdx b/website/docs/language/functions/range.mdx deleted file mode 100644 index e49779a95a..0000000000 --- a/website/docs/language/functions/range.mdx +++ /dev/null @@ -1,145 +0,0 @@ ---- -page_title: range - Functions - Configuration Language -description: The range function generates sequences of numbers. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `range` Function - -`range` generates a list of numbers using a start value, a limit value, -and a step value. - -```hcl -range(max) -range(start, limit) -range(start, limit, step) -``` - -The `start` and `step` arguments can be omitted, in which case `start` defaults -to zero and `step` defaults to either one or negative one depending on whether -`limit` is greater than or less than `start`. - -The resulting list is created by starting with the given `start` value and -repeatedly adding `step` to it until the result is equal to or beyond `limit`. - -The interpretation of `limit` depends on the direction of `step`: for a positive -step, the sequence is complete when the next number is greater than or equal -to `limit`. For a negative step, it's complete when less than or equal. - -The sequence-building algorithm follows the following pseudocode: - -``` -let num = start -while num < limit: (or, for negative step, num > limit) - append num to the sequence - num = num + step -return the sequence -``` - -Because the sequence is created as a physical list in memory, Terraform imposes -an artificial limit of 1024 numbers in the resulting sequence in order to avoid -unbounded memory usage if, for example, a very large value were accidentally -passed as the limit or a very small value as the step. If the algorithm above -would append the 1025th number to the sequence, the function immediately exits -with an error. - -We recommend iterating over existing collections where possible, rather than -creating ranges. However, creating small numerical sequences can sometimes -be useful when combined with other collections in collection-manipulation -functions or `for` expressions. - -## Examples - -``` -> range(3) -[ - 0, - 1, - 2, -] - -> range(1, 4) -[ - 1, - 2, - 3, -] - -> range(1, 8, 2) -[ - 1, - 3, - 5, - 7, -] - -> range(1, 4, 0.5) -[ - 1, - 1.5, - 2, - 2.5, - 3, - 3.5, -] - -> range(4, 1) -[ - 4, - 3, - 2, -] - -> range(10, 5, -2) -[ - 10, - 8, - 6, -] -``` - -The `range` function is primarily useful when working with other collections -to produce a certain number of instances of something. For example: - -```hcl -variable "name_counts" { - type = map(number) - default = { - "foo" = 2 - "bar" = 4 - } -} - -locals { - expanded_names = { - for name, count in var.name_counts : name => [ - for i in range(count) : format("%s%02d", name, i) - ] - } -} - -output "expanded_names" { - value = local.expanded_names -} - -# Produces the following expanded_names value when run with the default -# "name_counts": -# -# { -# "bar" = [ -# "bar00", -# "bar01", -# "bar02", -# "bar03", -# ] -# "foo" = [ -# "foo00", -# "foo01", -# ] -# } -``` diff --git a/website/docs/language/functions/regex.mdx b/website/docs/language/functions/regex.mdx deleted file mode 100644 index b929133cd5..0000000000 --- a/website/docs/language/functions/regex.mdx +++ /dev/null @@ -1,167 +0,0 @@ ---- -page_title: regex - Functions - Configuration Language -description: |- - The regex function applies a regular expression to a string and returns the - matching substrings. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `regex` Function - -`regex` applies a -[regular expression](https://en.wikipedia.org/wiki/Regular_expression) -to a string and returns the matching substrings. - -```hcl -regex(pattern, string) -``` - -The return type of `regex` depends on the capture groups, if any, in the -pattern: - -- If the pattern has no capture groups at all, the result is a single string - covering the substring matched by the pattern as a whole. -- If the pattern has one or more _unnamed_ capture groups, the result is a - list of the captured substrings in the same order as the definition of - the capture groups. -- If the pattern has one or more _named_ capture groups, the result is a - map of the captured substrings, using the capture group names as map keys. - -It's not valid to mix both named and unnamed capture groups in the same pattern. - -If the given pattern does not match at all, the `regex` raises an error. To -_test_ whether a given pattern matches a string, use -[`regexall`](/terraform/language/functions/regexall) and test that the result has length greater than -zero. - -The pattern is a string containing a mixture of literal characters and special -matching operators as described in the following table. Note that when giving a -regular expression pattern as a literal quoted string in the Terraform -language, the quoted string itself already uses backslash `\` as an escape -character for the string, so any backslashes intended to be recognized as part -of the pattern must be escaped as `\\`. - -| Sequence | Matches | -| ---------------------- | -------------------------------------------------------------------------------- | -| `.` | Any character except newline | -| `[xyz]` | Any character listed between the brackets (`x`, `y`, and `z` in this example) | -| `[a-z]` | Any character between `a` and `z`, inclusive | -| `[^xyz]` | The opposite of `[xyz]` | -| `\d` | ASCII digits (0 through 9, inclusive) | -| `\D` | Anything except ASCII digits | -| `\s` | ASCII spaces (space, tab, newline, carriage return, form feed) | -| `\S` | Anything except ASCII spaces | -| `\w` | The same as `[0-9A-Za-z_]` | -| `\W` | Anything except the characters matched by `\w` | -| `[[:alnum:]]` | The same as `[0-9A-Za-z]` | -| `[[:alpha:]]` | The same as `[A-Za-z]` | -| `[[:ascii:]]` | Any ASCII character | -| `[[:blank:]]` | ASCII tab or space | -| `[[:cntrl:]]` | ASCII/Unicode control characters | -| `[[:digit:]]` | The same as `[0-9]` | -| `[[:graph:]]` | All "graphical" (printable) ASCII characters | -| `[[:lower:]]` | The same as `[a-z]` | -| `[[:print:]]` | The same as `[[:graph:]]` | -| `[[:punct:]]` | The same as ``[!-/:-@[-`{-~]`` | -| `[[:space:]]` | The same as `[\t\n\v\f\r ]` | -| `[[:upper:]]` | The same as `[A-Z]` | -| `[[:word:]]` | The same as `\w` | -| `[[:xdigit:]]` | The same as `[0-9A-Fa-f]` | -| `\pN` | Unicode character class by using single-letter class names ("N" in this example) | -| `\p{Greek}` | Unicode character class by unicode name ("Greek" in this example) | -| `\PN` | The opposite of `\pN` | -| `\P{Greek}` | The opposite of `\p{Greek}` | -| `xy` | `x` followed immediately by `y` | -| `x|y` | either `x` or `y`, preferring `x` | -| `x*` | zero or more `x`, preferring more | -| `x*?` | zero or more `x`, preferring fewer | -| `x+` | one or more `x`, preferring more | -| `x+?` | one or more `x`, preferring fewer | -| `x?` | zero or one `x`, preferring one | -| `x??` | zero or one `x`, preferring zero | -| `x{n,m}` | between `n` and `m` repetitions of `x`, preferring more | -| `x{n,m}?` | between `n` and `m` repetitions of `x`, preferring fewer | -| `x{n,}` | at least `n` repetitions of `x`, preferring more | -| `x{n,}?` | at least `n` repetitions of `x`, preferring fewer | -| `x{n}` | exactly `n` repetitions of `x` | -| `(x)` | unnamed capture group for sub-pattern `x` | -| `(?Px)` | named capture group, named `name`, for sub-pattern `x` | -| `(?:x)` | non-capturing sub-pattern `x` | -| `\*` | Literal `*` for any punctuation character `*` For example, `\.` is a literal `.` | -| `\Q...\E` | Literal `...` for any text `...` as long as it does not include literally `\E` | - -In addition to the above matching operators that consume the characters they -match, there are some additional operators that _only_ match, but consume -no characters. These are "zero-width" matching operators: - -| Sequence | Matches | -| -------- | ------------------------------------------------------------------------------------------------ | -| `^` | At the beginning of the given string | -| `$` | At the end of the given string | -| `\A` | At the beginning of the given string | -| `\z` | At the end of the given string | -| `\b` | At an ASCII word boundary (transition between `\w` and either `\W`, `\A` or `\z`, or vice-versa) | -| `\B` | Not at an ASCII word boundary | - -Terraform uses the -[RE2](https://github.com/google/re2/wiki/Syntax) regular expression language. -This engine does not support all of the features found in some other regular -expression engines; in particular, it does not support backreferences. - -## Matching Flags - -Some of the matching behaviors described above can be modified by setting -matching flags, activated using either the `(?flags)` operator (to activate -within the current sub-pattern) or the `(?flags:x)` operator (to match `x` with -the modified flags). Each flag is a single letter, and multiple flags can be -set at once by listing multiple letters in the `flags` position. -The available flags are listed in the table below: - -| Flag | Meaning | -| ---- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `i` | Case insensitive: a literal letter in the pattern matches both lowercase and uppercase versions of that letter | -| `m` | The `^` and `$` operators also match the beginning and end of lines within the string, marked by newline characters; behavior of `\A` and `\z` is unchanged | -| `s` | The `.` operator also matches newline | -| `U` | The meaning of presence or absense `?` after a repetition operator is inverted. For example, `x*` is interpreted like `x*?` and vice-versa. | - -## Examples - -``` -> regex("[a-z]+", "53453453.345345aaabbbccc23454") -aaabbbccc - -> regex("(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d)", "2019-02-01") -[ - "2019", - "02", - "01", -] - -> regex("^(?:(?P[^:/?#]+):)?(?://(?P[^/?#]*))?", "https://terraform.io/docs/") -{ - "authority" = "terraform.io" - "scheme" = "https" -} - -> regex("[a-z]+", "53453453.34534523454") - -Error: Error in function call - -Call to function "regex" failed: pattern did not match any part of the given -string. -``` - -## Related Functions - -- [`regexall`](/terraform/language/functions/regexall) searches for potentially multiple matches of a given pattern in a string. -- [`replace`](/terraform/language/functions/replace) replaces a substring of a string with another string, optionally matching using the same regular expression syntax as `regex`. - -If Terraform already has a more specialized function to parse the syntax you -are trying to match, prefer to use that function instead. Regular expressions -can be hard to read and can obscure your intent, making a configuration harder -to read and understand. diff --git a/website/docs/language/functions/regexall.mdx b/website/docs/language/functions/regexall.mdx deleted file mode 100644 index 22759f2079..0000000000 --- a/website/docs/language/functions/regexall.mdx +++ /dev/null @@ -1,63 +0,0 @@ ---- -page_title: regexall - Functions - Configuration Language -description: >- - The regex function applies a regular expression to a string and returns a list - of all matches. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `regexall` Function - -`regexall` applies a -[regular expression](https://en.wikipedia.org/wiki/Regular_expression) -to a string and returns a list of all matches. - -```hcl -regexall(pattern, string) -``` - -`regexall` is a variant of [`regex`](/terraform/language/functions/regex) and uses the same pattern -syntax. For any given input to `regex`, `regexall` returns a list of whatever -type `regex` would've returned, with one element per match. That is: - -- If the pattern has no capture groups at all, the result is a list of - strings. -- If the pattern has one or more _unnamed_ capture groups, the result is a - list of lists. -- If the pattern has one or more _named_ capture groups, the result is a - list of maps. - -`regexall` can also be used to test whether a particular string matches a -given pattern, by testing whether the length of the resulting list of matches -is greater than zero. - -## Examples - -``` -> regexall("[a-z]+", "1234abcd5678efgh9") -[ - "abcd", - "efgh", -] - -> length(regexall("[a-z]+", "1234abcd5678efgh9")) -2 - -> length(regexall("[a-z]+", "123456789")) > 0 -false -``` - -## Related Functions - -- [`regex`](/terraform/language/functions/regex) searches for a single match of a given pattern, and - returns an error if no match is found. - -If Terraform already has a more specialized function to parse the syntax you -are trying to match, prefer to use that function instead. Regular expressions -can be hard to read and can obscure your intent, making a configuration harder -to read and understand. diff --git a/website/docs/language/functions/replace.mdx b/website/docs/language/functions/replace.mdx deleted file mode 100644 index 1f476ad8ad..0000000000 --- a/website/docs/language/functions/replace.mdx +++ /dev/null @@ -1,43 +0,0 @@ ---- -page_title: replace - Functions - Configuration Language -description: |- - The replace function searches a given string for another given substring, - and replaces all occurrences with a given replacement string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `replace` Function - -`replace` searches a given string for another given substring, and replaces -each occurrence with a given replacement string. - -```hcl -replace(string, substring, replacement) -``` - -If `substring` is wrapped in forward slashes, it is treated as a regular -expression, using the same pattern syntax as -[`regex`](/terraform/language/functions/regex). If using a regular expression for the substring -argument, the `replacement` string can incorporate captured strings from -the input by using an `$n` sequence, where `n` is the index or name of a -capture group. - -## Examples - -``` -> replace("1 + 2 + 3", "+", "-") -1 - 2 - 3 - -> replace("hello world", "/w.*d/", "everybody") -hello everybody -``` - -## Related Functions - -- [`regex`](/terraform/language/functions/regex) searches a given string for a substring matching a - given regular expression pattern. diff --git a/website/docs/language/functions/reverse.mdx b/website/docs/language/functions/reverse.mdx deleted file mode 100644 index 7f3bad66c0..0000000000 --- a/website/docs/language/functions/reverse.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -page_title: reverse - Functions - Configuration Language -description: The reverse function reverses a sequence. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `reverse` Function - -`reverse` takes a sequence and produces a new sequence of the same length -with all of the same elements as the given sequence but in reverse order. - -## Examples - -``` -> reverse([1, 2, 3]) -[ - 3, - 2, - 1, -] -``` - -## Related Functions - -* [`strrev`](/terraform/language/functions/strrev) reverses a string. diff --git a/website/docs/language/functions/rsadecrypt.mdx b/website/docs/language/functions/rsadecrypt.mdx deleted file mode 100644 index 53f52f79ad..0000000000 --- a/website/docs/language/functions/rsadecrypt.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: rsadecrypt - Functions - Configuration Language -description: The rsadecrypt function decrypts an RSA-encrypted message. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `rsadecrypt` Function - -`rsadecrypt` decrypts an RSA-encrypted ciphertext, returning the corresponding -cleartext. - -```hcl -rsadecrypt(ciphertext, privatekey) -``` - -`ciphertext` must be a base64-encoded representation of the ciphertext, using -the PKCS #1 v1.5 padding scheme. Terraform uses the "standard" Base64 alphabet -as defined in [RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -`privatekey` must be a PEM-encoded RSA private key that is not itself -encrypted. - -Terraform has no corresponding function for _encrypting_ a message. Use this -function to decrypt ciphertexts returned by remote services using a keypair -negotiated out-of-band. - -## Examples - -``` -> rsadecrypt(filebase64("${path.module}/ciphertext"), file("privatekey.pem")) -Hello, world! -``` diff --git a/website/docs/language/functions/sensitive.mdx b/website/docs/language/functions/sensitive.mdx deleted file mode 100644 index b87951f1d5..0000000000 --- a/website/docs/language/functions/sensitive.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: sensitive - Functions - Configuration Language -description: The sensitive function marks a value as being sensitive. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sensitive` Function - --> **Note:** This function is only available in Terraform v0.15 and later. - -`sensitive` takes any value and returns a copy of it marked so that Terraform -will treat it as sensitive, with the same meaning and behavior as for -[sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output). - -Wherever possible we recommend marking your input variable and/or output value -declarations as sensitive directly, instead of using this function, because in -that case you can be sure that there is no way to refer to those values without -Terraform automatically considering them as sensitive. - -The `sensitive` function might be useful in some less-common situations where a -sensitive value arises from a definition _within_ your module, such as if you've -loaded sensitive data from a file on disk as part of your configuration: - -```hcl -locals { - sensitive_content = sensitive(file("${path.module}/sensitive.txt")) -} -``` - -However, we generally don't recommend writing sensitive values directly within -your module any of the files you distribute statically as part of that module, -because they may be exposed in other ways outside of Terraform's control. - -## Examples - -``` -> sensitive(1) -(sensitive value) -> sensitive("hello") -(sensitive value) -> sensitive([]) -(sensitive value) -``` diff --git a/website/docs/language/functions/setintersection.mdx b/website/docs/language/functions/setintersection.mdx deleted file mode 100644 index 9a6dafdcd9..0000000000 --- a/website/docs/language/functions/setintersection.mdx +++ /dev/null @@ -1,81 +0,0 @@ ---- -page_title: setintersection function reference - Functions - Configuration Language -description: |- - The setintersection function takes multiple arrays and produces a single array - containing only the elements that all of the given arrays have in common. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `setintersection` function reference - -This topic provides reference information about the `setintersection` function, -which computes the intersection of the specified sets. - -## Introduction - -The `setintersection` function takes multiple sets and produces a single set -containing only the elements that all of the given sets have in common. -In other words, `setintersection` computes the intersection of the sets. -Refer to Wikipedia's [Intersection (set -theory)](https://en.wikipedia.org/wiki/Intersection_\(set_theory\)) article -for a mathematical explanantion of set theory intersection. - -## Syntax - -Use the `setintersection` function with the following syntax: - -```hcl -setintersection(sets...) -``` - -Replace `sets...` with a comma-delimited list of sets such as `["a","b"], ["a","c","g"]`. The elements of -the different sets do not have to be the same type. - -The `setintersection` result is an unordered set. - -## Example use cases - -This example passes in sets of strings and returns a set with one element. - -```hcl -> setintersection(["a", "b"], ["b", "c"], ["b", "d"]) -[ - "b", -] -``` - -This example passes in number sets of different sizes and returns a set with two elements. - -```hcl -> setintersection([3,3.3,4], [4,3.3,65,99], [4.0,3.3]) -toset([ - 3.3, - 4, -]) -``` - -This examples pass in sets of different lengths and element types. -The result is a set of two string elements. - -```hcl -> setintersection(["bob","jane",3], ["jane",3,"ajax",10], ["3","jane",26,"nomad"]) -toset([ - "3", - "jane", -]) -``` - -## Related Functions - -* [`contains`](/terraform/language/functions/contains) tests whether a given list or set contains - a given element value. -* [`setproduct`](/terraform/language/functions/setproduct) computes the _Cartesian product_ of multiple - sets. -* [`setsubtract`](/terraform/language/functions/setsubtract) computes the _relative complement_ of two sets -* [`setunion`](/terraform/language/functions/setunion) computes the _union_ of - multiple sets. diff --git a/website/docs/language/functions/setproduct.mdx b/website/docs/language/functions/setproduct.mdx deleted file mode 100644 index 6957c5ea30..0000000000 --- a/website/docs/language/functions/setproduct.mdx +++ /dev/null @@ -1,287 +0,0 @@ ---- -page_title: setproduct - Functions - Configuration Language -description: |- - The setproduct function finds all of the possible combinations of elements - from all of the given sets by computing the cartesian product. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `setproduct` Function - -The `setproduct` function finds all of the possible combinations of elements -from all of the given sets by computing the -[Cartesian product](https://en.wikipedia.org/wiki/Cartesian_product). - -```hcl -setproduct(sets...) -``` - -This function is particularly useful for finding the exhaustive set of all -combinations of members of multiple sets, such as per-application-per-environment -resources. - -``` -> setproduct(["development", "staging", "production"], ["app1", "app2"]) -[ - [ - "development", - "app1", - ], - [ - "development", - "app2", - ], - [ - "staging", - "app1", - ], - [ - "staging", - "app2", - ], - [ - "production", - "app1", - ], - [ - "production", - "app2", - ], -] -``` - -You must pass at least two arguments to this function. - -Although defined primarily for sets, this function can also work with lists. -If all of the given arguments are lists then the result is a list, preserving -the ordering of the given lists. Otherwise the result is a set. In either case, -the result's element type is a list of values corresponding to each given -argument in turn. - -## Examples - -There is an example of the common usage of this function above. There are some -other situations that are less common when hand-writing but may arise in -reusable module situations. - -If any of the arguments is empty then the result is always empty itself, -similar to how multiplying any number by zero gives zero: - -``` -> setproduct(["development", "staging", "production"], []) -[] -``` - -Similarly, if all of the arguments have only one element then the result has -only one element, which is the first element of each argument: - -``` -> setproduct(["a"], ["b"]) -[ - [ - "a", - "b", - ], -] -``` - -Each argument must have a consistent type for all of its elements. If not, -Terraform will attempt to convert to the most general type, or produce an -error if such a conversion is impossible. For example, mixing both strings and -numbers results in the numbers being converted to strings so that the result -elements all have a consistent type: - -``` -> setproduct(["staging", "production"], ["a", 2]) -[ - [ - "staging", - "a", - ], - [ - "staging", - "2", - ], - [ - "production", - "a", - ], - [ - "production", - "2", - ], -] -``` - -## Finding combinations for `for_each` - -The -[resource `for_each`](/terraform/language/meta-arguments/for_each) -and -[`dynamic` block](/terraform/language/expressions/dynamic-blocks) -language features both require a collection value that has one element for -each repetition. - -Sometimes your input data comes in separate values that cannot be directly -used in a `for_each` argument, and `setproduct` can be a useful helper function -for the situation where you want to find all unique combinations of elements in -a number of different collections. - -For example, consider a module that declares variables like the following: - -```hcl -variable "networks" { - type = map(object({ - base_cidr_block = string - })) -} - -variable "subnets" { - type = map(object({ - number = number - })) -} -``` - -If the goal is to create each of the defined subnets per each of the defined networks, creating the top-level networks can directly use `var.networks` because it is already in a form where the resulting instances match one-to-one with map elements: - -```hcl -resource "aws_vpc" "example" { - for_each = var.networks - - cidr_block = each.value.base_cidr_block -} -``` - -However, to declare all of the _subnets_ with a single `resource` block, you must first produce a collection whose elements represent all of the combinations of networks and subnets, so that each element itself represents a subnet: - -```hcl -locals { - # setproduct works with sets and lists, but the variables are both maps - # so convert them first. - networks = [ - for key, network in var.networks : { - key = key - cidr_block = network.cidr_block - } - ] - subnets = [ - for key, subnet in var.subnets : { - key = key - number = subnet.number - } - ] - - network_subnets = [ - # in pair, element zero is a network and element one is a subnet, - # in all unique combinations. - for pair in setproduct(local.networks, local.subnets) : { - network_key = pair[0].key - subnet_key = pair[1].key - network_id = aws_vpc.example[pair[0].key].id - - # The cidr_block is derived from the corresponding network. Refer to the - # cidrsubnet function for more information on how this calculation works. - cidr_block = cidrsubnet(pair[0].cidr_block, 4, pair[1].number) - } - ] -} - -resource "aws_subnet" "example" { - # local.network_subnets is a list, so project it into a map - # where each key is unique. Combine the network and subnet keys to - # produce a single unique key per instance. - for_each = tomap({ - for subnet in local.network_subnets : "${subnet.network_key}.${subnet.subnet_key}" => subnet - }) - - vpc_id = each.value.network_id - availability_zone = each.value.subnet_key - cidr_block = each.value.cidr_block -} -``` - -The `network_subnets` list in the example above creates one subnet instance per combination of network and subnet elements in the input variables. So for this example input: - -```hcl -networks = { - a = { - base_cidr_block = "10.1.0.0/16" - } - b = { - base_cidr_block = "10.2.0.0/16" - } -} -subnets = { - a = { - number = 1 - } - b = { - number = 2 - } - c = { - number = 3 - } -} -``` - -The `network_subnets` output would look similar to the following: - -```hcl -[ - { - "cidr_block" = "10.1.16.0/20" - "network_id" = "vpc-0bfb00ca6173ea5aa" - "network_key" = "a" - "subnet_key" = "a" - }, - { - "cidr_block" = "10.1.32.0/20" - "network_id" = "vpc-0bfb00ca6173ea5aa" - "network_key" = "a" - "subnet_key" = "b" - }, - { - "cidr_block" = "10.1.48.0/20" - "network_id" = "vpc-0bfb00ca6173ea5aa" - "network_key" = "a" - "subnet_key" = "c" - }, - { - "cidr_block" = "10.2.16.0/20" - "network_id" = "vpc-0d193e011f6211a7d" - "network_key" = "b" - "subnet_key" = "a" - }, - { - "cidr_block" = "10.2.32.0/20" - "network_id" = "vpc-0d193e011f6211a7d" - "network_key" = "b" - "subnet_key" = "b" - }, - { - "cidr_block" = "10.2.48.0/20" - "network_id" = "vpc-0d193e011f6211a7d" - "network_key" = "b" - "subnet_key" = "c" - }, -] -``` - -## Related Functions - -- [`contains`](/terraform/language/functions/contains) tests whether a given list or set contains - a given element value. -- [`flatten`](/terraform/language/functions/flatten) is useful for flattening hierarchical data - into a single list, for situations where the relationships between two - object types are defined explicitly. -- [`setintersection`](/terraform/language/functions/setintersection) computes the _intersection_ of - multiple sets. -- [`setsubtract`](/terraform/language/functions/setsubtract) computes the _relative complement_ of two sets -- [`setunion`](/terraform/language/functions/setunion) computes the _union_ of multiple - sets. diff --git a/website/docs/language/functions/setsubtract.mdx b/website/docs/language/functions/setsubtract.mdx deleted file mode 100644 index 35285449b3..0000000000 --- a/website/docs/language/functions/setsubtract.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: setsubtract - Functions - Configuration Language -description: |- - The setsubtract function returns a new set containing the elements - from the first set that are not present in the second set ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `setsubtract` Function - -The `setsubtract` function returns a new set containing the elements from the first set that are not present in the second set. In other words, it computes the -[relative complement](https://en.wikipedia.org/wiki/Complement_\(set_theory\)#Relative_complement) of the second set. - -```hcl -setsubtract(a, b) -``` - -## Examples - -``` -> setsubtract(["a", "b", "c"], ["a", "c"]) -toset([ - "b", -]) -``` - -### Set Difference (Symmetric Difference) - -``` -> setunion(setsubtract(["a", "b", "c"], ["a", "c", "d"]), setsubtract(["a", "c", "d"], ["a", "b", "c"])) -toset([ - "b", - "d", -]) -``` - -## Related Functions - -* [`setintersection`](/terraform/language/functions/setintersection) computes the _intersection_ of multiple sets -* [`setproduct`](/terraform/language/functions/setproduct) computes the _Cartesian product_ of multiple - sets. -* [`setunion`](/terraform/language/functions/setunion) computes the _union_ of - multiple sets. diff --git a/website/docs/language/functions/setunion.mdx b/website/docs/language/functions/setunion.mdx deleted file mode 100644 index e1f226d0b5..0000000000 --- a/website/docs/language/functions/setunion.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: setunion - Functions - Configuration Language -description: |- - The setunion function takes multiple sets and produces a single set - containing the elements from all of the given sets. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `setunion` Function - -The `setunion` function takes multiple sets and produces a single set -containing the elements from all of the given sets. In other words, it -computes the [union](https://en.wikipedia.org/wiki/Union_\(set_theory\)) of -the sets. - -```hcl -setunion(sets...) -``` - -## Examples - -``` -> setunion(["a", "b"], ["b", "c"], ["d"]) -[ - "d", - "b", - "c", - "a", -] -``` - -The given arguments are converted to sets, so the result is also a set and -the ordering of the given elements is not preserved. - -## Related Functions - -* [`contains`](/terraform/language/functions/contains) tests whether a given list or set contains - a given element value. -* [`setintersection`](/terraform/language/functions/setintersection) computes the _intersection_ of - multiple sets. -* [`setproduct`](/terraform/language/functions/setproduct) computes the _Cartesian product_ of multiple - sets. -* [`setsubtract`](/terraform/language/functions/setsubtract) computes the _relative complement_ of two sets diff --git a/website/docs/language/functions/sha1.mdx b/website/docs/language/functions/sha1.mdx deleted file mode 100644 index cb35a39c62..0000000000 --- a/website/docs/language/functions/sha1.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: sha1 - Functions - Configuration Language -description: |- - The sha1 function computes the SHA1 hash of a given string and encodes it - with hexadecimal digits. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sha1` Function - -`sha1` computes the SHA1 hash of a given string and encodes it with -hexadecimal digits. - -The given string is first encoded as UTF-8 and then the SHA1 algorithm is applied -as defined in [RFC 3174](https://tools.ietf.org/html/rfc3174). The raw hash is -then encoded to lowercase hexadecimal digits before returning. - -Collision attacks have been successfully performed against this hashing -function. Before using this function for anything security-sensitive, review -relevant literature to understand the security implications. - -## Examples - -``` -> sha1("hello world") -2aae6c35c94fcfb415dbe95f408b9ce91ee846ed -``` - -## Related Functions - -* [`filesha1`](/terraform/language/functions/filesha1) calculates the same hash from - the contents of a file rather than from a string value. diff --git a/website/docs/language/functions/sha256.mdx b/website/docs/language/functions/sha256.mdx deleted file mode 100644 index 969a10cf0b..0000000000 --- a/website/docs/language/functions/sha256.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: sha256 - Functions - Configuration Language -description: |- - The sha256 function computes the SHA256 hash of a given string and encodes it - with hexadecimal digits. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sha256` Function - -`sha256` computes the SHA256 hash of a given string and encodes it with -hexadecimal digits. - -The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied -as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is -then encoded to lowercase hexadecimal digits before returning. - -## Examples - -``` -> sha256("hello world") -b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 -``` - -## Related Functions - -## Related Functions - -* [`filesha256`](/terraform/language/functions/filesha256) calculates the same hash from - the contents of a file rather than from a string value. -* [`base64sha256`](/terraform/language/functions/base64sha256) calculates the same hash but returns - the result in a more-compact Base64 encoding. diff --git a/website/docs/language/functions/sha512.mdx b/website/docs/language/functions/sha512.mdx deleted file mode 100644 index 61c2118598..0000000000 --- a/website/docs/language/functions/sha512.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -page_title: sha512 - Functions - Configuration Language -description: |- - The sha512 function computes the SHA512 hash of a given string and encodes it - with hexadecimal digits. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sha512` Function - -`sha512` computes the SHA512 hash of a given string and encodes it with -hexadecimal digits. - -The given string is first encoded as UTF-8 and then the SHA512 algorithm is applied -as defined in [RFC 4634](https://tools.ietf.org/html/rfc4634). The raw hash is -then encoded to lowercase hexadecimal digits before returning. - -## Examples - -``` -> sha512("hello world") -309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f -``` - -## Related Functions - -* [`filesha512`](/terraform/language/functions/filesha512) calculates the same hash from - the contents of a file rather than from a string value. -* [`base64sha512`](/terraform/language/functions/base64sha512) calculates the same hash but returns - the result in a more-compact Base64 encoding. diff --git a/website/docs/language/functions/signum.mdx b/website/docs/language/functions/signum.mdx deleted file mode 100644 index 6371f15a4b..0000000000 --- a/website/docs/language/functions/signum.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -page_title: signum - Functions - Configuration Language -description: The signum function determines the sign of a number. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `signum` Function - -`signum` determines the sign of a number, returning a number between -1 and -1 to represent the sign. - -## Examples - -``` -> signum(-13) --1 -> signum(0) -0 -> signum(344) -1 -``` diff --git a/website/docs/language/functions/slice.mdx b/website/docs/language/functions/slice.mdx deleted file mode 100644 index 29f0c0182f..0000000000 --- a/website/docs/language/functions/slice.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: slice - Functions - Configuration Language -description: The slice function extracts some consecutive elements from within a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `slice` Function - -`slice` extracts some consecutive elements from within a list. - -```hcl -slice(list, startindex, endindex) -``` - -`startindex` is inclusive, while `endindex` is exclusive. This function returns -an error if either index is outside the bounds of valid indices for the given -list. - -## Examples - -``` -> slice(["a", "b", "c", "d"], 1, 3) -[ - "b", - "c", -] -``` - -## Related Functions - -* [`substr`](/terraform/language/functions/substr) performs a similar function for characters in a - string, although it uses a length instead of an end index. diff --git a/website/docs/language/functions/sort.mdx b/website/docs/language/functions/sort.mdx deleted file mode 100644 index cf70622404..0000000000 --- a/website/docs/language/functions/sort.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: sort - Functions - Configuration Language -description: |- - The sort function takes a list of strings and returns a new list with those - strings sorted lexicographically. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sort` Function - -`sort` takes a list of strings and returns a new list with those strings -sorted lexicographically. - -The sort is in terms of Unicode codepoints, with higher codepoints appearing -after lower ones in the result. - -## Examples - -``` -> sort(["e", "d", "a", "x"]) -[ - "a", - "d", - "e", - "x", -] -``` diff --git a/website/docs/language/functions/split.mdx b/website/docs/language/functions/split.mdx deleted file mode 100644 index 8fc176d1a3..0000000000 --- a/website/docs/language/functions/split.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -page_title: split - Functions - Configuration Language -description: |- - The split function produces a list by dividing a given string at all - occurrences of a given separator. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `split` Function - -`split` produces a list by dividing a given string at all occurrences of a -given separator. - -```hcl -split(separator, string) -``` - -## Examples - -``` -> split(",", "foo,bar,baz") -[ - "foo", - "bar", - "baz", -] -> split(",", "foo") -[ - "foo", -] -> split(",", "") -[ - "", -] -``` - -## Related Functions - -* [`join`](/terraform/language/functions/join) performs the opposite operation: producing a string - joining together a list of strings with a given separator. diff --git a/website/docs/language/functions/startswith.mdx b/website/docs/language/functions/startswith.mdx deleted file mode 100644 index b9a79ad883..0000000000 --- a/website/docs/language/functions/startswith.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: startswith - Functions - Configuration Language -description: |- - The startswith function takes two values: a string to check and a prefix string. It returns true if the string begins with that exact prefix. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `startswith` Function - -`startswith` takes two values: a string to check and a prefix string. The function returns true if the string begins with that exact prefix. - -```hcl -startswith(string, prefix) -``` - -## Examples - -``` -> startswith("hello world", "hello") -true - -> startswith("hello world", "world") -false -``` - -## Related Functions - -- [`endswith`](/terraform/language/functions/endswith) takes two values: a string to check and a suffix string. The function returns true if the first string ends with that exact suffix. \ No newline at end of file diff --git a/website/docs/language/functions/strcontains.mdx b/website/docs/language/functions/strcontains.mdx deleted file mode 100644 index 5906e94075..0000000000 --- a/website/docs/language/functions/strcontains.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -page_title: strcontains - Functions - Configuration Language -description: |- - The strcontains function checks whether a given string can be found within another string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `strcontains` Function - -`strcontains` function checks whether a substring is within another string. - -```hcl -strcontains(string, substr) -``` - -## Examples - -``` -> strcontains("hello world", "wor") -true -``` - -``` -> strcontains("hello world", "wod") -false -``` \ No newline at end of file diff --git a/website/docs/language/functions/strrev.mdx b/website/docs/language/functions/strrev.mdx deleted file mode 100644 index 76b92c28b3..0000000000 --- a/website/docs/language/functions/strrev.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: strrev - Functions - Configuration Language -description: The strrev function reverses a string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `strrev` Function - -`strrev` reverses the characters in a string. -Note that the characters are treated as _Unicode characters_ (in technical terms, Unicode [grapheme cluster boundaries](https://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) are respected). - -```hcl -strrev(string) -``` - -## Examples - -``` -> strrev("hello") -olleh -> strrev("a ☃") -☃ a -``` - -## Related Functions - -* [`reverse`](/terraform/language/functions/reverse) reverses a sequence. diff --git a/website/docs/language/functions/substr.mdx b/website/docs/language/functions/substr.mdx deleted file mode 100644 index 09b6b59581..0000000000 --- a/website/docs/language/functions/substr.mdx +++ /dev/null @@ -1,52 +0,0 @@ ---- -page_title: substr - Functions - Configuration Language -description: |- - The substr function extracts a substring from a given string by offset and - length. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `substr` Function - -`substr` extracts a substring from a given string by offset and (maximum) length. - -```hcl -substr(string, offset, length) -``` - -## Examples - -``` -> substr("hello world", 1, 4) -ello -``` - -The offset and length are both counted in _unicode characters_ rather than -bytes: - -``` -> substr("🤔🤷", 0, 1) -🤔 -``` - -The offset index may be negative, in which case it is relative to the end of -the given string. The length may be -1, in which case the remainder of the -string after the given offset will be returned. - -``` -> substr("hello world", -5, -1) -world -``` - -If the length is greater than the length of the string, the substring -will be the length of all remaining characters. - -``` -> substr("hello world", 6, 10) -world -``` diff --git a/website/docs/language/functions/sum.mdx b/website/docs/language/functions/sum.mdx deleted file mode 100644 index 9b7dd7c85d..0000000000 --- a/website/docs/language/functions/sum.mdx +++ /dev/null @@ -1,25 +0,0 @@ ---- -page_title: sum - Functions - Configuration Language -description: |- - The sum function takes a list or set of numbers and returns the sum of those - numbers. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `sum` Function - -`sum` takes a list or set of numbers and returns the sum of those numbers. - -`sum` fails when given an empty list or set. - -## Examples - -``` -> sum([10, 13, 6, 4.5]) -33.5 -``` diff --git a/website/docs/language/functions/templatefile.mdx b/website/docs/language/functions/templatefile.mdx deleted file mode 100644 index e35d937245..0000000000 --- a/website/docs/language/functions/templatefile.mdx +++ /dev/null @@ -1,156 +0,0 @@ ---- -page_title: templatefile - Functions - Configuration Language -description: |- - The templatefile function reads the file at the given path and renders its - content as a template. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `templatefile` Function - -`templatefile` reads the file at the given path and renders its content -as a template using a supplied set of template variables. - -```hcl -templatefile(path, vars) -``` - -The template syntax is the same as for -[string templates](/terraform/language/expressions/strings#string-templates) -in the main Terraform language, including interpolation sequences delimited with -`${` ... `}`. This function just allows longer template sequences to be factored -out into a separate file for readability. - -The "vars" argument must be an object. Within the template file, each of the -keys in the map is available as a variable for interpolation. The template may -also use any other function available in the Terraform language, except that -recursive calls to `templatefile` are not permitted. Variable names must -each start with a letter, followed by zero or more letters, digits, or -underscores. - -Strings in the Terraform language are sequences of Unicode characters, so -this function will interpret the file contents as UTF-8 encoded text and -return the resulting Unicode characters. If the file contains invalid UTF-8 -sequences then this function will produce an error. - -This function can be used only with files that already exist on disk at the -beginning of a Terraform run. Functions do not participate in the dependency -graph, so this function cannot be used with files that are generated -dynamically during a Terraform operation. - -`*.tftpl` is the recommended naming pattern to use for your template files. -Terraform will not prevent you from using other names, but following this -convention will help your editor understand the content and likely provide -better editing experience as a result. - -## Examples - -### Lists - -Given a template file `backends.tftpl` with the following content: - -``` -%{ for addr in ip_addrs ~} -backend ${addr}:${port} -%{ endfor ~} -``` - -The `templatefile` function renders the template: - -``` -> templatefile("${path.module}/backends.tftpl", { port = 8080, ip_addrs = ["10.0.0.1", "10.0.0.2"] }) -backend 10.0.0.1:8080 -backend 10.0.0.2:8080 -``` - -### Maps - -Given a template file `config.tftpl` with the following content: - -``` -%{ for config_key, config_value in config } -set ${config_key} = ${config_value} -%{ endfor ~} -``` - -The `templatefile` function renders the template: - -``` -> templatefile( - "${path.module}/config.tftpl", - { - config = { - "x" = "y" - "foo" = "bar" - "key" = "value" - } - } - ) -set foo = bar -set key = value -set x = y -``` - -### Generating JSON or YAML from a template - -If the string you want to generate will be in JSON or YAML syntax, it's -often tricky and tedious to write a template that will generate valid JSON or -YAML that will be interpreted correctly when using lots of individual -interpolation sequences and directives. - -Instead, you can write a template that consists only of a single interpolated -call to either [`jsonencode`](/terraform/language/functions/jsonencode) or -[`yamlencode`](/terraform/language/functions/yamlencode), specifying the value to encode using -[normal Terraform expression syntax](/terraform/language/expressions) -as in the following examples: - -``` -${jsonencode({ - "backends": [for addr in ip_addrs : "${addr}:${port}"], -})} -``` - -``` -${yamlencode({ - "backends": [for addr in ip_addrs : "${addr}:${port}"], -})} -``` - -Given the same input as the `backends.tftpl` example in the previous section, -this will produce a valid JSON or YAML representation of the given data -structure, without the need to manually handle escaping or delimiters. -In the latest examples above, the repetition based on elements of `ip_addrs` is -achieved by using a -[`for` expression](/terraform/language/expressions/for) -rather than by using -[template directives](/terraform/language/expressions/strings#directives). - -```json -{"backends":["10.0.0.1:8080","10.0.0.2:8080"]} -``` - -If the resulting template is small, you can choose instead to write -`jsonencode` or `yamlencode` calls inline in your main configuration files, and -avoid creating separate template files at all: - -```hcl -locals { - backend_config_json = jsonencode({ - "backends": [for addr in ip_addrs : "${addr}:${port}"], - }) -} -``` - -For more information, see the main documentation for -[`jsonencode`](/terraform/language/functions/jsonencode) and [`yamlencode`](/terraform/language/functions/yamlencode). - -## Related Functions - -* [`file`](/terraform/language/functions/file) reads a file from disk and returns its literal contents - without any template interpretation. -* [`templatestring`](/terraform/language/functions/templatestring) takes a simple reference to a string value containing the template and renders its content. diff --git a/website/docs/language/functions/templatestring.mdx b/website/docs/language/functions/templatestring.mdx deleted file mode 100644 index eb81b8b049..0000000000 --- a/website/docs/language/functions/templatestring.mdx +++ /dev/null @@ -1,74 +0,0 @@ ---- -page_title: templatestring - Functions - Configuration Language -description: |- - The templatestring function takes a string from elsewhere in the module and renders its content as a template using a supplied set of template 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `templatestring` function reference - -This topic provides reference information about the `templatestring` function. The `templatestring` function renders a string defined elsewhere in the module as a template using a set of variables. - -## Introduction - -The primary use case for the `templatestring` function is to render templates fetched as a single string from remote locations. The function enables advanced use cases where a [string template expression](/terraform/language/expressions/strings#string-templates) is insufficient, such as when the template is available from a named object declared in the current module. Refer to [Dynamic template construction](#dynamic-template-construction) for additional information. - -To render a template from a file, use the [`templatefile` function](/terraform/language/functions/templatefile). - -## Syntax - -Write `templatestring` functions using the following syntax: - -```hcl -templatestring(ARG1, ARG2, . . .) -``` - -Specify the following arguments: - -- The first argument is always a reference to an object defined in the module. You cannot supply the template expression directly as the first argument. -- The second argument is an object that specifies a variable to use for rendering the template. -- You can specify additional arguments to use multiple variables for the template. - -In the following example, the function renders the string value located at `data.aws_s3_object.example.body` as the template: - -```hcl -templatestring(data.aws_s3_object.example.body, { - name = var.name -}) -``` - -For information about the syntax you can use for the variables arguments, refer to [Strings and Templates](/terraform/language/expressions/strings). - -## Example use case - -The following example retrieves a template from S3 and dynamically renders it: - -```hcl -data "aws_s3_object" "example" { - bucket = "example-example" - key = "example.tmpl" -} - -output "example" { - value = templatestring(data.aws_s3_object.example.body, { - name = var.name - }) -} -``` - -For more examples of how to use templates, refer to the documentation for [the `templatefile` function](/terraform/language/functions/templatefile#Examples). - -## Dynamic template construction - -You can write an expression that builds a template dynamically and then assigns it to a [local value](/terraform/language/values/locals). You can then use a reference to that local value as the first argument to the `templatestring` function. - -Note that you should only dynamically construct templates in this way when no other alternative is feasible. This is because the result can be difficult to understand and maintain and is susceptible to unexpected inputs. Built-in Terraform functions may interact with the local filesystem. As a result, the inputs may produce a template that includes data from arbitrary files on the system where Terraform is running. - -## Related Functions - -* [`templatefile`](/terraform/language/functions/templatefile) reads a file from disk and renders its content as a template. diff --git a/website/docs/language/functions/terraform-applying.mdx b/website/docs/language/functions/terraform-applying.mdx deleted file mode 100644 index 71df82ac53..0000000000 --- a/website/docs/language/functions/terraform-applying.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -page_title: terraform.applying reference - Functions - Configuration Language -description: |- - The terraform.applying symbol enables you to determine if Terraform is currently running an apply operation. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `terraform.applying` symbol - --> **Note**: The `terraform.applying` symbol is available in Terraform v1.10 and later. - -You can use the `terraform.applying` symbol in your configuration to determine if Terraform is currently running an apply operation. - -Terraform automatically sets `terraform.applying` to `true` when you run an [apply](/terraform/cli/commands/apply) operation, and `false` during any other operation. The [planning mode](/terraform/cli/commands/plan#planning-modes) you run `terraform apply` in does not affect `terraform.applying`, meaning that even in destroy mode, `terraform.applying` is still `true`. - -You can use `terraform.applying` to change Terraform behavior during apply operations. In the following example, Terraform uses your read-only credentials when running a plan operation but uses your write credentials when you run an apply operation: - -```hcl -locals { - aws_read_role_arn = "arn:aws:iam::XXXXX:role/terraform-read" - aws_write_role_arn = "arn:aws:iam::XXXXX:role/terraform-full" - - role_arn = terraform.applying ? local.aws_write_role_arn : local.aws_read_role_arn -} - -provider "aws" { - region = "us-west-2" - - assume_role { - role_arn = local.role_arn - } -} - -``` - - -The `terraform.applying` symbol is an ephemeral value and is only available during Terraform operations. Terraform does not write ephemeral values to plan or state files. Additionally, you can only reference `terraform.applying` in the following ephemeral contexts: - -- In a [write-only argument](/terraform/language/resources/ephemeral/write-only) -- In [ephemeral variables](/terraform/language/values/variables#exclude-values-from-state) -- In [local values](/terraform/language/values/locals#ephemeral-values) -- In [ephemeral resources](/terraform/language/resources/ephemeral) -- In [ephemeral outputs](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files) -- Configuring providers in the `provider` block -- In [provisioner](/terraform/language/resources/provisioners/syntax) and [connection](/terraform/language/resources/provisioners/connection) blocks diff --git a/website/docs/language/functions/terraform-decode_tfvars.mdx b/website/docs/language/functions/terraform-decode_tfvars.mdx deleted file mode 100644 index d72b22940a..0000000000 --- a/website/docs/language/functions/terraform-decode_tfvars.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -page_title: provider::terraform::decode_tfvars - Functions - Configuration Language -description: >- - The decode_tfvars function parses a string containing syntax like that used - in a ".tfvars" 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `provider::terraform::decode_tfvars` Function - --> **Note:** This function is supported only in Terraform v1.8 and later. - -`provider::terraform::decode_tfvars` is a rarely-needed function which takes -a string containing the content of a -[`.tfvars` file](/terraform/language/values/variables#variable-definitions-tfvars-files) -and returns an object describing the raw variable values it defines. - -To use this function, your module must declare a dependency on the built-in -`terraform` provider, which contains this function: - -```hcl -terraform { - required_providers { - terraform = { - source = "terraform.io/builtin/terraform" - } - } -} -``` - -Elsewhere in your module you can then call this function: - -```hcl -provider::terraform::decode_tfvars( - <- - The encode_expr function produces a string representation of an arbitrary value - using Terraform expression syntax. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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::terraform::encode_expr` Function - --> **Note:** This function is supported only in Terraform v1.8 and later. - -`provider::terraform::encode_expr` is a rarely-needed function which takes -any value and produces a string containing Terraform language expression syntax -approximating that value. - -To use this function, your module must declare a dependency on the built-in -`terraform` provider, which contains this function: - -```hcl -terraform { - required_providers { - terraform = { - source = "terraform.io/builtin/terraform" - } - } -} -``` - -The primary use for this function is in conjunction with the `hashicorp/tfe` -provider's resource type -[`tfe_variable`](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/resources/variable), -which expects variable values to be provided in Terraform expression syntax. - -For example, the following concisely declares multiple input variables for -a particular HCP Terraform workspace: - -```hcl -locals { - workspace_vars = { - example1 = "Hello" - example2 = ["A", "B"] - } -} - -resource "tfe_variable" "test" { - for_each = local.workspace_vars - - category = "terraform" - workspace_id = tfe_workspace.example.id - - key = each.key - value = provider::terraform::encode_expr(each.value) - hcl = true -} -``` - -When using this pattern, always set `hcl = true` in the resource declaration -to ensure that HCP Terraform will expect `value` to be given as Terraform -expression syntax. - -We do not recommend using this function in any other situation. - -~> **Warning:** The exact syntax used to encode certain values may change -in future versions of Terraform to follow idiomatic style. Avoid using the -results of this function in any context where such changes might be disruptive -when upgrading Terraform in future. - -## Related Functions - -* [`encode_tfvars`](/terraform/language/functions/terraform-encode_tfvars) - produces expression strings for many different values at once, in `.tfvars` - syntax. diff --git a/website/docs/language/functions/terraform-encode_tfvars.mdx b/website/docs/language/functions/terraform-encode_tfvars.mdx deleted file mode 100644 index 82f0fcb1ae..0000000000 --- a/website/docs/language/functions/terraform-encode_tfvars.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -page_title: provider::terraform::encode_tfvars - Functions - Configuration Language -description: >- - The encode_tfvars function produces a string representation of an object - using the same syntax as for ".tfvars" files used in 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `provider::terraform::encode_tfvars` Function - --> **Note:** This function is supported only in Terraform v1.8 and later. - -`provider::terraform::encode_tfvars` is a rarely-needed function which takes -an object value and produces a string containing a description of that object -using the same syntax as Terraform CLI would expect in a -[`.tfvars` file](/terraform/language/values/variables#variable-definitions-tfvars-files). - -In most cases it's better to pass data between Terraform configurations using -[Data Sources](/terraform/language/data-sources), -instead of writing generated `.tfvars` files to disk. Use this function only as -a last resort. - -To use this function, your module must declare a dependency on the built-in -`terraform` provider, which contains this function: - -```hcl -terraform { - required_providers { - terraform = { - source = "terraform.io/builtin/terraform" - } - } -} -``` - -Elsewhere in your module you can then call this function: - -```hcl -provider::terraform::encode_tfvars({ - example = "Hello!" -}) -``` - -The call above would produce the following result: - -```hcl -example = "Hello!" -``` - -Due to Terraform's requirements for the `.tfvars` format, all of the attributes -of the given object must be valid Terraform variable names, as would be -accepted in an -[input variable declaration](/terraform/language/values/variables#declaring-an-input-variable). - -The `.tfvars` format is specific to Terraform and so we do not recommend using -it as a general serialization format. -Use [`jsonencode`](/terraform/language/functions/jsonencode) or -[`yamlencode`](/terraform/language/functions/yamlencode) instead to produce -formats that are supported by other software. - -~> **Warning:** The exact syntax used to encode certain values may change -in future versions of Terraform to follow idiomatic style. Avoid using the -results of this function in any context where such changes might be disruptive -when upgrading Terraform in future. - -## Related Functions - -* [`decode_tfvars`](/terraform/language/functions/terraform-decode_tfvars) - performs the opposite operation: parsing `.tfvars` content to obtain - the variable values declared inside. -* [`encode_expr`](/terraform/language/functions/terraform-encode_expr) - encodes a single value as a plain expression, without the `.tfvars` - container around it. diff --git a/website/docs/language/functions/textdecodebase64.mdx b/website/docs/language/functions/textdecodebase64.mdx deleted file mode 100644 index 02e2d3a64a..0000000000 --- a/website/docs/language/functions/textdecodebase64.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: textdecodebase64 - Functions - Configuration Language -description: >- - The textdecodebase64 function decodes a string that was previously - Base64-encoded, - - and then interprets the result as characters in a specified character - encoding. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `textdecodebase64` Function - --> **Note:** This function is supported only in Terraform v0.14 and later. - -`textdecodebase64` function decodes a string that was previously Base64-encoded, -and then interprets the result as characters in a specified character encoding. - -Terraform uses the "standard" Base64 alphabet as defined in -[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -The `encoding_name` argument must contain one of the encoding names or aliases -recorded in -[the IANA character encoding registry](https://www.iana.org/assignments/character-sets/character-sets.xhtml). -Terraform supports only a subset of the registered encodings, and the encoding -support may vary between Terraform versions. - -Terraform accepts the encoding name `UTF-8`, which will produce the same result -as [`base64decode`](/terraform/language/functions/base64decode). - -## Examples - -``` -> textdecodebase64("SABlAGwAbABvACAAVwBvAHIAbABkAA==", "UTF-16LE") -Hello World -``` - -## Related Functions - -* [`textencodebase64`](/terraform/language/functions/textencodebase64) performs the opposite operation, - applying target encoding and then Base64 to a string. -* [`base64decode`](/terraform/language/functions/base64decode) is effectively a shorthand for - `textdecodebase64` where the character encoding is fixed as `UTF-8`. diff --git a/website/docs/language/functions/textencodebase64.mdx b/website/docs/language/functions/textencodebase64.mdx deleted file mode 100644 index 9ffdf37cf8..0000000000 --- a/website/docs/language/functions/textencodebase64.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -page_title: textencodebase64 - Functions - Configuration Language -description: >- - The textencodebase64 function encodes the unicode characters in a given string - using a - - specified character encoding, returning the result base64 encoded. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `textencodebase64` Function - --> **Note:** This function is supported only in Terraform v0.14 and later. - -`textencodebase64` encodes the unicode characters in a given string using a -specified character encoding, returning the result base64 encoded because -Terraform language strings are always sequences of unicode characters. - -```hcl -textencodebase64(string, encoding_name) -``` - -Terraform uses the "standard" Base64 alphabet as defined in -[RFC 4648 section 4](https://tools.ietf.org/html/rfc4648#section-4). - -The `encoding_name` argument must contain one of the encoding names or aliases -recorded in -[the IANA character encoding registry](https://www.iana.org/assignments/character-sets/character-sets.xhtml). -Terraform supports only a subset of the registered encodings, and the encoding -support may vary between Terraform versions. In particular Terraform supports -`UTF-16LE`, which is the native character encoding for the Windows API and -therefore sometimes expected by Windows-originated software such as PowerShell. - -Terraform also accepts the encoding name `UTF-8`, which will produce the same -result as [`base64encode`](/terraform/language/functions/base64encode). - -## Examples - -``` -> textencodebase64("Hello World", "UTF-16LE") -SABlAGwAbABvACAAVwBvAHIAbABkAA== -``` - -## Related Functions - -* [`textdecodebase64`](/terraform/language/functions/textdecodebase64) performs the opposite operation, - decoding Base64 data and interpreting it as a particular character encoding. -* [`base64encode`](/terraform/language/functions/base64encode) applies Base64 encoding of the UTF-8 - encoding of a string. -* [`filebase64`](/terraform/language/functions/filebase64) reads a file from the local filesystem - and returns its raw bytes with Base64 encoding, without creating an - intermediate Unicode string. diff --git a/website/docs/language/functions/timeadd.mdx b/website/docs/language/functions/timeadd.mdx deleted file mode 100644 index d882ec075d..0000000000 --- a/website/docs/language/functions/timeadd.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -page_title: timeadd function reference - Functions - Configuration Language -description: |- - The timeadd function adds a duration to a timestamp, returning a new - timestamp. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `timeadd` function reference - -This topic provices reference information about the `timeadd` function. -`timeadd` adds a duration to a timestamp, returning a new timestamp. - -## Introduction - -The Terraform language represents timestamps as strings using [RFC -3339][rfc3339]'s Date and Time format. -`timeadd` requires that the `timestamp` argument is a string conforming to the Date and Time syntax. - -## Syntax - -Use the `timeadd` function with the following syntax: - - -```hcl -timeadd(timestamp, duration) -``` - -- `timestamp` is a string representation of a date in RFC 3339 format. Refer to the - external RFC 3339's [Internet Date/Time Format section][date-time-format] for how to construct a timestamp string. -- `duration` is a string representation of a time difference. This string consists of -sequences of number and unit pairs, such as `"1.5h"` or `"1h30m"`. You may use -the following units: - - - `ns`: nanosecond - - `us` or `µs`: microsecond - - `ms`: millisecond - - `s`: second - - `m`: minute - - `h`: hour - - To indicate a negative duration, make the first number negative, such as `"-2h5m"`. - -The `timeadd` result is a string, also in RFC 3339 format, representing the result -of adding the given duration to the given timestamp. - -## Example use case - -This example adds ten minutes. - -```hcl -> timeadd("2024-08-16T12:45:05Z", "10m") -"2024-08-16T12:55:05Z" -``` - -This example subtracts ten minutes by using a negative duration. - -```hcl -> timeadd("2024-08-16T12:45:05Z", "-10m") -"2024-08-16T12:35:05Z" -``` - -# Related Functions - -* [`timecmp`](/terraform/language/functions/timecmp) determines an ordering for two timestamps. - -[rfc3339]: https://tools.ietf.org/html/rfc3339 -[date-time-format]: https://datatracker.ietf.org/doc/html/rfc3339#section-5.6 diff --git a/website/docs/language/functions/timecmp.mdx b/website/docs/language/functions/timecmp.mdx deleted file mode 100644 index 7c2bda591a..0000000000 --- a/website/docs/language/functions/timecmp.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -page_title: timecmp - Functions - Configuration Language -description: |- - The timecmp function adds a duration to a timestamp, returning a new - timestamp. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `timecmp` Function - -`timecmp` compares two timestamps and returns a number that represents the -ordering of the instants those timestamps represent. - -```hcl -timecmp(timestamp_a, timestamp_b) -``` - -| Condition | Return Value | -|----------------------------------------------------|--------------| -| `timestamp_a` is before `timestamp_b` | `-1` | -| `timestamp_a` is the same instant as `timestamp_b` | `0` | -| `timestamp_a` is after `timestamp_b` | `1` | - -When comparing the timestamps, `timecmp` takes into account the UTC offsets -given in each timestamp. For example, `06:00:00+0200` and `04:00:00Z` are -the same instant after taking into account the `+0200` offset on the first -timestamp. - -In the Terraform language, timestamps are conventionally represented as -strings using [RFC 3339](https://tools.ietf.org/html/rfc3339) -"Date and Time format" syntax. `timecmp` requires the its two arguments to -both be strings conforming to this syntax. - -## Examples - -``` -> timecmp("2017-11-22T00:00:00Z", "2017-11-22T00:00:00Z") -0 -> timecmp("2017-11-22T00:00:00Z", "2017-11-22T01:00:00Z") --1 -> timecmp("2017-11-22T01:00:00Z", "2017-11-22T00:00:00Z") -1 -> timecmp("2017-11-22T01:00:00Z", "2017-11-22T00:00:00-01:00") -0 -``` - -`timecmp` can be particularly useful in defining -[custom condition checks](/terraform/language/expressions/custom-conditions) that -involve a specified timestamp being within a particular range. For example, -the following resource postcondition would raise an error if a TLS certificate -(or other expiring object) expires sooner than 30 days from the time of -the "apply" step: - -```hcl - lifecycle { - postcondition { - condition = timecmp(timestamp(), timeadd(self.expiration_timestamp, "-720h")) < 0 - error_message = "Certificate will expire in less than 30 days." - } - } -``` - -## Related Functions - -* [`timestamp`](/terraform/language/functions/timestamp) returns the current timestamp when it is evaluated - during the apply step. -* [`timeadd`](/terraform/language/functions/timeadd) can perform arithmetic on timestamps by adding or removing a specified duration. diff --git a/website/docs/language/functions/timestamp.mdx b/website/docs/language/functions/timestamp.mdx deleted file mode 100644 index f08d8fea98..0000000000 --- a/website/docs/language/functions/timestamp.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -page_title: timestamp - Functions - Configuration Language -description: |- - The timestamp function returns a string representation of the current date - and time. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `timestamp` Function - -`timestamp` returns a UTC timestamp string in [RFC 3339](https://tools.ietf.org/html/rfc3339) format. - -In the Terraform language, timestamps are conventionally represented as -strings using [RFC 3339](https://tools.ietf.org/html/rfc3339) -"Date and Time format" syntax, and so `timestamp` returns a string -in this format. - -The result of this function will change every second, so using this function -directly with resource attributes will cause a diff to be detected on every -Terraform run. We do not recommend using this function in resource attributes, -but in rare cases it can be used in conjunction with -[the `ignore_changes` lifecycle meta-argument](/terraform/language/meta-arguments/lifecycle#ignore_changes) -to take the timestamp only on initial creation of the resource. For more stable -time handling, see the [Time Provider](https://registry.terraform.io/providers/hashicorp/time). - -Due to the constantly changing return value, the result of this function cannot -be predicted during Terraform's planning phase, and so the timestamp will be -taken only once the plan is being applied. - -## Examples - -``` -> timestamp() -2018-05-13T07:44:12Z -``` - -## Related Functions - -* [`formatdate`](/terraform/language/functions/formatdate) can convert the resulting timestamp to - other date and time formats. -* [`plantimestamp`](/terraform/language/functions/plantimestamp) will return a consistent timestamp - representing the date and time during the plan. diff --git a/website/docs/language/functions/title.mdx b/website/docs/language/functions/title.mdx deleted file mode 100644 index 819ab05fc4..0000000000 --- a/website/docs/language/functions/title.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -page_title: title - Functions - Configuration Language -description: |- - The title function converts the first letter of each word in a given string - to uppercase. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `title` Function - -`title` converts the first letter of each word in the given string to uppercase. - -## Examples - -``` -> title("hello world") -Hello World -``` - -This function uses Unicode's definition of letters and of upper- and lowercase. - -## Related Functions - -* [`upper`](/terraform/language/functions/upper) converts _all_ letters in a string to uppercase. -* [`lower`](/terraform/language/functions/lower) converts all letters in a string to lowercase. diff --git a/website/docs/language/functions/tobool.mdx b/website/docs/language/functions/tobool.mdx deleted file mode 100644 index a6014511c0..0000000000 --- a/website/docs/language/functions/tobool.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -page_title: tobool - Functions - Configuration Language -description: The tobool function converts a value to boolean. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `tobool` Function - -`tobool` converts its argument to a boolean value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -Only boolean values, `null`, and the exact strings `"true"` and `"false"` can be -converted to boolean. All other values will produce an error. - -## Examples - -``` -> tobool(true) -true -> tobool("true") -true -> tobool(null) -null -> tobool("no") -Error: Invalid function argument - -Invalid value for "v" parameter: cannot convert "no" to bool: only the strings -"true" or "false" are allowed. - -> tobool(1) -Error: Invalid function argument - -Invalid value for "v" parameter: cannot convert number to bool. -``` diff --git a/website/docs/language/functions/tolist.mdx b/website/docs/language/functions/tolist.mdx deleted file mode 100644 index a731f85bfb..0000000000 --- a/website/docs/language/functions/tolist.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -page_title: tolist - Functions - Configuration Language -description: The tolist function converts a value to a list. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `tolist` Function - -`tolist` converts its argument to a list value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -Pass a _set_ value to `tolist` to convert it to a list. Since set elements are -not ordered, the resulting list will have an undefined order that will be -consistent within a particular run of Terraform. - -## Examples - -``` -> tolist(["a", "b", "c"]) -[ - "a", - "b", - "c", -] -``` - -Since Terraform's concept of a list requires all of the elements to be of the -same type, mixed-typed elements will be converted to the most general type: - -``` -> tolist(["a", "b", 3]) -[ - "a", - "b", - "3", -] -``` diff --git a/website/docs/language/functions/tomap.mdx b/website/docs/language/functions/tomap.mdx deleted file mode 100644 index db1547d4c1..0000000000 --- a/website/docs/language/functions/tomap.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -page_title: tomap - Functions - Configuration Language -description: The tomap function converts a value to a map. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `tomap` Function - -`tomap` converts its argument to a map value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -## Examples - -``` -> tomap({"a" = 1, "b" = 2}) -{ - "a" = 1 - "b" = 2 -} -``` - -Since Terraform's concept of a map requires all of the elements to be of the -same type, mixed-typed elements will be converted to the most general type: - -``` -> tomap({"a" = "foo", "b" = true}) -{ - "a" = "foo" - "b" = "true" -} -``` diff --git a/website/docs/language/functions/tonumber.mdx b/website/docs/language/functions/tonumber.mdx deleted file mode 100644 index 080b983215..0000000000 --- a/website/docs/language/functions/tonumber.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: tonumber - Functions - Configuration Language -description: The tonumber function converts a value to a number. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `tonumber` Function - -`tonumber` converts its argument to a number value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -Only numbers, `null`, and strings containing decimal representations of numbers can be -converted to number. All other values will produce an error. - -## Examples - -``` -> tonumber(1) -1 -> tonumber("1") -1 -> tonumber(null) -null -> tonumber("no") -Error: Invalid function argument - -Invalid value for "v" parameter: cannot convert "no" to number: string must be -a decimal representation of a number. -``` diff --git a/website/docs/language/functions/toset.mdx b/website/docs/language/functions/toset.mdx deleted file mode 100644 index 52ad7038dd..0000000000 --- a/website/docs/language/functions/toset.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -page_title: toset - Functions - Configuration Language -description: The toset function converts a value to a set. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `toset` Function - -`toset` converts its argument to a set value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -Pass a _list_ value to `toset` to convert it to a set, which will remove any -duplicate elements and discard the ordering of the elements. - -## Examples - -``` -> toset(["a", "b", "c"]) -[ - "a", - "b", - "c", -] -``` - -Since Terraform's concept of a set requires all of the elements to be of the -same type, mixed-typed elements will be converted to the most general type: - -``` -> toset(["a", "b", 3]) -[ - "3", - "a", - "b", -] -``` - -Set collections are unordered and cannot contain duplicate values, so the -ordering of the argument elements is lost and any duplicate values are -coalesced: - -``` -> toset(["c", "b", "b"]) -[ - "b", - "c", -] -``` diff --git a/website/docs/language/functions/tostring.mdx b/website/docs/language/functions/tostring.mdx deleted file mode 100644 index 2d6722efa7..0000000000 --- a/website/docs/language/functions/tostring.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -page_title: tostring - Functions - Configuration Language -description: The tostring function converts a value to a string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `tostring` Function - -`tostring` converts its argument to a string value. - -Explicit type conversions are rarely necessary in Terraform because it will -convert types automatically where required. Use the explicit type conversion -functions only to normalize types returned in module outputs. - -Only the primitive types (string, number, and bool) and `null` can be converted to string. -`tostring(null)` produces a `null` value of type `string`. All other values produce an error. - -## Examples - -``` -> tostring("hello") -"hello" -> tostring(1) -"1" -> tostring(true) -"true" -> tostring(null) -tostring(null) -> tostring([]) -Error: Invalid function argument - -Invalid value for "v" parameter: cannot convert tuple to string. -``` diff --git a/website/docs/language/functions/transpose.mdx b/website/docs/language/functions/transpose.mdx deleted file mode 100644 index f4ff0f392f..0000000000 --- a/website/docs/language/functions/transpose.mdx +++ /dev/null @@ -1,35 +0,0 @@ ---- -page_title: transpose - Functions - Configuration Language -description: |- - The transpose function takes a map of lists of strings and swaps the keys - and values. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `transpose` Function - -`transpose` takes a map of lists of strings and swaps the keys and values -to produce a new map of lists of strings. - -## Examples - -``` -> transpose({"a" = ["1", "2"], "b" = ["2", "3"]}) -{ - "1" = [ - "a", - ], - "2" = [ - "a", - "b", - ], - "3" = [ - "b", - ], -} -``` diff --git a/website/docs/language/functions/trim.mdx b/website/docs/language/functions/trim.mdx deleted file mode 100644 index 6ca23df5a3..0000000000 --- a/website/docs/language/functions/trim.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -page_title: trim - Functions - Configuration Language -description: >- - The trim function removes the specified set of characters from the start and - end of - - a given string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `trim` Function - -`trim` removes the specified set of characters from the start and end of the given -string. - -```hcl -trim(string, str_character_set) -``` - -Every occurrence of a character in the second argument is removed from the start -and end of the string specified in the first argument. - -## Examples - -``` -> trim("?!hello?!", "!?") -"hello" - -> trim("foobar", "far") -"oob" - -> trim(" hello! world.! ", "! ") -"hello! world." -``` - -## Related Functions - -* [`trimprefix`](/terraform/language/functions/trimprefix) removes a word from the start of a string. -* [`trimsuffix`](/terraform/language/functions/trimsuffix) removes a word from the end of a string. -* [`trimspace`](/terraform/language/functions/trimspace) removes all types of whitespace from - both the start and the end of a string. diff --git a/website/docs/language/functions/trimprefix.mdx b/website/docs/language/functions/trimprefix.mdx deleted file mode 100644 index 01f39756c8..0000000000 --- a/website/docs/language/functions/trimprefix.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -page_title: trimprefix - Functions - Configuration Language -description: |- - The trimprefix function removes the specified prefix from the start of a - given string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `trimprefix` Function - -`trimprefix` removes the specified prefix from the start of the given string, but only once. If the string does not begin with the prefix, the original string is returned unchanged. - -## Examples - -``` -> trimprefix("helloworld", "hello") -world -``` - -``` -> trimprefix("helloworld", "cat") -helloworld -``` - -``` -> trimprefix("--hello", "-") --hello -``` - -## Related Functions - -* [`trim`](/terraform/language/functions/trim) removes characters at the start and end of a string. -* [`trimsuffix`](/terraform/language/functions/trimsuffix) removes a word from the end of a string. -* [`trimspace`](/terraform/language/functions/trimspace) removes all types of whitespace from - both the start and the end of a string. diff --git a/website/docs/language/functions/trimspace.mdx b/website/docs/language/functions/trimspace.mdx deleted file mode 100644 index 2c78a9219e..0000000000 --- a/website/docs/language/functions/trimspace.mdx +++ /dev/null @@ -1,33 +0,0 @@ ---- -page_title: trimspace - Functions - Configuration Language -description: |- - The trimspace function removes space characters from the start and end of - a given string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `trimspace` Function - -`trimspace` removes any space characters from the start and end of the given -string. - -This function follows the Unicode definition of "space", which includes -regular spaces, tabs, newline characters, and various other space-like -characters. - -## Examples - -``` -> trimspace(" hello\n\n") -hello -``` - -## Related Functions - -* [`chomp`](/terraform/language/functions/chomp) removes just line ending characters from the _end_ of - a string. diff --git a/website/docs/language/functions/trimsuffix.mdx b/website/docs/language/functions/trimsuffix.mdx deleted file mode 100644 index c5fb78f8fc..0000000000 --- a/website/docs/language/functions/trimsuffix.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -page_title: trimsuffix - Functions - Configuration Language -description: |- - The trimsuffix function removes the specified suffix from the end of a - given string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `trimsuffix` Function - -`trimsuffix` removes the specified suffix from the end of the given string, but only once, even if the suffix appears multiple times. If the suffix does not appear at the very end of the string, the original string is returned unchanged. - -## Examples - -``` -> trimsuffix("helloworld", "world") -hello -``` - -``` -> trimsuffix("helloworld", "cat") -helloworld -``` - -``` -> trimsuffix("hello--", "-") -hello- -``` - -## Related Functions - -* [`trim`](/terraform/language/functions/trim) removes characters at the start and end of a string. -* [`trimprefix`](/terraform/language/functions/trimprefix) removes a word from the start of a string. -* [`trimspace`](/terraform/language/functions/trimspace) removes all types of whitespace from - both the start and the end of a string. diff --git a/website/docs/language/functions/try.mdx b/website/docs/language/functions/try.mdx deleted file mode 100644 index 7b38856712..0000000000 --- a/website/docs/language/functions/try.mdx +++ /dev/null @@ -1,117 +0,0 @@ ---- -page_title: try - Functions - Configuration Language -description: |- - The try function tries to evaluate a sequence of expressions given as - arguments and returns the result of the first one that does not produce - any errors. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `try` Function - -`try` evaluates all of its argument expressions in turn and returns the result -of the first one that does not produce any errors. - -This is a special function that is able to catch errors produced when evaluating -its arguments, which is particularly useful when working with complex data -structures whose shape is not well-known at implementation time. - -For example, if some data is retrieved from an external system in JSON or YAML -format and then decoded, the result may have attributes that are not guaranteed -to be set. We can use `try` to produce a normalized data structure which has -a predictable type that can therefore be used more conveniently elsewhere in -the configuration: - -```hcl -locals { - raw_value = yamldecode(file("${path.module}/example.yaml")) - normalized_value = { - name = tostring(try(local.raw_value.name, null)) - groups = try(local.raw_value.groups, []) - } -} -``` - -With the above local value expressions, configuration elsewhere in the module -can refer to `local.normalized_value` attributes without the need to repeatedly -check for and handle absent attributes that would otherwise produce errors. - -We can also use `try` to deal with situations where a value might be provided -in two different forms, allowing us to normalize to the most general form: - -```hcl -variable "example" { - type = any -} - -locals { - example = try( - [tostring(var.example)], - tolist(var.example), - ) -} -``` - -The above permits `var.example` to be either a list or a single string. If it's -a single string then it'll be normalized to a single-element list containing -that string, again allowing expressions elsewhere in the configuration to just -assume that `local.example` is always a list. - -This second example contains two expressions that can both potentially fail. -For example, if `var.example` were set to `{}` then it could be converted to -neither a string nor a list. If `try` exhausts all of the given expressions -without any succeeding, it will return an error describing all of the problems -it encountered. - -We strongly suggest using `try` only in special local values whose expressions -perform normalization, so that the error handling is confined to a single -location in the module and the rest of the module can just use straightforward -references to the normalized structure and thus be more readable for future -maintainers. - -The `try` function can only catch and handle _dynamic_ errors resulting from -access to data that isn't known until runtime. It will not catch errors -relating to expressions that can be proven to be invalid for any input, such -as a malformed resource reference. - -~> **Warning:** The `try` function is intended only for concise testing of the -presence of and types of object attributes. Although it can technically accept -any sort of expression, we recommend using it only with simple attribute -references and type conversion functions as shown in the examples above. -Overuse of `try` to suppress errors will lead to a configuration that is hard -to understand and maintain. - -## Examples - -``` -> local.foo -{ - "bar" = "baz" -} -> try(local.foo.bar, "fallback") -baz -> try(local.foo.boop, "fallback") -fallback -``` - -The `try` function will _not_ catch errors relating to constructs that are -provably invalid even before dynamic expression evaluation, such as a malformed -reference or a reference to a top-level object that has not been declared: - -``` -> try(local.nonexist, "fallback") - -Error: Reference to undeclared local value - -A local value with the name "nonexist" has not been declared. -``` - -## Related Functions - -* [`can`](/terraform/language/functions/can), which tries evaluating an expression and returns a - boolean value indicating whether it succeeded. diff --git a/website/docs/language/functions/type.mdx b/website/docs/language/functions/type.mdx deleted file mode 100644 index 3f7e1600f7..0000000000 --- a/website/docs/language/functions/type.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -page_title: type - Functions - Configuration Language -description: 'The type function returns the type of a given value. ' ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `type` Function - --> **Note:** This function is available only in Terraform 1.0 and later. - -`type` returns the type of a given value. - -Sometimes a Terraform configuration can result in confusing errors regarding -inconsistent types. This function displays terraform's evaluation of a given -value's type, which is useful in understanding this error message. - -This is a special function which is only available in the `terraform console` -command. It can only be used to examine the type of a given value, and should -not be used in more complex expressions. - -## Examples - -Here we have a conditional `output` which prints either the value of `var.list` or a local named `default_list`: - -```hcl -variable "list" { - default = [] -} - -locals { - default_list = [ - { - foo = "bar" - map = { bleep = "bloop" } - }, - { - beep = "boop" - }, - ] -} - -output "list" { - value = var.list != [] ? var.list : local.default_list -} -``` - -Applying this configuration results in the following error: - -``` -Error: Inconsistent conditional result types - - on main.tf line 18, in output "list": - 18: value = var.list != [] ? var.list : local.default_list - |---------------- - | local.default_list is tuple with 2 elements - | var.list is empty tuple - -The true and false result expressions must have consistent types. The given -expressions are tuple and tuple, respectively. -``` - -While this error message does include some type information, it can be helpful -to inspect the exact type that Terraform has determined for each given input. -Examining both `var.list` and `local.default_list` using the `type` function -provides more context for the error message: - -``` -> type(var.list) -tuple -> type(local.default_list) -tuple([ - object({ - foo: string, - map: object({ - bleep: string, - }), - }), - object({ - beep: string, - }), -]) -``` diff --git a/website/docs/language/functions/upper.mdx b/website/docs/language/functions/upper.mdx deleted file mode 100644 index bf24ea039a..0000000000 --- a/website/docs/language/functions/upper.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -page_title: upper - Functions - Configuration Language -description: >- - The upper function converts all cased letters in the given string to - uppercase. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `upper` Function - -`upper` converts all cased letters in the given string to uppercase. - -## Examples - -``` -> upper("hello") -HELLO -> upper("алло!") -АЛЛО! -``` - -This function uses Unicode's definition of letters and of upper- and lowercase. - -## Related Functions - -* [`lower`](/terraform/language/functions/lower) converts letters in a string to _lowercase_. -* [`title`](/terraform/language/functions/title) converts the first letter of each word in a string to uppercase. diff --git a/website/docs/language/functions/urlencode.mdx b/website/docs/language/functions/urlencode.mdx deleted file mode 100644 index fb0aef17f1..0000000000 --- a/website/docs/language/functions/urlencode.mdx +++ /dev/null @@ -1,37 +0,0 @@ ---- -page_title: urlencode - Functions - Configuration Language -description: The urlencode function applies URL encoding to a given string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `urlencode` Function - -`urlencode` applies URL encoding to a given string. - -This function identifies characters in the given string that would have a -special meaning when included as a query string argument in a URL and -escapes them using -[RFC 3986 "percent encoding"](https://tools.ietf.org/html/rfc3986#section-2.1). - -The exact set of characters escaped may change over time, but the result -is guaranteed to be interpolatable into a query string argument without -inadvertently introducing additional delimiters. - -If the given string contains non-ASCII characters, these are first encoded as -UTF-8 and then percent encoding is applied separately to each UTF-8 byte. - -## Examples - -``` -> urlencode("Hello World!") -Hello+World%21 -> urlencode("☃") -%E2%98%83 -> "http://example.com/search?q=${urlencode("terraform urlencode")}" -http://example.com/search?q=terraform+urlencode -``` diff --git a/website/docs/language/functions/uuid.mdx b/website/docs/language/functions/uuid.mdx deleted file mode 100644 index 179ec7714d..0000000000 --- a/website/docs/language/functions/uuid.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -page_title: uuid - Functions - Configuration Language -description: The uuid function generates a unique id. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `uuid` Function - -`uuid` generates UUID-format strings using random bytes. - -The function generates a well-understood string representation of a 128-bit value, but the output is not RFC-compliant. - -This function produces a new value each time it is called, and so using it -directly in resource arguments will result in spurious diffs. We do not -recommend using the `uuid` function in resource configurations, but it can -be used with care in conjunction with -[the `ignore_changes` lifecycle meta-argument](/terraform/language/meta-arguments/lifecycle#ignore_changes). - -In most cases we recommend using [the `random` provider](https://registry.terraform.io/providers/hashicorp/random/latest/docs) -instead, since it allows the one-time generation of random values that are -then retained in the Terraform [state](/terraform/language/state) for use by -future operations. In particular, -[`random_id`](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) can generate results with -equivalent randomness to the `uuid` function. - -## Examples - -``` -> uuid() -b5ee72a3-54dd-c4b8-551c-4bdc0204cedb -``` - -## Related Functions - -* [`uuidv5`](/terraform/language/functions/uuidv5), which generates name-based UUIDs. diff --git a/website/docs/language/functions/uuidv5.mdx b/website/docs/language/functions/uuidv5.mdx deleted file mode 100644 index 02e87a8fd5..0000000000 --- a/website/docs/language/functions/uuidv5.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -page_title: uuidv5 - Functions - Configuration Language -description: >- - The uuidv5 function generates a uuid v5 string representation of the value in - the specified namespace. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `uuidv5` Function - -`uuidv5` generates a _name-based_ UUID, as described in -[RFC 4122 section 4.3](https://tools.ietf.org/html/rfc4122#section-4.3), -also known as a "version 5" UUID. - -``` -uuidv5(namespace, name) -``` - -Unlike the pseudo-random UUIDs generated by -[`uuid`](/terraform/language/functions/uuid), name-based UUIDs derive from namespace and an name, -producing the same UUID value every time if the namespace and name are -unchanged. - -Name-based UUID namespaces are themselves UUIDs, but for readability this -function accepts some keywords as aliases for the namespaces that were -assigned by RFC 4122: - -| Keyword | Namespace ID | Name format | -| -------- | -------------------------------------- | ---------------------------------------------------------------------------- | -| `"dns"` | `6ba7b810-9dad-11d1-80b4-00c04fd430c8` | A fully-qualified DNS domain name. | -| `"url"` | `6ba7b811-9dad-11d1-80b4-00c04fd430c8` | Any valid URL as defined in [RFC 3986](https://tools.ietf.org/html/rfc3986). | -| `"oid"` | `6ba7b812-9dad-11d1-80b4-00c04fd430c8` | An [ISO/IEC object identifier](https://oidref.com/) | -| `"x500"` | `6ba7b814-9dad-11d1-80b4-00c04fd430c8` | [X.500 Distinguished Name](https://tools.ietf.org/html/rfc1779) | - -To use any other namespace not included in the above table, pass its assigned -namespace ID directly in the first argument in the usual UUID string format. - -## Examples - -Use the namespace keywords where possible, to make the intent more obvious to -a future reader: - -``` -> uuidv5("dns", "www.terraform.io") -a5008fae-b28c-5ba5-96cd-82b4c53552d6 - -> uuidv5("url", "https://www.terraform.io/") -9db6f67c-dd95-5ea0-aa5b-e70e5c5f7cf5 - -> uuidv5("oid", "1.3.6.1.4") -af9d40a5-7a36-5c07-b23a-851cd99fbfa5 - -> uuidv5("x500", "CN=Example,C=GB") -84e09961-4aa4-57f8-95b7-03edb1073253 -``` - -The namespace keywords treated as equivalent to their corresponding namespace -UUIDs, and in some special cases it may be more appropriate to use the -UUID form: - -``` -> uuidv5("6ba7b810-9dad-11d1-80b4-00c04fd430c8", "www.terraform.io") -a5008fae-b28c-5ba5-96cd-82b4c53552d6 -``` - -If you wish to use a namespace defined outside of RFC 4122, using the namespace -UUID is required because no corresponding keyword is available: - -``` -> uuidv5("743ac3c0-3bf7-4a5b-9e6c-59360447c757", "LIBS:diskfont.library") -ede1a974-df7e-5f17-84b9-76208818b2c8 -``` - -When using raw UUID namespaces, consider including a comment alongside the -expression that indicates which namespace this represents in a -human-significant manner, such as by reference to the standard that -defined it. - -## Related Functions - -* [`uuid`](/terraform/language/functions/uuid), which generates pseudorandom UUIDs. diff --git a/website/docs/language/functions/values.mdx b/website/docs/language/functions/values.mdx deleted file mode 100644 index 64065ae766..0000000000 --- a/website/docs/language/functions/values.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -page_title: values - Functions - Configuration Language -description: The values function returns a list of the element values in a given map. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `values` Function - -`values` takes a map and returns a list containing the values of the elements -in that map. - -The values are returned in lexicographical order by their corresponding _keys_, -so the values will be returned in the same order as their keys would be -returned from [`keys`](/terraform/language/functions/keys). - -## Examples - -``` -> values({a=3, c=2, d=1}) -[ - 3, - 2, - 1, -] -``` - -## Related Functions - -* [`keys`](/terraform/language/functions/keys) returns a list of the _keys_ from a map. diff --git a/website/docs/language/functions/yamldecode.mdx b/website/docs/language/functions/yamldecode.mdx deleted file mode 100644 index 662bd74591..0000000000 --- a/website/docs/language/functions/yamldecode.mdx +++ /dev/null @@ -1,105 +0,0 @@ ---- -page_title: yamldecode - Functions - Configuration Language -description: |- - The yamldecode function decodes a YAML string into a representation of its - value. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `yamldecode` Function - -`yamldecode` parses a string as a subset of YAML, and produces a representation -of its value. - -This function supports a subset of [YAML 1.2](https://yaml.org/spec/1.2/spec.html), -as described below. - -This function maps YAML values to -[Terraform language values](/terraform/language/expressions/types) -in the following way: - -| YAML type | Terraform type | -| ------------- | ------------------------------------------------------------------ | -| `!!str` | `string` | -| `!!float` | `number` | -| `!!int` | `number` | -| `!!bool` | `bool` | -| `!!map` | `object(...)` with attribute types determined per this table | -| `!!seq` | `tuple(...)` with element types determined per this table | -| `!!null` | The Terraform language `null` value | -| `!!timestamp` | `string` in [RFC 3339](https://tools.ietf.org/html/rfc3339) format | -| `!!binary` | `string` containing base64-encoded representation | - -The Terraform language automatic type conversion rules mean that you don't -usually need to worry about exactly what type is produced for a given value, -and can just use the result in an intuitive way. - -Note though that the mapping above is ambiguous -- several different source -types map to the same target type -- and so round-tripping through `yamldecode` -and then `yamlencode` cannot produce an identical result. - -YAML is a complex language and it supports a number of possibilities that the -Terraform language's type system cannot represent. Therefore this YAML decoder -supports only a subset of YAML 1.2, with restrictions including the following: - -- Although aliases to earlier anchors are supported, cyclic data structures - (where a reference to a collection appears inside that collection) are not. - If `yamldecode` detects such a structure then it will return an error. - -- Only the type tags shown in the above table (or equivalent alternative - representations of those same tags) are supported. Any other tags will - result in an error. - -- Only one YAML document is permitted. If multiple documents are present in - the given string then this function will return an error. - -## Examples - -``` -> yamldecode("hello: world") -{ - "hello" = "world" -} - -> yamldecode("true") -true - -> yamldecode("{a: &foo [1, 2, 3], b: *foo}") -{ - "a" = [ - 1, - 2, - 3, - ] - "b" = [ - 1, - 2, - 3, - ] -} - -> yamldecode("{a: &foo [1, *foo, 3]}") - -Error: Error in function call - -Call to function "yamldecode" failed: cannot refer to anchor "foo" from inside -its own definition. - -> yamldecode("{a: !not-supported foo}") - -Error: Error in function call - -Call to function "yamldecode" failed: unsupported tag "!not-supported". -``` - -## Related Functions - -- [`jsondecode`](/terraform/language/functions/jsondecode) is a similar operation using JSON instead - of YAML. -- [`yamlencode`](/terraform/language/functions/yamlencode) performs the opposite operation, _encoding_ - a value as YAML. diff --git a/website/docs/language/functions/yamlencode.mdx b/website/docs/language/functions/yamlencode.mdx deleted file mode 100644 index ff6757c2ff..0000000000 --- a/website/docs/language/functions/yamlencode.mdx +++ /dev/null @@ -1,83 +0,0 @@ ---- -page_title: yamlencode - Functions - Configuration Language -description: The yamlencode function encodes a given value as a YAML string. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `yamlencode` Function - -`yamlencode` encodes a given value to a string using -[YAML 1.2](https://yaml.org/spec/1.2/spec.html) block syntax. - -This function maps -[Terraform language values](/terraform/language/expressions/types) -to YAML tags in the following way: - -| Terraform type | YAML type | -| -------------- | -------------------- | -| `string` | `!!str` | -| `number` | `!!float` or `!!int` | -| `bool` | `!!bool` | -| `list(...)` | `!!seq` | -| `set(...)` | `!!seq` | -| `tuple(...)` | `!!seq` | -| `map(...)` | `!!map` | -| `object(...)` | `!!map` | -| Null value | `!!null` | - -`yamlencode` uses the implied syntaxes for all of the above types, so it does -not generate explicit YAML tags. - -Because the YAML format cannot fully represent all of the Terraform language -types, passing the `yamlencode` result to `yamldecode` will not produce an -identical value, but the Terraform language automatic type conversion rules -mean that this is rarely a problem in practice. - -YAML is a superset of JSON, and so where possible we recommend generating -JSON using [`jsonencode`](/terraform/language/functions/jsonencode) instead, even if -a remote system supports YAML. JSON syntax is equivalent to flow-style YAML -and Terraform can present detailed structural change information for JSON -values in plans, whereas Terraform will treat block-style YAML just as a normal -multi-line string. However, generating YAML may improve readability if the -resulting value will be directly read or modified in the remote system by -humans. - -## Examples - -``` -> yamlencode({"a":"b", "c":"d"}) -"a": "b" -"c": "d" - -> yamlencode({"foo":[1, 2, 3], "bar": "baz"}) -"bar": "baz" -"foo": -- 1 -- 2 -- 3 - -> yamlencode({"foo":[1, {"a":"b","c":"d"}, 3], "bar": "baz"}) -"bar": "baz" -"foo": -- 1 -- "a": "b" - "c": "d" -- 3 -``` - -`yamlencode` always uses YAML's "block style" for mappings and sequences, unless -the mapping or sequence is empty. To generate flow-style YAML, use -[`jsonencode`](/terraform/language/functions/jsonencode) instead: YAML flow-style is a superset -of JSON syntax. - -## Related Functions - -- [`jsonencode`](/terraform/language/functions/jsonencode) is a similar operation using JSON instead - of YAML. -- [`yamldecode`](/terraform/language/functions/yamldecode) performs the opposite operation, _decoding_ - a YAML string to obtain its represented value. diff --git a/website/docs/language/functions/zipmap.mdx b/website/docs/language/functions/zipmap.mdx deleted file mode 100644 index 5d0bb03af2..0000000000 --- a/website/docs/language/functions/zipmap.mdx +++ /dev/null @@ -1,39 +0,0 @@ ---- -page_title: zipmap - Functions - Configuration Language -description: |- - The zipmap function constructs a map from a list of keys and a corresponding - list of values. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `zipmap` Function - -`zipmap` constructs a map from a list of keys and a corresponding list of -values. - -```hcl -zipmap(keyslist, valueslist) -``` - -Both `keyslist` and `valueslist` must be of the same length. `keyslist` must -be a list of strings, while `valueslist` can be a list of any type. - -Each pair of elements with the same index from the two lists will be used -as the key and value of an element in the resulting map. If the same value -appears multiple times in `keyslist` then the value with the highest index -is used in the resulting map. - -## Examples - -``` -> zipmap(["a", "b"], [1, 2]) -{ - "a" = 1 - "b" = 2 -} -``` diff --git a/website/docs/language/import/generating-configuration.mdx b/website/docs/language/import/generating-configuration.mdx deleted file mode 100644 index 5761d8fdd9..0000000000 --- a/website/docs/language/import/generating-configuration.mdx +++ /dev/null @@ -1,151 +0,0 @@ ---- -page_title: Import - Generating Configuration -description: >- - Generate configuration and manage existing resources with Terraform using configuration-driven import. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Generating configuration - -~> **Experimental:** Configuration generation is available in Terraform v1.5 as an experimental feature. Later minor versions may contain changes to the formatting of generated configuration and behavior of the `terraform plan` command using the `-generate-config-out` flag. - -Terraform can generate code for the resources you define in [`import` blocks](/terraform/language/import) that do not already exist in your configuration. Terraform produces HCL to act as a template that contains Terraform's best guess at the appropriate value for each resource argument. - -Starting with Terraform's generated HCL, we recommend iterating to find your ideal configuration by removing some attributes, adjusting the value of others, and rearranging `resource` blocks into files and modules as appropriate. - -To generate configuration, run `terraform plan` with the `-generate-config-out` flag and supply a new file path. Do not supply a path to an existing file, or Terraform throws an error. - -```shell -$ terraform plan -generate-config-out="generated_resources.tf" -``` - -If any resources targeted by an `import` block do not exist in your configuration, Terraform then generates and writes configuration for those resources in `generated_resources.tf`. - -## Workflow - -The workflow for generating configuration is similar to the [`import` block workflow](/terraform/language/import#plan-and-apply-an-import), with the extra step of generating configuration during the planning stage. You can then review and modify the generated configuration before applying. - -### 1. Add the `import` block - -Add an `import` block to your configuration. This `import` block can be in a separate file (e.g., `import.tf`) or an existing configuration file. - -```hcl -import { - to = aws_iot_thing.bar - id = "foo" -} -``` - -The import block's `to` argument points to the address a `resource` will have in your state file. If a resource address in your state matches an `import` block's `to` argument, Terraform attempts to import into that resource. In future planning, Terraform knows it doesn't need to generate configuration for resources that already exist in your state. - -The import block's `id` argument uses that resource's [import ID](/terraform/language/import#import-id). - -If your configuration does not contain other resources for your selected provider, you must add a `provider` block to inform Terraform which provider it should use to generate configuration. Otherwise, Terraform displays an error if it can not determine which provider to use. -If you add a new `provider` block to your configuration, you must run `terraform init` again. - -### 2. Plan and generate configuration - -To instruct Terraform to generate configuration for the `import` blocks you defined, run `terraform plan` with the `-generate-config-out=` flag and a new file path. Terraform displays its plan for importing your resource and the file where Terraform generated configuration based on this plan. - -```shell -$ terraform plan -generate-config-out=generated.tf - -aws_iot_thing.bar: Preparing import... [id=foo] -aws_iot_thing.bar: Refreshing state... [id=foo] - -Terraform will perform the following actions: - - # aws_iot_thing.bar will be imported - # (config will be generated) - resource "aws_iot_thing" "bar" { - arn = "arn:aws:iot:eu-west-1:1234567890:thing/foo" - attributes = {} - default_client_id = "foo" - id = "foo" - name = "foo" - version = 1 - } - -Plan: 1 to import, 0 to add, 0 to change, 0 to destroy. - -╷ -│ Warning: Config generation is experimental -│ -│ Generating configuration during import is currently experimental, and the generated configuration format may change in future versions. -╵ - -────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - -Terraform has generated configuration and written it to generated.tf. Please review the configuration and edit it as necessary before adding it to version control. -``` - -### 3. Review generated configuration - -The example above instructs Terraform to generate configuration in a file named `generated.tf`. The below code is an example of a `generated.tf` file. - -```hcl -resource "aws_iot_thing" "bar" { - name = "foo" -} -``` - -Review the generated configuration and update it as needed. You may wish to move the generated configuration to another file, add or remove resource arguments, or update it to reference input variables or other resources in your configuration. - -### 4. Apply - -Run `terraform apply` to import your infrastructure. - -```shell -$ terraform apply - -aws_iot_thing.bar: Preparing import... [id=foo] -aws_iot_thing.bar: Refreshing state... [id=foo] - -Terraform will perform the following actions: - - # aws_iot_thing.bar will be imported - resource "aws_iot_thing" "bar" { - arn = "arn:aws:iot:eu-west-1:1234567890:thing/foo" - attributes = {} - default_client_id = "foo" - id = "foo" - name = "foo" - version = 1 - } - -Plan: 1 to import, 0 to add, 0 to change, 0 to destroy. -aws_iot_thing.bar: Importing... [id=foo] -aws_iot_thing.bar: Import complete [id=foo] - -Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed. -``` - -Commit your new resource configuration to your version control system. - -## Limitations - -### Conflicting resource arguments - -Terraform generates configuration for importable resources during a plan by requesting values for resource attributes from the provider. For certain resources with complex schemas, Terraform may not be able to construct a valid configuration from these values. - -Terraform will display an error like the one below if it does not receive values for resource attributes while generating configuration. - -```shell -$ terraform plan -generate-config-out="generated.tf" -╷ -│ Error: Conflicting configuration arguments -│ -│ with aws_instance.ubuntu, -│ on g.tf line 20, in resource "aws_instance" "ubuntu": -│ 20: ipv6_address_count = 0 -│ -│ "ipv6_address_count": conflicts with ipv6_addresses -╵ -``` - -In the example above, Terraform still generates configuration and writes it to `generated.tf`. This error stems from a conflict between the `ipv6_address_count` and `ipv6_addresses` arguments. The resource supports both of these arguments, but you must choose only one when configuring the resource. You could fix the error by removing one of these two arguments, then running `terraform plan` again to check that there are no further issues. diff --git a/website/docs/language/import/index.mdx b/website/docs/language/import/index.mdx deleted file mode 100644 index 48eaf146e5..0000000000 --- a/website/docs/language/import/index.mdx +++ /dev/null @@ -1,217 +0,0 @@ ---- -page_title: Import - Configuration Language -description: >- - Import and manage existing resources with Terraform using configuration-driven import. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 - --> **Note:** Import blocks are only available in Terraform v1.5.0 and later. - -~> **Experimental:** While we do not expect to make backwards-incompatible changes to syntax, the `-generate-config-out` flag and how Terraform processes imports during the plan stage and generates configuration may change in future releases. - -Use the `import` block to import existing infrastructure resources into Terraform, bringing them under Terraform's management. Unlike the `terraform import` command, configuration-driven import using `import` blocks is predictable, works with CICD pipelines, and lets you preview an import operation before modifying state. - -Once imported, Terraform tracks the resource in your state file. You can then manage the imported resource like any other, updating its attributes and destroying it as part of a standard resource lifecycle. - -The `import` block records that Terraform imported the resource and did not create it. After importing, you can optionally remove import blocks from your configuration or leave them as a record of the resource's origin. - -## Syntax - -You can add an `import` block to any Terraform configuration file. A common pattern is to create an `imports.tf` file, or to place each `import` block beside the `resource` block it imports into. - -```hcl -import { - to = aws_instance.example - id = "i-abcd1234" -} - -resource "aws_instance" "example" { - name = "hashi" - # (other resource arguments...) -} -``` - -The above `import` block defines an import of the AWS instance with the ID "i-abcd1234" into the `aws_instance.example` resource in the root module. - -The `import` block has the following arguments: - - `to` - The instance address this resource will have in your state file. - - `id` - A string with the [import ID](#import-id) of the resource, or an expression that evaluates to a string. This argument is mutually exclusive with `identity`. - - `identity` - A resource identity object that uniquely identifies a resource. It is mutually exclusive with `id`. - - `provider` (optional) - An optional custom resource provider, see [The Resource provider Meta-Argument](/terraform/language/meta-arguments/resource-provider) for details. - -If you do not set the `provider` argument, Terraform attempts to import from the default provider. - -### Import ID - -The import block's `id` argument can be a literal string of your resource's import ID, or an expression that evaluates to a string, such as `var.instance_id`. Terraform needs this import ID to locate the resource you want to import. - -The import ID must be known at plan time for planning to succeed. If the value of `id` is only known after apply, `terraform plan` will fail with an error. - -The identifier you use for a resource's import ID is resource-specific. You can find the required ID in the [provider documentation](https://registry.terraform.io/browse/providers) for the resource you wish to import. - -Instead of the `id` argument you can also use the `identity` argument, which represents a resource's identity. The `identity` argument is an object of key-value pairs that uniquely identify a resource. The keys and values are specific to the resource type and provider. - -### Import multiple instances with `for_each` - -Multiple resource instances can be imported via a single `import` block using the `for_each` argument. The `for_each` argument accepts a collection to iterate over, and results in an `each` iterator in the same manner as it does for [`dynamic` blocks](/terraform/language/expressions/dynamic-blocks). The `for_each` argument must be entirely known for the import plan to succeed, and `for_each` cannot be used when [generating configuration](/terraform/language/import/generating-configuration). - -The resulting `each.key` and `each.value` values can be used both in the `id` expression, and within index expressions in the `to` argument. This allows the mapping of multiple instances to expanded resources: - -```hcl -locals { - buckets = { - "staging" = "bucket1" - "uat" = "bucket2" - "prod" = "bucket3" - } -} - -import { - for_each = local.buckets - to = aws_s3_bucket.this[each.key] - id = each.value -} - -resource "aws_s3_bucket" "this" { - for_each = local.buckets -} -``` - -The same process can also be used to expand the imports across multiple module instances: - -```hcl -locals { - buckets = [ - { - group = "one" - key = "bucket1" - id = "one_1" - }, - { - group = "one" - key = "bucket2" - id = "one_2" - }, - { - group = "two" - key = "bucket1" - id = "two_1" - }, - { - group = "two" - key = "bucket2" - id = "two_2" - }, - ] -} - -import { - for_each = local.buckets - id = each.value.id - to = module.group[each.value.group].aws_s3_bucket.this[each.value.key] -} -``` - - -## Plan and apply an import - -Terraform processes the `import` block during the plan stage. Once a plan is approved, Terraform imports the resource into its state during the subsequent apply stage. - -To import a resource using `import` blocks, you must: -1. Define an `import` block for the resource(s). -1. Add a corresponding `resource` block to your configuration , or [generate configuration](/terraform/language/import/generating-configuration) for that resource. -1. Run `terraform plan` to review how Terraform will import the resource(s). -1. Apply the configuration to import the resources and update your Terraform state. - -> **Hands-on:** Try the [State Import](/terraform/tutorials/state/state-import?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -The `import` block is [_idempotent_](https://en.wikipedia.org/wiki/Idempotence), meaning that applying an import action and running another plan will not generate another import action as long as that resource remains in your state. - -Terraform only needs to import a given resource once. Attempting to import a resource into the same address again is a harmless no-op. You can remove `import` blocks after completing the import or safely leave them in your configuration as a record of the resource's origin for future module maintainers. For more information on maintaining configurations over time, see [Refactoring](/terraform/language/modules/develop/refactoring). - -## Resource configuration - -Before importing, you must add configuration for every resource you want Terraform to import. Otherwise, Terraform throws an error during planning, insisting you add resource configuration before it can successfully import. You can create resource configuration manually or [generate it using Terraform](/terraform/language/import/generating-configuration). - -We recommend writing a `resource` block if you know what most of the [resource's arguments](/terraform/language/resources/syntax#resource-arguments) will be. For example, your configuration may already contain a similar resource whose configuration you can copy and modify. - -We recommend [generating configuration](/terraform/language/import/generating-configuration) when importing multiple resources or a single complex resource that you do not already have the configuration for. - -### Add a `resource` block - -Add a `resource` block for the resource to import. The resource address must match the import block's `to` argument. - -```hcl -import { - to = aws_instance.example - id = "i-abcd1234" -} - -resource "aws_instance" "example" { - name = "renderer" -} -``` - -### Generate configuration - -Terraform can generate HCL for resources that do not already exist in configuration. -For more details, see [Generating Configuration](/terraform/language/import/generating-configuration). - -## Examples - -The following example demonstrates how to import into a module. - -```hcl -import { - to = module.instances.aws_instance.example - id = "i-abcd1234" -} -``` - -The below example shows how to use the value of a variable as the import ID. - -```hcl -import { - to = aws_instance.example - id = var.instance_id -} -``` - -The below example shows how to import a resource that includes [`count`](/terraform/language/meta-arguments/count). - -```hcl -import { - to = aws_instance.example[0] - id = "i-abcd1234" -} -``` - -The below example shows how to import a resource that includes [`for_each`](/terraform/language/meta-arguments/for_each). -```hcl -import { - to = aws_instance.example["foo"] - id = "i-abcd1234" -} -``` - -Finally, the below example demonstrates how to import from a custom resource provider. - -```hcl -provider "aws" { - alias = "europe" - region = "eu-west-1" -} - -import { - provider = aws.europe - to = aws_instance.example["foo"] - id = "i-abcd1234" -} -``` diff --git a/website/docs/language/index.mdx b/website/docs/language/index.mdx deleted file mode 100644 index 8918a050c7..0000000000 --- a/website/docs/language/index.mdx +++ /dev/null @@ -1,125 +0,0 @@ ---- -page_title: Overview - Configuration Language -description: >- - Use the Terraform configuration language to describe the infrastructure that Terraform manages. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Language Documentation - -This is the documentation for Terraform's configuration language. It is relevant -to users of [Terraform CLI](/terraform/cli), -[HCP Terraform](https://cloud.hashicorp.com/products/terraform), and -[Terraform Enterprise](/terraform/enterprise). Terraform's language is -its primary user interface. Configuration files you write in Terraform -language tell Terraform what plugins to install, what infrastructure to create, -and what data to fetch. Terraform language also lets you define dependencies -between resources and create multiple similar resources from a single -configuration block. - -> **Hands-on:** Try the [Write Terraform Configuration](/terraform/tutorials/configuration-language) tutorials. - -## About the Terraform Language - -The main purpose of the Terraform language is declaring -[resources](/terraform/language/resources), which represent infrastructure objects. All other -language features exist only to make the definition of resources more flexible -and convenient. - -A _Terraform configuration_ is a complete document in the Terraform language -that tells Terraform how to manage a given collection of infrastructure. A -configuration can consist of multiple files and directories. - -The syntax of the Terraform language consists of only a few basic elements: - -```hcl -resource "aws_vpc" "main" { - cidr_block = var.base_cidr_block -} - - "" "" { - # Block body - = # Argument -} -``` - -- _Blocks_ are containers for other content and usually represent the - configuration of some kind of object, like a resource. Blocks have a - _block type,_ can have zero or more _labels,_ and have a _body_ that contains - any number of arguments and nested blocks. Most of Terraform's features are - controlled by top-level blocks in a configuration file. -- _Arguments_ assign a value to a name. They appear within blocks. -- _Expressions_ represent a value, either literally or by referencing and - combining other values. They appear as values for arguments, or within other - expressions. - -The Terraform language is declarative, describing an intended goal rather than -the steps to reach that goal. The ordering of blocks and the files they are -organized into are generally not significant; Terraform only considers implicit -and explicit relationships between resources when determining an order of -operations. - -### Example - -The following example describes a simple network topology for Amazon Web -Services, just to give a sense of the overall structure and syntax of the -Terraform language. Similar configurations can be created for other virtual -network services, using resource types defined by other providers, and a -practical network configuration will often contain additional elements not -shown here. - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 1.0.4" - } - } -} - -variable "aws_region" {} - -variable "base_cidr_block" { - description = "A /16 CIDR range definition, such as 10.1.0.0/16, that the VPC will use" - default = "10.1.0.0/16" -} - -variable "availability_zones" { - description = "A list of availability zones in which to create subnets" - type = list(string) -} - -provider "aws" { - region = var.aws_region -} - -resource "aws_vpc" "main" { - # Referencing the base_cidr_block variable allows the network address - # to be changed without modifying the configuration. - cidr_block = var.base_cidr_block -} - -resource "aws_subnet" "az" { - # Create one subnet for each given availability zone. - count = length(var.availability_zones) - - # For each subnet, use one of the specified availability zones. - availability_zone = var.availability_zones[count.index] - - # By referencing the aws_vpc.main object, Terraform knows that the subnet - # must be created only after the VPC is created. - vpc_id = aws_vpc.main.id - - # Built-in functions and operators can be used for simple transformations of - # values, such as computing a subnet address. Here we create a /20 prefix for - # each subnet, using consecutive addresses for each availability zone, - # such as 10.1.16.0/20 . - cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 4, count.index+1) -} -``` diff --git a/website/docs/language/meta-arguments/count.mdx b/website/docs/language/meta-arguments/count.mdx deleted file mode 100644 index c1b46c6126..0000000000 --- a/website/docs/language/meta-arguments/count.mdx +++ /dev/null @@ -1,130 +0,0 @@ ---- -page_title: The count Meta-Argument - Configuration Language -description: >- - Count helps you efficiently manage nearly identical infrastructure resources - without writing a separate block for each one. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `count` Meta-Argument - --> **Version note:** Module support for `count` was added in Terraform 0.13, and -previous versions can only use it with resources. - --> **Note:** A given resource or module block cannot use both `count` and `for_each`. - -> **Hands-on:** Try the [Manage Similar Resources With Count](/terraform/tutorials/0-13/count?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -By default, a [resource block](/terraform/language/resources/syntax) configures one real -infrastructure object. (Similarly, a -[module block](/terraform/language/modules/syntax) includes a -child module's contents into the configuration one time.) -However, sometimes you want to manage several similar objects (like a fixed -pool of compute instances) without writing a separate block for each one. -Terraform has two ways to do this: -`count` and [`for_each`](/terraform/language/meta-arguments/for_each). - -If a resource or module block includes a `count` argument whose value is a whole number, -Terraform will create that many instances. - -## Basic Syntax - -`count` is a meta-argument defined by the Terraform language. It can be used -with modules and with every resource type. - -The `count` meta-argument accepts a whole number, and creates that many -instances of the resource or module. Each instance has a distinct infrastructure object -associated with it, and each is separately created, -updated, or destroyed when the configuration is applied. - -```hcl -resource "aws_instance" "server" { - count = 4 # create four similar EC2 instances - - ami = "ami-a1b2c3d4" - instance_type = "t2.micro" - - tags = { - Name = "Server ${count.index}" - } -} -``` - -## The `count` Object - -In blocks where `count` is set, an additional `count` object is -available in expressions, so you can modify the configuration of each instance. -This object has one attribute: - -- `count.index` — The distinct index number (starting with `0`) corresponding - to this instance. - -## Using Expressions in `count` - -The `count` meta-argument accepts numeric [expressions](/terraform/language/expressions). -However, unlike most arguments, the `count` value must be known -_before_ Terraform performs any remote resource actions. This means `count` -can't refer to any resource attributes that aren't known until after a -configuration is applied (such as a unique ID generated by the remote API when -an object is created). - -## Referring to Instances - -When `count` is set, Terraform distinguishes between the block itself -and the multiple _resource or module instances_ associated with it. Instances are -identified by an index number, starting with `0`. - -- `.` or `module.` (for example, `aws_instance.server`) refers to the resource block. -- `.[]` or `module.[]` (for example, `aws_instance.server[0]`, - `aws_instance.server[1]`, etc.) refers to individual instances. - -This is different from resources and modules without `count` or `for_each`, which can be -referenced without an index or key. - -Similarly, resources from child modules with multiple instances are prefixed -with `module.[]` when displayed in plan output and elsewhere in the UI. -For a module without `count` or `for_each`, the address will not contain -the module index as the module's name suffices to reference the module. - --> **Note:** Within nested `provisioner` or `connection` blocks, the special -`self` object refers to the current _resource instance,_ not the resource block -as a whole. - -## When to Use `for_each` Instead of `count` - -If your instances are almost identical, `count` is appropriate. If some -of their arguments need distinct values that can't be directly derived from an -integer, it's safer to use `for_each`. - -Before `for_each` was available, it was common to derive `count` from the -length of a list and use `count.index` to look up the original list value: - -```hcl -variable "subnet_ids" { - type = list(string) -} - -resource "aws_instance" "server" { - # Create one instance for each subnet - count = length(var.subnet_ids) - - ami = "ami-a1b2c3d4" - instance_type = "t2.micro" - subnet_id = var.subnet_ids[count.index] - - tags = { - Name = "Server ${count.index}" - } -} -``` - -This was fragile, because the resource instances were still identified by their -_index_ instead of the string values in the list. If an element was removed from -the middle of the list, every instance _after_ that element would see its -`subnet_id` value change, resulting in more remote object changes than intended. -Using `for_each` gives the same flexibility without the extra churn. diff --git a/website/docs/language/meta-arguments/depends_on.mdx b/website/docs/language/meta-arguments/depends_on.mdx deleted file mode 100644 index d83b22f3b1..0000000000 --- a/website/docs/language/meta-arguments/depends_on.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -page_title: The depends_on Meta-Argument - Configuration Language -description: >- - The depends_on meta-argument allows you to handle hidden resource or module - dependencies. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `depends_on` Meta-Argument - -Use the `depends_on` meta-argument to handle hidden resource or module dependencies that Terraform cannot automatically infer. You only need to explicitly specify a dependency when a resource or module relies on another resource's behavior but does not access any of that resource's data in its arguments. - --> **Note:** Module support for `depends_on` was added in Terraform version 0.13, and prior versions can only use it with resources. - - -## Processing and Planning Consequences - -The `depends_on` meta-argument instructs Terraform to complete all actions on the dependency object (including Read actions) before performing actions on the object declaring the dependency. When the dependency object is an entire module, `depends_on` affects the order in which Terraform processes all of the resources and data sources associated with that module. Refer to [Resource Dependencies](/terraform/language/resources/behavior#resource-dependencies) and [Data Resource Dependencies](/terraform/language/data-sources#data-resource-dependencies) for more details. - -You should use `depends_on` as a last resort because it can cause Terraform to create more conservative plans that replace more resources than necessary. For example, Terraform may treat more values as unknown “(known after apply)” because it is uncertain what changes will occur on the upstream object. This is especially likely when you use `depends_on` for modules. - -Instead of `depends_on`, we recommend using [expression references](/terraform/language/expressions/references) to imply dependencies when possible. Expression references let Terraform understand which value the reference derives from and avoid planning changes if that particular value hasn’t changed, even if other parts of the upstream object have planned changes. - -## Usage - -You can use the `depends_on` meta-argument in `module` blocks and in all `resource` blocks, regardless of resource type. It requires a list of references to other resources or child modules in the same calling module. This list cannot include arbitrary expressions because the `depends_on` value must be known before Terraform knows resource relationships and thus before it can safely evaluate expressions. - -We recommend always including a comment that explains why using `depends_on` is necessary. The following example uses `depends_on` to handle a "hidden" dependency on the `aws_iam_instance_profile.example`. - -```hcl -resource "aws_iam_role" "example" { - name = "example" - - # assume_role_policy is omitted for brevity in this example. Refer to the - # documentation for aws_iam_role for a complete example. - assume_role_policy = "..." -} - -resource "aws_iam_instance_profile" "example" { - # Because this expression refers to the role, Terraform can infer - # automatically that the role must be created first. - role = aws_iam_role.example.name -} - -resource "aws_iam_role_policy" "example" { - name = "example" - role = aws_iam_role.example.name - policy = jsonencode({ - "Statement" = [{ - # This policy allows software running on the EC2 instance to - # access the S3 API. - "Action" = "s3:*", - "Effect" = "Allow", - }], - }) -} - -resource "aws_instance" "example" { - ami = "ami-a1b2c3d4" - instance_type = "t2.micro" - - # Terraform can infer from this that the instance profile must - # be created before the EC2 instance. - iam_instance_profile = aws_iam_instance_profile.example - - # However, if software running in this EC2 instance needs access - # to the S3 API in order to boot properly, there is also a "hidden" - # dependency on the aws_iam_role_policy that Terraform cannot - # automatically infer, so it must be declared explicitly: - depends_on = [ - aws_iam_role_policy.example - ] -} -``` diff --git a/website/docs/language/meta-arguments/for_each.mdx b/website/docs/language/meta-arguments/for_each.mdx deleted file mode 100644 index e3f934880a..0000000000 --- a/website/docs/language/meta-arguments/for_each.mdx +++ /dev/null @@ -1,279 +0,0 @@ ---- -page_title: The for_each Meta-Argument - Configuration Language -description: >- - The for_each meta-argument allows you to manage similar infrastructure - resources without writing a separate block for each one. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `for_each` Meta-Argument - -By default, a [resource block](/terraform/language/resources/syntax) configures one real -infrastructure object (and similarly, a -[module block](/terraform/language/modules/syntax) includes a -child module's contents into the configuration one time). -However, sometimes you want to manage several similar objects (like a fixed -pool of compute instances) without writing a separate block for each one. -Terraform has two ways to do this: -[`count`](/terraform/language/meta-arguments/count) and `for_each`. - -> **Hands-on:** Try the [Manage Similar Resources With For Each](/terraform/tutorials/configuration-language/for-each) tutorial. - -If a resource or module block includes a `for_each` argument whose value is a map or -a set of strings, Terraform creates one instance for each member of -that map or set. - --> **Version note:** `for_each` was added in Terraform 0.12.6. Module support -for `for_each` was added in Terraform 0.13; previous versions can only use -it with resources. - --> **Note:** A given resource or module block cannot use both `count` and `for_each`. - -## Basic Syntax - -`for_each` is a meta-argument defined by the Terraform language. It can be used -with modules and with every resource type. - -The `for_each` meta-argument accepts a map or a set of strings, and creates an -instance for each item in that map or set. Each instance has a distinct -infrastructure object associated with it, and each is separately created, -updated, or destroyed when the configuration is applied. - -Map: - -```hcl -resource "azurerm_resource_group" "rg" { - for_each = tomap({ - a_group = "eastus" - another_group = "westus2" - }) - name = each.key - location = each.value -} -``` - -Set of strings: - -```hcl -resource "aws_iam_user" "the-accounts" { - for_each = toset(["Todd", "James", "Alice", "Dottie"]) - name = each.key -} -``` - -Child module: - -```hcl -# my_buckets.tf -module "bucket" { - for_each = toset(["assets", "media"]) - source = "./publish_bucket" - name = "${each.key}_bucket" -} -``` - -```hcl -# publish_bucket/bucket-and-cloudfront.tf -variable "name" {} # this is the input parameter of the module - -resource "aws_s3_bucket" "example" { - # Because var.name includes each.key in the calling - # module block, its value will be different for - # each instance of this module. - bucket = var.name - - # ... -} - -resource "aws_iam_user" "deploy_user" { - # ... -} -``` - -## The `each` Object - -In blocks where `for_each` is set, an additional `each` object is -available in expressions, so you can modify the configuration of each instance. -This object has two attributes: - -- `each.key` — The map key (or set member) corresponding to this instance. -- `each.value` — The map value corresponding to this instance. (If a set was - provided, this is the same as `each.key`.) - -## Limitations on values used in `for_each` - -The keys of the map (or all the values in the case of a set of strings) must -be _known values_, or you will get an error message that `for_each` has dependencies -that cannot be determined before apply, and a `-target` may be needed. - -`for_each` keys cannot be the result (or rely on the result of) of impure functions, -including `uuid`, `bcrypt`, or `timestamp`, as their evaluation is deferred during the -main evaluation step. - -Sensitive values, such as [sensitive input variables](/terraform/language/values/variables#suppressing-values-in-cli-output), -[sensitive outputs](/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output), -or [sensitive resource attributes](/terraform/language/expressions/references#sensitive-resource-attributes), -cannot be used as arguments to `for_each`. The value used in `for_each` is used -to identify the resource instance and will always be disclosed in UI output, -which is why sensitive values are not allowed. -Attempts to use sensitive values as `for_each` arguments will result in an error. - -If you transform a value containing sensitive data into an argument to be used in `for_each`, be aware that -[most functions in Terraform will return a sensitive result if given an argument with any sensitive content](/terraform/language/expressions/function-calls#using-sensitive-data-as-function-arguments). -In many cases, you can achieve similar results to a function used for this purpose by -using a `for` expression. For example, if you would like to call `keys(local.map)`, where -`local.map` is an object with sensitive values (but non-sensitive keys), you can create a -value to pass to `for_each` with `toset([for k,v in local.map : k])`. - -## Using Expressions in `for_each` - -The `for_each` meta-argument accepts map or set [expressions](/terraform/language/expressions). -However, unlike most arguments, the `for_each` value must be known -_before_ Terraform performs any remote resource actions. This means `for_each` -can't refer to any resource attributes that aren't known until after a -configuration is applied (such as a unique ID generated by the remote API when -an object is created). - -The `for_each` value must be a map or set with one element per desired resource -instance. To use a sequence as the `for_each` value, you must use an expression -that explicitly returns a set value, like the [toset](/terraform/language/functions/toset) -function. To prevent unwanted surprises during conversion, the `for_each` argument -does not implicitly convert lists or tuples to sets. -If you need to declare resource instances based on a nested -data structure or combinations of elements from multiple data structures you -can use Terraform expressions and functions to derive a suitable value. -For example: - -- Transform a multi-level nested structure into a flat list by - [using nested `for` expressions with the `flatten` function](/terraform/language/functions/flatten#flattening-nested-structures-for-for_each). -- Produce an exhaustive list of combinations of elements from two or more - collections by - [using the `setproduct` function inside a `for` expression](/terraform/language/functions/setproduct#finding-combinations-for-for_each). - -### Chaining `for_each` Between Resources - -Because a resource using `for_each` appears as a map of objects when used in -expressions elsewhere, you can directly use one resource as the `for_each` -of another in situations where there is a one-to-one relationship between -two sets of objects. - -For example, in AWS an `aws_vpc` object is commonly associated with a number -of other objects that provide additional services to that VPC, such as an -"internet gateway". If you are declaring multiple VPC instances using `for_each` -then you can chain that `for_each` into another resource to declare an -internet gateway for each VPC: - -```hcl -variable "vpcs" { - type = map(object({ - cidr_block = string - })) -} - -resource "aws_vpc" "example" { - # One VPC for each element of var.vpcs - for_each = var.vpcs - - # each.value here is a value from var.vpcs - cidr_block = each.value.cidr_block -} - -resource "aws_internet_gateway" "example" { - # One Internet Gateway per VPC - for_each = aws_vpc.example - - # each.value here is a full aws_vpc object - vpc_id = each.value.id -} - -output "vpc_ids" { - value = { - for k, v in aws_vpc.example : k => v.id - } - - # The VPCs aren't fully functional until their - # internet gateways are running. - depends_on = [aws_internet_gateway.example] -} -``` - -This chaining pattern explicitly and concisely declares the relationship -between the internet gateway instances and the VPC instances, which tells -Terraform to expect the instance keys for both to always change together, -and typically also makes the configuration easier to understand for human -maintainers. - -## Referring to Instances - -When `for_each` is set, Terraform distinguishes between the block itself -and the multiple _resource or module instances_ associated with it. Instances are -identified by a map key (or set member) from the value provided to `for_each`. - -- `.` or `module.` (for example, `azurerm_resource_group.rg`) refers to the block. -- `.[]` or `module.[]` (for example, `azurerm_resource_group.rg["a_group"]`, - `azurerm_resource_group.rg["another_group"]`, etc.) refers to individual instances. - -This is different from resources and modules without `count` or `for_each`, which can be -referenced without an index or key. - -Similarly, resources from child modules with multiple instances are prefixed -with `module.[]` when displayed in plan output and elsewhere in the UI. -For a module without `count` or `for_each`, the address will not contain -the module index as the module's name suffices to reference the module. - --> **Note:** Within nested `provisioner` or `connection` blocks, the special -`self` object refers to the current _resource instance,_ not the resource block -as a whole. - -## Using Sets - -The Terraform language doesn't have a literal syntax for -[set values](/terraform/language/expressions/type-constraints#collection-types), but you can use the `toset` -function to explicitly convert a list of strings to a set: - -```hcl -locals { - subnet_ids = toset([ - "subnet-abcdef", - "subnet-012345", - ]) -} - -resource "aws_instance" "server" { - for_each = local.subnet_ids - - ami = "ami-a1b2c3d4" - instance_type = "t2.micro" - subnet_id = each.key # note: each.key and each.value are the same for a set - - tags = { - Name = "Server ${each.key}" - } -} -``` - -Conversion from list to set discards the ordering of the items in the list and -removes any duplicate elements. `toset(["b", "a", "b"])` will produce a set -containing only `"a"` and `"b"` in no particular order; the second `"b"` is -discarded. - -If you are writing a module with an [input variable](/terraform/language/values/variables) that -will be used as a set of strings for `for_each`, you can set its type to -`set(string)` to avoid the need for an explicit type conversion: - -```hcl -variable "subnet_ids" { - type = set(string) -} - -resource "aws_instance" "server" { - for_each = var.subnet_ids - - # (and the other arguments as above) -} -``` diff --git a/website/docs/language/meta-arguments/lifecycle.mdx b/website/docs/language/meta-arguments/lifecycle.mdx deleted file mode 100644 index e85198ac80..0000000000 --- a/website/docs/language/meta-arguments/lifecycle.mdx +++ /dev/null @@ -1,188 +0,0 @@ ---- -page_title: The lifecycle Meta-Argument - Configuration Language -description: >- - The meta-arguments in a lifecycle block allow you to customize resource - 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `lifecycle` Meta-Argument - -> **Hands-on:** Try the [Lifecycle Management](/terraform/tutorials/state/resource-lifecycle?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -The [Resource Behavior](/terraform/language/resources/behavior) page describes the general lifecycle for resources. Some details of -that behavior can be customized using the special nested `lifecycle` block -within a resource block body: - -```hcl -resource "azurerm_resource_group" "example" { - # ... - - lifecycle { - create_before_destroy = true - } -} -``` - -## Syntax and Arguments - -`lifecycle` is a nested block that can appear within a resource block. -The `lifecycle` block and its contents are meta-arguments, available -for all `resource` blocks regardless of type. - -The arguments available within a `lifecycle` block are `create_before_destroy`, -`prevent_destroy`, `ignore_changes`, and `replace_triggered_by`. - -* `create_before_destroy` (bool) - By default, when Terraform must change - a resource argument that cannot be updated in-place due to - remote API limitations, Terraform will instead destroy the existing object - and then create a new replacement object with the new configured arguments. - - The `create_before_destroy` meta-argument changes this behavior so that - the new replacement object is created _first,_ and the prior object - is destroyed after the replacement is created. - - This is an opt-in behavior because many remote object types have unique - name requirements or other constraints that must be accommodated for - both a new and an old object to exist concurrently. Some resource types - offer special options to append a random suffix onto each object name to - avoid collisions, for example. Terraform CLI cannot automatically activate - such features, so you must understand the constraints for each resource - type before using `create_before_destroy` with it. - - Note that Terraform propagates and applies the `create_before_destroy` meta-attribute - behaviour to all resource dependencies. For example, if `create_before_destroy` is enabled on resource A but not on resource B, but resource A is dependent on resource B, then Terraform enables `create_before_destroy` for resource B - implicitly by default and stores it to the state file. You cannot override `create_before_destroy` - to `false` on resource B because that would imply dependency cycles in the graph. - - Destroy provisioners of this resource do not run if `create_before_destroy` - is set to `true`. - -* `prevent_destroy` (bool) - This meta-argument, when set to `true`, will - cause Terraform to reject with an error any plan that would destroy the - infrastructure object associated with the resource, as long as the argument - remains present in the configuration. - - This can be used as a measure of safety against the accidental replacement - of objects that may be costly to reproduce, such as database instances. - However, it will make certain configuration changes impossible to apply, - and will prevent the use of the `terraform destroy` command once such - objects are created, and so this option should be used sparingly. - - Since this argument must be present in configuration for the protection to - apply, note that this setting does not prevent the remote object from - being destroyed if the `resource` block were removed from configuration - entirely: in that case, the `prevent_destroy` setting is removed along - with it, and so Terraform will allow the destroy operation to succeed. - -* `ignore_changes` (list of attribute names) - By default, Terraform detects - any difference in the current settings of a real infrastructure object - and plans to update the remote object to match configuration. - - The `ignore_changes` feature is intended to be used when a resource is - created with references to data that may change in the future, but should - not affect said resource after its creation. In some rare cases, settings - of a remote object are modified by processes outside of Terraform, which - Terraform would then attempt to "fix" on the next run. In order to make - Terraform share management responsibilities of a single object with a - separate process, the `ignore_changes` meta-argument specifies resource - attributes that Terraform should ignore when planning updates to the - associated remote object. - - The arguments corresponding to the given attribute names are considered - when planning a _create_ operation, but are ignored when planning an - _update_. The arguments are the relative address of the attributes in the - resource. Map and list elements can be referenced using index notation, - like `tags["Name"]` and `list[0]` respectively. - - ```hcl - resource "aws_instance" "example" { - # ... - - lifecycle { - ignore_changes = [ - # Ignore changes to tags, e.g. because a management agent - # updates these based on some ruleset managed elsewhere. - tags, - ] - } - } - ``` - - Instead of a list, the special keyword `all` may be used to instruct - Terraform to ignore _all_ attributes, which means that Terraform can - create and destroy the remote object but will never propose updates to it. - - Only attributes defined by the resource type can be ignored. - `ignore_changes` cannot be applied to itself or to any other meta-arguments. - -* `replace_triggered_by` (list of resource or attribute references) - - _Added in Terraform 1.2._ Replaces the resource when any of the referenced - items change. Supply a list of expressions referencing managed resources, - instances, or instance attributes. When used in a resource that uses `count` - or `for_each`, you can use `count.index` or `each.key` in the expression to - reference specific instances of other resources that are configured with the - same count or collection. - - References trigger replacement in the following conditions: - - - If the reference is to a resource with multiple instances, a plan to - update or replace any instance will trigger replacement. - - If the reference is to a single resource instance, a plan to update or - replace that instance will trigger replacement. - - If the reference is to a single attribute of a resource instance, any - change to the attribute value will trigger replacement. - - You can only reference managed resources in `replace_triggered_by` - expressions. This lets you modify these expressions without forcing - replacement. - - ```hcl - resource "aws_appautoscaling_target" "ecs_target" { - # ... - lifecycle { - replace_triggered_by = [ - # Replace `aws_appautoscaling_target` each time this instance of - # the `aws_ecs_service` is replaced. - aws_ecs_service.svc.id - ] - } - } - ``` - - `replace_triggered_by` allows only resource addresses because the decision is based on the planned actions for all of the given resources. Plain values such as local values or input variables do not have planned actions of their own, but you can treat them with a resource-like lifecycle by using them with [the `terraform_data` resource type](/terraform/language/resources/terraform-data). - -## Custom Condition Checks - -You can add `precondition` and `postcondition` blocks with a `lifecycle` block to specify assumptions and guarantees about how resources and data sources operate. The following examples creates a precondition that checks whether the AMI is properly configured. - -```hcl -resource "aws_instance" "example" { - instance_type = "t2.micro" - ami = "ami-abc123" - - lifecycle { - # The AMI ID must refer to an AMI that contains an operating system - # for the `x86_64` architecture. - precondition { - condition = data.aws_ami.example.architecture == "x86_64" - error_message = "The selected AMI must be for the x86_64 architecture." - } - } -} -``` - -Custom conditions can help capture assumptions, helping future maintainers understand the configuration design and intent. They also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations. - -Refer to [Custom Conditions](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions) for more details. - -## Literal Values Only - -The `lifecycle` settings all affect how Terraform constructs and traverses -the dependency graph. As a result, only literal values can be used because -the processing happens too early for arbitrary expression evaluation. diff --git a/website/docs/language/meta-arguments/module-providers.mdx b/website/docs/language/meta-arguments/module-providers.mdx deleted file mode 100644 index 4f0870f47e..0000000000 --- a/website/docs/language/meta-arguments/module-providers.mdx +++ /dev/null @@ -1,132 +0,0 @@ ---- -page_title: The Module providers Meta-Argument - Configuration Language -description: >- - The providers meta-argument specifies which provider configurations from a - parent module are available in a child module. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The Module `providers` Meta-Argument - -In a [module call](/terraform/language/modules/syntax) block, the -optional `providers` meta-argument specifies which -[provider configurations](/terraform/language/providers/configuration) from the parent -module will be available inside the child module. - -```hcl -# The default "aws" configuration is used for AWS resources in the root -# module where no explicit provider instance is selected. -provider "aws" { - region = "us-west-1" -} - -# An alternate configuration is also defined for a different -# region, using the alias "usw2". -provider "aws" { - alias = "usw2" - region = "us-west-2" -} - -# An example child module is instantiated with the alternate configuration, -# so any AWS resources it defines will use the us-west-2 region. -module "example" { - source = "./example" - providers = { - aws = aws.usw2 - } -} -``` - -## Default Behavior: Inherit Default Providers - -If the child module does not declare any [configuration aliases](/terraform/language/modules/develop/providers#provider-aliases-within-modules), -the `providers` argument is optional. If you omit it, a child module inherits -all of the _default_ provider configurations from its parent module. (Default -provider configurations are ones that don't use the `alias` argument.) - -If you specify a `providers` argument, it cancels this default behavior, and the -child module will _only_ have access to the provider configurations you specify. - -## Usage and Behavior - -The value of `providers` is a map, where: - -- The keys are the provider configuration names used inside the child module. -- The values are provider configuration names from the parent module. - -Both keys and values should be unquoted references to provider configurations. -For default configurations, this is the local name of the provider; for -alternate configurations, this is a `.` reference. - -Within a child module, resources are assigned to provider configurations as -normal — either Terraform chooses a default based on the name of the resource -type, or the resource specifies an alternate configuration with the `provider` -argument. If the module receives a `providers` map when it's called, the -provider configuration names used within the module are effectively remapped to -refer the specified configurations from the parent module. - -## When to Specify Providers - -There are two main reasons to use the `providers` argument: - -- Using different default provider configurations for a child module. -- Configuring a module that requires multiple configurations of the same provider. - -### Changing Default Provider Configurations - -Most re-usable modules only use default provider configurations, which they can -automatically inherit from their caller when `providers` is omitted. - -However, in Terraform configurations that use multiple configurations of the -same provider, you might want some child modules to use the default provider -configuration and other ones to use an alternate. (This usually happens when -using one configuration to manage resources in multiple different regions of the -same cloud provider.) - -By using the `providers` argument (like in the code example above), you can -accommodate this without needing to edit the child module. Although the code -within the child module always refers to the default provider configuration, the -actual configuration of that default can be different for each instance. - -### Modules With Alternate Provider Configurations - -In rare cases, a single re-usable module might require multiple configurations -of the same provider. For example, a module that configures connectivity between -networks in two AWS regions is likely to need both a source and a destination -region. In that case, the root module may look something like this: - -```hcl -provider "aws" { - alias = "usw1" - region = "us-west-1" -} - -provider "aws" { - alias = "usw2" - region = "us-west-2" -} - -module "tunnel" { - source = "./tunnel" - providers = { - aws.src = aws.usw1 - aws.dst = aws.usw2 - } -} -``` - -Non-default provider configurations are never automatically inherited, so any -module that works like this will always need a `providers` argument. The -documentation for the module should specify all of the provider configuration -names it needs. - -## More Information for Module Developers - -For more details and guidance about working with providers inside a re-usable -child module, see -[Module Development: Providers Within Modules](/terraform/language/modules/develop/providers). diff --git a/website/docs/language/meta-arguments/resource-provider.mdx b/website/docs/language/meta-arguments/resource-provider.mdx deleted file mode 100644 index ca36bf71dc..0000000000 --- a/website/docs/language/meta-arguments/resource-provider.mdx +++ /dev/null @@ -1,65 +0,0 @@ ---- -page_title: The Resource provider Meta-Argument - Configuration Language -description: >- - The provider meta-argument specifies the provider configuration Terraform - should use for a resource, overriding Terraform's default 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The Resource `provider` Meta-Argument - -The `provider` meta-argument specifies which provider configuration to use for a resource, -overriding Terraform's default behavior of selecting one based on the resource -type name. Its value should be an unquoted `.` reference. - -As described in [Provider Configuration](/terraform/language/providers/configuration), you can optionally -create multiple configurations for a single provider (usually to manage -resources in different regions of multi-region services). Each provider can have -one default configuration, and any number of alternate configurations that -include an extra name segment (or "alias"). - -By default, Terraform interprets the initial word in the resource type name -(separated by underscores) as the local name of a provider, and uses that -provider's default configuration. For example, the resource type -`google_compute_instance` is associated automatically with the default -configuration for the provider named `google`. - -By using the `provider` meta-argument, you can select an alternate provider -configuration for a resource: - -```hcl -# default configuration -provider "google" { - region = "us-central1" -} - -# alternate configuration, whose alias is "europe" -provider "google" { - alias = "europe" - region = "europe-west1" -} - -resource "google_compute_instance" "example" { - # This "provider" meta-argument selects the google provider - # configuration whose alias is "europe", rather than the - # default configuration. - provider = google.europe - - # ... -} -``` - -A resource always has an implicit dependency on its associated provider, to -ensure that the provider is fully configured before any resource actions -are taken. - -The `provider` meta-argument expects -[a `.` reference](/terraform/language/providers/configuration#referring-to-alternate-provider-configurations), -which does not need to be quoted. Arbitrary expressions are not permitted for -`provider` because it must be resolved while Terraform is constructing the -dependency graph, before it is safe to evaluate expressions. diff --git a/website/docs/language/modules/develop/composition.mdx b/website/docs/language/modules/develop/composition.mdx deleted file mode 100644 index d83ed7d196..0000000000 --- a/website/docs/language/modules/develop/composition.mdx +++ /dev/null @@ -1,382 +0,0 @@ ---- -page_title: Module Composition -description: |- - Module composition allows infrastructure to be described from modular - building blocks. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Composition - -In a simple Terraform configuration with only one root module, we create a -flat set of resources and use Terraform's expression syntax to describe the -relationships between these resources: - -```hcl -resource "aws_vpc" "example" { - cidr_block = "10.1.0.0/16" -} - -resource "aws_subnet" "example" { - vpc_id = aws_vpc.example.id - - availability_zone = "us-west-2b" - cidr_block = cidrsubnet(aws_vpc.example.cidr_block, 4, 1) -} -``` - -When we introduce `module` blocks, our configuration becomes hierarchical -rather than flat: each module contains its own set of resources, and possibly -its own child modules, which can potentially create a deep, complex tree of -resource configurations. - -However, in most cases we strongly recommend keeping the module tree flat, -with only one level of child modules, and use a technique similar to the -above of using expressions to describe the relationships between the modules: - -```hcl -module "network" { - source = "./modules/aws-network" - - base_cidr_block = "10.0.0.0/8" -} - -module "consul_cluster" { - source = "./modules/aws-consul-cluster" - - vpc_id = module.network.vpc_id - subnet_ids = module.network.subnet_ids -} -``` - -We call this flat style of module usage _module composition_, because it -takes multiple [composable](https://en.wikipedia.org/wiki/Composability) -building-block modules and assembles them together to produce a larger system. -Instead of a module _embedding_ its dependencies, creating and managing its -own copy, the module _receives_ its dependencies from the root module, which -can therefore connect the same modules in different ways to produce different -results. - -The rest of this page discusses some more specific composition patterns that -may be useful when describing larger systems with Terraform. - -## Dependency Inversion - -In the example above, we saw a `consul_cluster` module that presumably describes -a cluster of [HashiCorp Consul](https://www.consul.io/) servers running in -an AWS VPC network, and thus it requires as arguments the identifiers of both -the VPC itself and of the subnets within that VPC. - -An alternative design would be to have the `consul_cluster` module describe -its _own_ network resources, but if we did that then it would be hard for -the Consul cluster to coexist with other infrastructure in the same network, -and so where possible we prefer to keep modules relatively small and pass in -their dependencies. - -This [dependency inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle) -approach also improves flexibility for future -refactoring, because the `consul_cluster` module doesn't know or care how -those identifiers are obtained by the calling module. A future refactor may -separate the network creation into its own configuration, and thus we may -pass those values into the module from data sources instead: - -```hcl -data "aws_vpc" "main" { - tags = { - Environment = "production" - } -} - -data "aws_subnet_ids" "main" { - vpc_id = data.aws_vpc.main.id -} - -module "consul_cluster" { - source = "./modules/aws-consul-cluster" - - vpc_id = data.aws_vpc.main.id - subnet_ids = data.aws_subnet_ids.main.ids -} -``` - -### Conditional Creation of Objects - -In situations where the same module is used across multiple environments, -it's common to see that some necessary object already exists in some -environments but needs to be created in other environments. - -For example, this can arise in development environment scenarios: for cost -reasons, certain infrastructure may be shared across multiple development -environments, while in production the infrastructure is unique and managed -directly by the production configuration. - -Rather than trying to write a module that itself tries to detect whether something -exists and create it if not, we recommend applying the dependency inversion -approach: making the module accept the object it needs as an argument, via -an input variable. - -For example, consider a situation where a Terraform module deploys compute -instances based on a disk image, and in some environments there is a -specialized disk image available while other environments share a common -base disk image. Rather than having the module itself handle both of these -scenarios, we can instead declare an input variable for an object representing -the disk image. Using AWS EC2 as an example, we might declare a common subtype -of the `aws_ami` resource type and data source schemas: - -```hcl -variable "ami" { - type = object({ - # Declare an object using only the subset of attributes the module - # needs. Terraform will allow any object that has at least these - # attributes. - id = string - architecture = string - }) -} -``` - -The caller of this module can now itself directly represent whether this is -an AMI to be created inline or an AMI to be retrieved from elsewhere: - -```hcl -# In situations where the AMI will be directly managed: - -resource "aws_ami_copy" "example" { - name = "local-copy-of-ami" - source_ami_id = "ami-abc123" - source_ami_region = "eu-west-1" -} - -module "example" { - source = "./modules/example" - - ami = aws_ami_copy.example -} -``` - -```hcl -# Or, in situations where the AMI already exists: - -data "aws_ami" "example" { - owner = "9999933333" - - tags = { - application = "example-app" - environment = "dev" - } -} - -module "example" { - source = "./modules/example" - - ami = data.aws_ami.example -} -``` - -This is consistent with Terraform's declarative style: rather than creating -modules with complex conditional branches, we directly describe what -should already exist and what we want Terraform to manage itself. - -By following this pattern, we can be explicit about in which situations we -expect the AMI to already be present and which we don't. A future reader -of the configuration can then directly understand what it is intending to do -without first needing to inspect the state of the remote system. - -In the above example, the object to be created or read is simple enough to -be given inline as a single resource, but we can also compose together multiple -modules as described elsewhere on this page in situations where the -dependencies themselves are complicated enough to benefit from abstractions. - -## Assumptions and Guarantees - -Every module has implicit assumptions and guarantees that define what data it expects and what data it produces for consumers. - -- **Assumption:** A condition that must be true in order for the configuration of a particular resource to be usable. For example, an `aws_instance` configuration can have the assumption that the given AMI will always be configured for the `x86_64` CPU architecture. -- **Guarantee:** A characteristic or behavior of an object that the rest of the configuration should be able to rely on. For example, an `aws_instance` configuration can have the guarantee that an EC2 instance will be running in a network that assigns it a private DNS record. - -We recommend using [custom conditions](/terraform/language/expressions/custom-conditions) to help capture and test for assumptions and guarantees. This helps future maintainers understand the configuration design and intent. Custom conditions also return useful information about errors earlier and in context, helping consumers more easily diagnose issues in their configurations. - -The following examples creates a precondition that checks whether the EC2 instance has an encrypted root volume. - -```hcl -output "api_base_url" { - value = "https://${aws_instance.example.private_dns}:8433/" - - # The EC2 instance must have an encrypted root volume. - precondition { - condition = data.aws_ebs_volume.example.encrypted - error_message = "The server's root volume is not encrypted." - } -} -``` - -## Multi-cloud Abstractions - -Terraform itself intentionally does not attempt to abstract over similar -services offered by different vendors, because we want to expose the full -functionality in each offering and yet unifying multiple offerings behind a -single interface will tend to require a "lowest common denominator" approach. - -However, through composition of Terraform modules it is possible to create -your own lightweight multi-cloud abstractions by making your own tradeoffs -about which platform features are important to you. - -Opportunities for such abstractions arise in any situation where multiple -vendors implement the same concept, protocol, or open standard. For example, -the basic capabilities of the domain name system are common across all vendors, -and although some vendors differentiate themselves with unique features such -as geolocation and smart load balancing, you may conclude that in your use-case -you are willing to eschew those features in return for creating modules that -abstract the common DNS concepts across multiple vendors: - -```hcl -module "webserver" { - source = "./modules/webserver" -} - -locals { - fixed_recordsets = [ - { - name = "www" - type = "CNAME" - ttl = 3600 - records = [ - "webserver01", - "webserver02", - "webserver03", - ] - }, - ] - server_recordsets = [ - for i, addr in module.webserver.public_ip_addrs : { - name = format("webserver%02d", i) - type = "A" - records = [addr] - } - ] -} - -module "dns_records" { - source = "./modules/route53-dns-records" - - route53_zone_id = var.route53_zone_id - recordsets = concat(local.fixed_recordsets, local.server_recordsets) -} -``` - -In the above example, we've created a lightweight abstraction in the form of -a "recordset" object. This contains the attributes that describe the general -idea of a DNS recordset that should be mappable onto any DNS provider. - -We then instantiate one specific _implementation_ of that abstraction as a -module, in this case deploying our recordsets to Amazon Route53. - -If we later wanted to switch to a different DNS provider, we'd need only to -replace the `dns_records` module with a new implementation targeting that -provider, and all of the configuration that _produces_ the recordset -definitions can remain unchanged. - -We can create lightweight abstractions like these by defining Terraform object -types representing the concepts involved and then using these object types -for module input variables. In this case, all of our "DNS records" -implementations would have the following variable declared: - -```hcl -variable "recordsets" { - type = list(object({ - name = string - type = string - ttl = number - records = list(string) - })) -} -``` - -While DNS serves as a simple example, there are many more opportunities to -exploit common elements across vendors. A more complex example is Kubernetes, -where there are now many different vendors offering hosted Kubernetes clusters -and even more ways to run Kubernetes yourself. - -If the common functionality across all of these implementations is sufficient -for your needs, you may choose to implement a set of different modules that -describe a particular Kubernetes cluster implementation and all have the common -trait of exporting the hostname of the cluster as an output value: - -```hcl -output "hostname" { - value = azurerm_kubernetes_cluster.main.fqdn -} -``` - -You can then write _other_ modules that expect only a Kubernetes cluster -hostname as input and use them interchangeably with any of your Kubernetes -cluster modules: - -```hcl -module "k8s_cluster" { - source = "modules/azurerm-k8s-cluster" - - # (Azure-specific configuration arguments) -} - -module "monitoring_tools" { - source = "modules/monitoring_tools" - - cluster_hostname = module.k8s_cluster.hostname -} -``` - -## Data-only Modules - -Most modules contain `resource` blocks and thus describe infrastructure to be -created and managed. It may sometimes be useful to write modules that do not -describe any new infrastructure at all, but merely retrieve information about -existing infrastructure that was created elsewhere using -[data sources](/terraform/language/data-sources). - -As with conventional modules, we suggest using this technique only when the -module raises the level of abstraction in some way, in this case by -encapsulating exactly how the data is retrieved. - -A common use of this technique is when a system has been decomposed into several -subsystem configurations but there is certain infrastructure that is shared -across all of the subsystems, such as a common IP network. In this situation, -we might write a shared module called `join-network-aws` which can be called -by any configuration that needs information about the shared network when -deployed in AWS: - -```hcl -module "network" { - source = "./modules/join-network-aws" - - environment = "production" -} - -module "k8s_cluster" { - source = "./modules/aws-k8s-cluster" - - subnet_ids = module.network.aws_subnet_ids -} -``` - -The `network` module itself could retrieve this data in a number of different -ways: it could query the AWS API directly using -[`aws_vpc`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) -and -[`aws_subnet_ids`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids) -data sources, or it could read saved information from a Consul cluster using -[`consul_keys`](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/data-sources/keys), -or it might read the outputs directly from the state of the configuration that -manages the network using -[`terraform_remote_state`](/terraform/language/state/remote-state-data). - -The key benefit of this approach is that the source of this information can -change over time without updating every configuration that depends on it. -Furthermore, if you design your data-only module with a similar set of outputs -as a corresponding management module, you can swap between the two relatively -easily when refactoring. diff --git a/website/docs/language/modules/develop/index.mdx b/website/docs/language/modules/develop/index.mdx deleted file mode 100644 index d90ca0c2ec..0000000000 --- a/website/docs/language/modules/develop/index.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -page_title: Creating Modules -description: >- - Modules are containers for multiple resources that are used together in a - configuration. Learn when to create modules and about module structure. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Creating Modules - -> **Hands-on:** Try the [Reuse Configuration with Modules](/terraform/tutorials/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. - -A _module_ is a container for multiple resources that are used together. -You can use modules to create lightweight abstractions, so that you can -describe your infrastructure in terms of its architecture, rather than -directly in terms of physical objects. - -The `.tf` files in your working directory when you run [`terraform plan`](/terraform/cli/commands/plan) -or [`terraform apply`](/terraform/cli/commands/apply) together form the _root_ -module. That module may [call other modules](/terraform/language/modules/syntax#calling-a-child-module) -and connect them together by passing output values from one to input values -of another. - -To learn how to _use_ modules, see [the Modules configuration section](/terraform/language/modules). -This section is about _creating_ re-usable modules that other configurations -can include using `module` blocks. - -## Module structure - -Re-usable modules are defined using all of the same -[configuration language](/terraform/language) concepts we use in root modules. -Most commonly, modules use: - -* [Input variables](/terraform/language/values/variables) to accept values from - the calling module. -* [Output values](/terraform/language/values/outputs) to return results to the - calling module, which it can then use to populate arguments elsewhere. -* [Resources](/terraform/language/resources) to define one or more - infrastructure objects that the module will manage. - -To define a module, create a new directory for it and place one or more `.tf` -files inside just as you would do for a root module. Terraform can load modules -either from local relative paths or from remote repositories; if a module will -be re-used by lots of configurations you may wish to place it in its own -version control repository. - -Modules can also call other modules using a `module` block, but we recommend -keeping the module tree relatively flat and using [module composition](/terraform/language/modules/develop/composition) -as an alternative to a deeply-nested tree of modules, because this makes -the individual modules easier to re-use in different combinations. - -## When to write a module - -In principle any combination of resources and other constructs can be factored -out into a module, but over-using modules can make your overall Terraform -configuration harder to understand and maintain, so we recommend moderation. - -A good module should raise the level of abstraction by describing a new concept -in your architecture that is constructed from resource types offered by -providers. - -For example, `aws_instance` and `aws_elb` are both resource types belonging to -the AWS provider. You might use a module to represent the higher-level concept -"[HashiCorp Consul](https://www.consul.io/) cluster running in AWS" which -happens to be constructed from these and other AWS provider resources. - -We _do not_ recommend writing modules that are just thin wrappers around single -other resource types. If you have trouble finding a name for your module that -isn't the same as the main resource type inside it, that may be a sign that -your module is not creating any new abstraction and so the module is -adding unnecessary complexity. Just use the resource type directly in the -calling module instead. - -### No-Code Provisioning in HCP Terraform - -You can also create no-code ready modules to enable the no-code provisioning workflow in HCP Terraform. No-code provisioning lets users deploy a module's resources in HCP Terraform without writing any Terraform configuration. - -No-code ready modules have additional requirements and considerations. Refer to [Designing No-Code Ready Modules](/terraform/cloud-docs/no-code-provisioning/module-design) in the HCP Terraform documentation for details. - -## Refactoring module resources - -You can include [refactoring blocks](/terraform/language/modules/develop/refactoring) to record how resource -names and module structure have changed from previous module versions. -Terraform uses that information during planning to reinterpret existing objects -as if they had been created at the corresponding new addresses, eliminating a -separate workflow step to replace or migrate existing objects. diff --git a/website/docs/language/modules/develop/providers.mdx b/website/docs/language/modules/develop/providers.mdx deleted file mode 100644 index 38a9a0a872..0000000000 --- a/website/docs/language/modules/develop/providers.mdx +++ /dev/null @@ -1,369 +0,0 @@ ---- -page_title: Providers Within Modules - Configuration Language -description: >- - Use providers within Terraform modules. Learn about version constraints, aliases, implicit inheritance, and passing providers to Terraform 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Providers Within Modules - -[inpage-providers]: #providers-within-modules - -In a configuration with multiple modules, there are some special considerations -for how resources are associated with provider configurations. - -Each resource in the configuration must be associated with one provider -configuration. Provider configurations, unlike most other concepts in -Terraform, are global to an entire Terraform configuration and can be shared -across module boundaries. Provider configurations can be defined only in a -root Terraform module. - -Providers can be passed down to descendant modules in two ways: either -_implicitly_ through inheritance, or _explicitly_ via the `providers` argument -within a `module` block. These two options are discussed in more detail in the -following sections. - -A module intended to be called by one or more other modules must not contain -any `provider` blocks. A module containing its own provider configurations is -not compatible with the `for_each`, `count`, and `depends_on` arguments that -were introduced in Terraform v0.13. For more information, see -[Legacy Shared Modules with Provider Configurations](#legacy-shared-modules-with-provider-configurations). - -Provider configurations are used for all operations on associated resources, -including destroying remote objects and refreshing state. Terraform retains, as -part of its state, a reference to the provider configuration that was most -recently used to apply changes to each resource. When a `resource` block is -removed from the configuration, this record in the state will be used to locate -the appropriate configuration because the resource's `provider` argument -(if any) will no longer be present in the configuration. - -As a consequence, you must ensure that all resources that belong to a -particular provider configuration are destroyed before you can remove that -provider configuration's block from your configuration. If Terraform finds -a resource instance tracked in the state whose provider configuration block is -no longer available then it will return an error during planning, prompting you -to reintroduce the provider configuration. - -## Provider Version Constraints in Modules - -Although provider _configurations_ are shared between modules, each module must -declare its own [provider requirements](/terraform/language/providers/requirements), so that -Terraform can ensure that there is a single version of the provider that is -compatible with all modules in the configuration and to specify the -[source address](/terraform/language/providers/requirements#source-addresses) that serves as -the global (module-agnostic) identifier for a provider. - -To declare that a module requires particular versions of a specific provider, -use a `required_providers` block inside a `terraform` block: - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 2.7.0" - } - } -} -``` - -A provider requirement says, for example, "This module requires version v2.7.0 -of the provider `hashicorp/aws` and will refer to it as `aws`." It doesn't, -however, specify any of the configuration settings that determine what remote -endpoints the provider will access, such as an AWS region; configuration -settings come from provider _configurations_, and a particular overall Terraform -configuration can potentially have -[several different configurations for the same provider](/terraform/language/providers/configuration#alias-multiple-provider-configurations). - -## Provider Aliases Within Modules - -To declare multiple configuration names for a provider within a module, add the -`configuration_aliases` argument: - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 2.7.0" - configuration_aliases = [ aws.alternate ] - } - } -} -``` - -The above requirements are identical to the previous, with the addition of the -alias provider configuration name `aws.alternate`, which can be referenced by -resources using the `provider` argument. - -If you are writing a shared Terraform module, constrain only the minimum -required provider version using a `>=` constraint. This should specify the -minimum version containing the features your module relies on, and thus allow a -user of your module to potentially select a newer provider version if other -features are needed by other parts of their overall configuration. - -## Implicit Provider Inheritance - -For convenience in simple configurations, a child module automatically inherits -[default provider configurations](/terraform/language/providers/configuration#default-provider-configurations) from its parent. This means that -explicit `provider` blocks appear only in the root module, and downstream -modules can simply declare resources for that provider and have them -automatically associated with the root provider configurations. - -For example, the root module might contain only a `provider` block and a -`module` block to instantiate a child module: - -```hcl -provider "aws" { - region = "us-west-1" -} - -module "child" { - source = "./child" -} -``` - -The child module can then use any resource from this provider with no further -provider configuration required: - -```hcl -resource "aws_s3_bucket" "example" { - bucket = "provider-inherit-example" -} -``` - -We recommend using this approach when a single configuration for each provider -is sufficient for an entire configuration. - -~> **Note:** Only provider configurations are inherited by child modules, not provider source or version requirements. Each module must [declare its own provider requirements](/terraform/language/providers/requirements). This is especially important for non-HashiCorp providers. - -In more complex situations there may be -[multiple provider configurations](/terraform/language/providers/configuration#alias-multiple-provider-configurations), -or a child module may need to use different provider settings than -its parent. For such situations, you must pass providers explicitly. - -## Passing Providers Explicitly - -When child modules each need a different configuration of a particular -provider, or where the child module requires a different provider configuration -than its parent, you can use the `providers` argument within a `module` block -to explicitly define which provider configurations are available to the -child module. For example: - -```hcl -# The default "aws" configuration is used for AWS resources in the root -# module where no explicit provider instance is selected. -provider "aws" { - region = "us-west-1" -} - -# An alternate configuration is also defined for a different -# region, using the alias "usw2". -provider "aws" { - alias = "usw2" - region = "us-west-2" -} - -# An example child module is instantiated with the alternate configuration, -# so any AWS resources it defines will use the us-west-2 region. -module "example" { - source = "./example" - providers = { - aws = aws.usw2 - } -} -``` - -The `providers` argument within a `module` block is similar to -[the `provider` argument](/terraform/language/meta-arguments/resource-provider) -within a resource, but is a map rather than a single string because a module may -contain resources from many different providers. - -The keys of the `providers` map are provider configuration names as expected by -the child module, and the values are the names of corresponding configurations -in the _current_ module. - -Modules implicitly inherit default providers. Setting a `providers` argument within a `module` block overrides the default inheritance behavior for that provider. - -Additional provider configurations (those with the `alias` argument set) are -_never_ inherited automatically by child modules, and so must always be passed -explicitly using the `providers` map. For example, a module -that configures connectivity between networks in two AWS regions is likely -to need both a source and a destination region. In that case, the root module -may look something like this: - -```hcl -provider "aws" { - alias = "usw1" - region = "us-west-1" -} - -provider "aws" { - alias = "usw2" - region = "us-west-2" -} - -module "tunnel" { - source = "./tunnel" - providers = { - aws.src = aws.usw1 - aws.dst = aws.usw2 - } -} -``` - -The subdirectory `./tunnel` must then declare the configuration aliases for the -provider so the calling module can pass configurations with these names in its `providers` argument: - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = ">= 2.7.0" - configuration_aliases = [ aws.src, aws.dst ] - } - } -} -``` - -Each resource should then have its own `provider` attribute set to either -`aws.src` or `aws.dst` to choose which of the two provider configurations to -use. - -## Legacy Shared Modules with Provider Configurations - -In Terraform v0.10 and earlier there was no explicit way to use different -configurations of a provider in different modules in the same configuration, -and so module authors commonly worked around this by writing `provider` blocks -directly inside their modules, making the module have its own separate -provider configurations separate from those declared in the root module. - -However, that pattern had a significant drawback: because a provider -configuration is required to destroy the remote object associated with a -resource instance as well as to create or update it, a provider configuration -must always stay present in the overall Terraform configuration for longer -than all of the resources it manages. If a particular module includes -both resources and the provider configurations for those resources then -removing the module from its caller would violate that constraint: both the -resources and their associated providers would, in effect, be removed -simultaneously. - -Terraform v0.11 introduced the mechanisms described in earlier sections to -allow passing provider configurations between modules in a structured way, and -thus we explicitly recommended against writing a child module with its own -provider configuration blocks. However, that legacy pattern continued to work -for compatibility purposes -- though with the same drawback -- until Terraform -v0.13. - -Terraform v0.13 introduced the possibility for a module itself to use the -`for_each`, `count`, and `depends_on` arguments, but the implementation of -those unfortunately conflicted with the support for the legacy pattern. - -To retain the backward compatibility as much as possible, Terraform v0.13 -continues to support the legacy pattern for module blocks that do not use these -new features, but a module with its own provider configurations is not -compatible with `for_each`, `count`, or `depends_on`. Terraform will produce an -error if you attempt to combine these features. For example: - -``` -Error: Module does not support count - - on main.tf line 15, in module "child": - 15: count = 2 - -Module "child" cannot be used with count because it contains a nested provider -configuration for "aws", at child/main.tf:2,10-15. - -This module can be made compatible with count by changing it to receive all of -its provider configurations from the calling module, by using the "providers" -argument in the calling module block. -``` - -To make a module compatible with the new features, you must remove all of the -`provider` blocks from its definition. - -If the new version of the module declares `configuration_aliases`, or if the -calling module needs the child module to use different provider configurations -than its own default provider configurations, the calling module must then -include an explicit `providers` argument to describe which provider -configurations the child module will use: - -```hcl -provider "aws" { - region = "us-west-1" -} - -provider "aws" { - region = "us-east-1" - alias = "east" -} - -module "child" { - count = 2 - providers = { - # By default, the child module would use the - # default (unaliased) AWS provider configuration - # using us-west-1, but this will override it - # to use the additional "east" configuration - # for its resources instead. - aws = aws.east - } -} -``` - -Since the association between resources and provider configurations is -static, module calls using `for_each` or `count` cannot pass different -provider configurations to different instances. If you need different -instances of your module to use different provider configurations then you -must use a separate `module` block for each distinct set of provider -configurations: - -```hcl -provider "aws" { - alias = "usw1" - region = "us-west-1" -} - -provider "aws" { - alias = "usw2" - region = "us-west-2" -} - -provider "google" { - alias = "usw1" - credentials = file("account.json") - project = "my-project-id" - region = "us-west1" - zone = "us-west1-a" -} - -provider "google" { - alias = "usw2" - credentials = file("account.json") - project = "my-project-id" - region = "us-west2" - zone = "us-west2-a" -} - -module "bucket_w1" { - source = "./publish_bucket" - providers = { - aws.src = aws.usw1 - google.src = google.usw1 - } -} - -module "bucket_w2" { - source = "./publish_bucket" - providers = { - aws.src = aws.usw2 - google.src = google.usw2 - } -} -``` diff --git a/website/docs/language/modules/develop/publish.mdx b/website/docs/language/modules/develop/publish.mdx deleted file mode 100644 index df79c620bd..0000000000 --- a/website/docs/language/modules/develop/publish.mdx +++ /dev/null @@ -1,47 +0,0 @@ ---- -page_title: Publishing Modules -description: A module is a container for multiple resources that are used together. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Publishing Modules - -If you've built a module that you intend to be reused, we recommend -[publishing the module](/terraform/registry/modules/publish) on the -[Terraform Registry](https://registry.terraform.io). This will version -your module, generate documentation, and more. - -Published modules can be easily consumed by Terraform, and users can -[constrain module versions](/terraform/language/modules/syntax#version) -for safe and predictable updates. The following example shows how a caller -might use a module from the Terraform Registry: - -```hcl -module "consul" { - source = "hashicorp/consul/aws" -} -``` - -If you do not wish to publish your modules in the public registry, you can -instead use a [private registry](/terraform/registry/private) to get -the same benefits. - -We welcome contributions of Terraform modules from our community members, partners, and customers. Our ecosystem is made richer by each new module created or an existing one updated, as they reflect the wide range of experience and technical requirements of the community that uses them. Our cloud provider partners often seek to develop specific modules for popular or challenging use cases on their platform and utilize them as valuable learning experiences to empathize with their users. Similarly, our community module developers incorporate a variety of opinions and use cases from the broader Terraform community. Both types of modules have their place in the Terraform registry, accessible to practitioners who can decide which modules best fit their requirements. - -## Distribution via other sources - -Although the registry is the native mechanism for distributing re-usable -modules, Terraform can also install modules from -[various other sources](/terraform/language/modules/sources). The alternative sources -do not support the first-class versioning mechanism, but some sources have -their own mechanisms for selecting particular VCS commits, etc. - -We recommend that modules distributed via other protocols still use the -[standard module structure](/terraform/language/modules/develop/structure) so that they can -be used in a similar way as a registry module or be published on the registry -at a later time. diff --git a/website/docs/language/modules/develop/refactoring.mdx b/website/docs/language/modules/develop/refactoring.mdx deleted file mode 100644 index 7c57785d91..0000000000 --- a/website/docs/language/modules/develop/refactoring.mdx +++ /dev/null @@ -1,456 +0,0 @@ ---- -page_title: Refactoring -description: How to make backward-compatible changes to modules already in use. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Refactoring - --> **Note:** Explicit refactoring declarations with `moved` blocks is available in Terraform v1.1 and later. For earlier Terraform versions or for refactoring actions too complex to express as `moved` blocks, you can -use the [`terraform state mv` CLI command](/terraform/cli/commands/state/mv) -as a separate step. - -In shared modules and long-lived configurations, you may eventually outgrow -your initial module structure and resource names. For example, you might decide -that what was previously one child module makes more sense as two separate -modules and move a subset of the existing resources to the new one. - -Terraform compares previous state with new configuration, correlating by -each module or resource's unique address. Therefore _by default_ Terraform -understands moving or renaming an object as an intent to destroy the object -at the old address and to create a new object at the new address. - -When you add `moved` blocks in your configuration to record where you've -historically moved or renamed an object, Terraform treats an existing object at -the old address as if it now belongs to the new address. - -> **Hands On:** Try the [Use Configuration to Move Resources](/terraform/tutorials/configuration-language/move-config) tutorial. - -## `moved` Block Syntax - -A `moved` block expects no labels and contains only `from` and `to` arguments: - -```hcl -moved { - from = aws_instance.a - to = aws_instance.b -} -``` - -The example above records that the resource currently known as `aws_instance.b` -was known as `aws_instance.a` in a previous version of this module. - -Before creating a new plan for `aws_instance.b`, Terraform first checks -whether there is an existing object for `aws_instance.a` recorded in the state. -If there is an existing object, Terraform renames that object to -`aws_instance.b` and then proceeds with creating a plan. The resulting plan is -as if the object had originally been created at `aws_instance.b`, avoiding any -need to destroy it during apply. - -The `from` and `to` addresses both use a special addressing syntax that allows -selecting modules, resources, and resources inside child modules. Below, we -describe several refactoring use-cases and the appropriate addressing syntax -for each situation. - -* [Renaming a Resource](#renaming-a-resource) -* [Enabling `count` or `for_each` For a Resource](#enabling-count-or-for_each-for-a-resource) -* [Renaming a Module Call](#renaming-a-module-call) -* [Enabling `count` or `for_each` For a Module Call](#enabling-count-or-for_each-for-a-module-call) -* [Splitting One Module into Multiple](#splitting-one-module-into-multiple) -* [Removing `moved` blocks](#removing-moved-blocks) - -## Renaming a Resource - -Consider this example module with a resource configuration: - -```hcl -resource "aws_instance" "a" { - count = 2 - - # (resource-type-specific configuration) -} -``` - -Applying this configuration for the first time would cause Terraform to -create `aws_instance.a[0]` and `aws_instance.a[1]`. - -If you later choose a different name for this resource, then you can change the -name label in the `resource` block and record the old name inside a `moved` block: - -```hcl -resource "aws_instance" "b" { - count = 2 - - # (resource-type-specific configuration) -} - -moved { - from = aws_instance.a - to = aws_instance.b -} -``` - -When creating the next plan for each configuration using this module, Terraform -treats any existing objects belonging to `aws_instance.a` as if they had -been created for `aws_instance.b`: `aws_instance.a[0]` will be treated as -`aws_instance.b[0]`, and `aws_instance.a[1]` as `aws_instance.b[1]`. - -New instances of the module, which _never_ had an -`aws_instance.a`, will ignore the `moved` block and propose to create -`aws_instance.b[0]` and `aws_instance.b[1]` as normal. - -Both of the addresses in this example referred to a resource as a whole, and -so Terraform recognizes the move for all instances of the resource. That is, -it covers both `aws_instance.a[0]` and `aws_instance.a[1]` without the need -to identify each one separately. - -Each resource type has a separate schema so objects of different types -are not typically compatible. You can always use the `moved` block to change -the name of a resource, but some providers also let you change an object from -one resource type to another. Refer to the provider documentation for details -on which resources can move between types. You _cannot_ use the `moved` -block to change a managed resource (a `resource` block) into a data -resource (a `data` block). - -## Enabling `count` or `for_each` For a Resource - -Consider this example module containing a single-instance resource: - -```hcl -resource "aws_instance" "a" { - # (resource-type-specific configuration) -} -``` - -Applying this configuration would lead to Terraform creating an object -bound to the address `aws_instance.a`. - -Later, you use [`for_each`](/terraform/language/meta-arguments/for_each) with this -resource to systematically declare multiple instances. To preserve an object -that was previously associated with `aws_instance.a` alone, you must add a -`moved` block to specify which instance key the object will take in the new -configuration: - -```hcl -locals { - instances = tomap({ - big = { - instance_type = "m3.large" - } - small = { - instance_type = "t2.medium" - } - }) -} - -resource "aws_instance" "a" { - for_each = local.instances - - instance_type = each.value.instance_type - # (other resource-type-specific configuration) -} - -moved { - from = aws_instance.a - to = aws_instance.a["small"] -} -``` - -The above will keep Terraform from planning to destroy any existing object at -`aws_instance.a`, treating that object instead as if it were originally -created as `aws_instance.a["small"]`. - -When at least one of the two addresses includes an instance key, like -`["small"]` in the above example, Terraform understands both addresses as -referring to specific _instances_ of a resource rather than the resource as a -whole. That means you can use `moved` to switch between keys and to add and -remove keys as you switch between `count`, `for_each`, or neither. - -The following are some other examples of valid `moved` blocks that record -changes to resource instance keys in a similar way: - -```hcl -# Both old and new configuration used "for_each", but the -# "small" element was renamed to "tiny". -moved { - from = aws_instance.b["small"] - to = aws_instance.b["tiny"] -} - -# The old configuration used "count" and the new configuration -# uses "for_each", with the following mappings from -# index to key: -moved { - from = aws_instance.c[0] - to = aws_instance.c["small"] -} -moved { - from = aws_instance.c[1] - to = aws_instance.c["tiny"] -} - -# The old configuration used "count", and the new configuration -# uses neither "count" nor "for_each", and you want to keep -# only the object at index 2. -moved { - from = aws_instance.d[2] - to = aws_instance.d -} -``` - --> **Note:** When you add `count` to an existing resource that didn't use it, -Terraform automatically proposes to move the original object to instance zero, -unless you write an `moved` block explicitly mentioning that resource. -However, we recommend still writing out the corresponding `moved` block -explicitly, to make the change clearer to future readers of the module. - -## Renaming a Module Call - -You can rename a call to a module in a similar way as renaming a resource. -Consider the following original module version: - -```hcl -module "a" { - source = "../modules/example" - - # (module arguments) -} -``` - -When applying this configuration, Terraform would prefix the addresses for -any resources declared in this module with the module path `module.a`. -For example, a resource `aws_instance.example` would have the full address -`module.a.aws_instance.example`. - -If you later choose a better name for this module call, then you can change the -name label in the `module` block and record the old name inside a `moved` block: - -```hcl -module "b" { - source = "../modules/example" - - # (module arguments) -} - -moved { - from = module.a - to = module.b -} -``` - -When creating the next plan for each configuration using this module, Terraform -will treat any existing object addresses beginning with `module.a` as if -they had instead been created in `module.b`. `module.a.aws_instance.example` -would be treated as `module.b.aws_instance.example`. - -Both of the addresses in this example referred to a module call as a whole, and -so Terraform recognizes the move for all instances of the call. If this -module call used `count` or `for_each` then it would apply to all of the -instances, without the need to specify each one separately. - -## Enabling `count` or `for_each` For a Module Call - -Consider this example of a single-instance module: - -```hcl -module "a" { - source = "../modules/example" - - # (module arguments) -} -``` - -Applying this configuration would cause Terraform to create objects whose -addresses begin with `module.a`. - -In later module versions, you may need to use -[`count`](/terraform/language/meta-arguments/count) with this resource to systematically -declare multiple instances. To preserve an object that was previously associated -with `aws_instance.a` alone, you can add a `moved` block to specify which -instance key that object will take in the new configuration: - -```hcl -module "a" { - source = "../modules/example" - count = 3 - - # (module arguments) -} - -moved { - from = module.a - to = module.a[2] -} -``` - -The configuration above directs Terraform to treat all objects in `module.a` as -if they were originally created in `module.a[2]`. As a result, Terraform plans -to create new objects only for `module.a[0]` and `module.a[1]`. - -When at least one of the two addresses includes an instance key, like -`[2]` in the above example, Terraform will understand both addresses as -referring to specific _instances_ of a module call rather than the module -call as a whole. That means you can use `moved` to switch between keys and to -add and remove keys as you switch between `count`, `for_each`, or neither. - -For more examples of recording moves associated with instances, refer to -the similar section -[Enabling `count` and `for_each` For a Resource](#enabling-count-or-for_each-for-a-resource). - -# Splitting One Module into Multiple - -As a module grows to support new requirements, it might eventually grow big -enough to warrant splitting into two separate modules. - -Consider this example module: - -```hcl -resource "aws_instance" "a" { - # (other resource-type-specific configuration) -} - -resource "aws_instance" "b" { - # (other resource-type-specific configuration) -} - -resource "aws_instance" "c" { - # (other resource-type-specific configuration) -} -``` - -You can split this into two modules as follows: - -* `aws_instance.a` now belongs to module "x". -* `aws_instance.b` also belongs to module "x". -* `aws_instance.c` belongs module "y". - -To achieve this refactoring without replacing existing objects bound to the -old resource addresses, you must: - -1. Write module "x", copying over the two resources it should contain. -1. Write module "y", copying over the one resource it should contain. -1. Edit the original module to no longer include any of these resources, and - instead to contain only shim configuration to migrate existing users. - -The new modules "x" and "y" should contain only `resource` blocks: - -```hcl -# module "x" - -resource "aws_instance" "a" { - # (other resource-type-specific configuration) -} - -resource "aws_instance" "b" { - # (other resource-type-specific configuration) -} -``` - -```hcl -# module "y" - -resource "aws_instance" "c" { - # (other resource-type-specific configuration) -} -``` - -The original module, now only a shim for backward-compatibility, calls the -two new modules and indicates that the resources moved into them: - -```hcl -module "x" { - source = "../modules/x" - - # ... -} - -module "y" { - source = "../modules/y" - - # ... -} - -moved { - from = aws_instance.a - to = module.x.aws_instance.a -} - -moved { - from = aws_instance.b - to = module.x.aws_instance.b -} - -moved { - from = aws_instance.c - to = module.y.aws_instance.c -} -``` - -When an existing user of the original module upgrades to the new "shim" -version, Terraform notices these three `moved` blocks and behaves -as if the objects associated with the three old resource addresses were -originally created inside the two new modules. - -New users of this family of modules may use either the combined shim module -_or_ the two new modules separately. You may wish to communicate to your -existing users that the old module is now deprecated and so they should use -the two separate modules for any new needs. - -The multi-module refactoring situation is unusual in that it violates the -typical rule that a parent module sees its child module as a "closed box", -unaware of exactly which resources are declared inside it. This compromise -assumes that all three of these modules are maintained by the same people -and distributed together in a single -[module package](/terraform/language/modules/sources#modules-in-package-sub-directories). - -Terraform resolves module references in `moved` blocks relative to the module -instance they are defined in. For example, if the original module above were -already a child module named `module.original`, the reference to -`module.x.aws_instance.a` would resolve as -`module.original.module.x.aws_instance.a`. A module may only make `moved` -statements about its own objects and objects of its child modules. - -If you need to refer to resources within a module that was called using -`count` or `for_each` meta-arguments, you must specify a specific instance -key to use in order to match with the new location of the resource -configuration: - -```hcl -moved { - from = aws_instance.example - to = module.new[2].aws_instance.example -} -``` - -## Removing `moved` Blocks - -Over time, a long-lasting module may accumulate many `moved` blocks. - -Removing a `moved` block is a generally breaking change because any configurations that refer to the old address will plan to delete that existing object instead of move it. We strongly recommend that you retain all historical `moved` blocks from earlier versions of your modules to preserve the upgrade path for users of any previous version. - -If you do decide to remove `moved` blocks, proceed with caution. It can be safe to remove `moved` blocks when you are maintaining private modules within an organization and you are certain that all users have successfully run `terraform apply` with your new module version. - -If you need to rename or move the same object twice, we recommend documenting the full history -using _chained_ `moved` blocks, where the new block refers to the existing block: - -```hcl -moved { - from = aws_instance.a - to = aws_instance.b -} - -moved { - from = aws_instance.b - to = aws_instance.c -} -``` - -Recording a sequence of moves in this way allows for successful upgrades for -both configurations with objects at `aws_instance.a` _and_ configurations with -objects at `aws_instance.b`. In both cases, Terraform treats the existing -object as if it had been originally created as `aws_instance.c`. diff --git a/website/docs/language/modules/develop/structure.mdx b/website/docs/language/modules/develop/structure.mdx deleted file mode 100644 index b87aa19d09..0000000000 --- a/website/docs/language/modules/develop/structure.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -page_title: Standard Module Structure -description: >- - Learn about the recommended file and directory structure for developing reusable modules distributed as separate repositories. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Standard Module Structure - -The standard module structure is a file and directory layout we recommend for -reusable modules distributed in separate repositories. Terraform tooling is -built to understand the standard module structure and use that structure to -generate documentation, index modules for the module registry, and more. - -The standard module structure expects the layout documented below. The list may -appear long, but everything is optional except for the root module. Most modules -don't need to do any extra work to follow the standard structure. - -* **Root module**. This is the **only required element** for the standard - module structure. Terraform files must exist in the root directory of - the repository. This should be the primary entrypoint for the module and is - expected to be opinionated. For the - [Consul module](https://registry.terraform.io/modules/hashicorp/consul) - the root module sets up a complete Consul cluster. It makes a lot of assumptions - however, and we expect that advanced users will use specific _nested modules_ - to more carefully control what they want. - -* **README**. The root module and any nested modules should have README - files. This file should be named `README` or `README.md`. The latter will - be treated as markdown. There should be a description of the module and - what it should be used for. If you want to include an example for how this - module can be used in combination with other resources, put it in an [examples - directory like this](https://github.com/hashicorp/terraform-aws-consul/tree/master/examples). - Consider including a visual diagram depicting the infrastructure resources - the module may create and their relationship. - - The README doesn't need to document inputs or outputs of the module because - tooling will automatically generate this. If you are linking to a file or - embedding an image contained in the repository itself, use a commit-specific - absolute URL so the link won't point to the wrong version of a resource in the - future. - -* **LICENSE**. The license under which this module is available. If you are - publishing a module publicly, many organizations will not adopt a module - unless a clear license is present. We recommend always having a license - file, even if it is not an open source license. - -* **`main.tf`, `variables.tf`, `outputs.tf`**. These are the recommended filenames for - a minimal module, even if they're empty. `main.tf` should be the primary - entrypoint. For a simple module, this may be where all the resources are - created. For a complex module, resource creation may be split into multiple - files but any nested module calls should be in the main file. `variables.tf` - and `outputs.tf` should contain the declarations for variables and outputs, - respectively. - -* **Variables and outputs should have descriptions.** All variables and - outputs should have one or two sentence descriptions that explain their - purpose. This is used for documentation. See the documentation for - [variable configuration](/terraform/language/values/variables) and - [output configuration](/terraform/language/values/outputs) for more details. - -* **Nested modules**. Nested modules should exist under the `modules/` - subdirectory. Any nested module with a `README.md` is considered usable - by an external user. If a README doesn't exist, it is considered for internal - use only. These are purely advisory; Terraform will not actively deny usage - of internal modules. Nested modules should be used to split complex behavior - into multiple small modules that advanced users can carefully pick and - choose. For example, the - [Consul module](https://registry.terraform.io/modules/hashicorp/consul) - has a nested module for creating the Cluster that is separate from the - module to setup necessary IAM policies. This allows a user to bring in their - own IAM policy choices. - - If the root module includes calls to nested modules, they should use relative - paths like `./modules/consul-cluster` so that Terraform will consider them - to be part of the same repository or package, rather than downloading them - again separately. - - If a repository or package contains multiple nested modules, they should - ideally be [composable](/terraform/language/modules/develop/composition) by the caller, rather than - calling directly to each other and creating a deeply-nested tree of modules. - -* **Examples**. Examples of using the module should exist under the - `examples/` subdirectory at the root of the repository. Each example may have - a README to explain the goal and usage of the example. Examples for - submodules should also be placed in the root `examples/` directory. - - Because examples will often be copied into other repositories for - customization, any `module` blocks should have their `source` set to the - address an external caller would use, not to a relative path. - -A minimal recommended module following the standard structure is shown below. -While the root module is the only required element, we recommend the structure -below as the minimum: - -```sh -$ tree minimal-module/ -. -├── README.md -├── main.tf -├── variables.tf -├── outputs.tf -``` - -A complete example of a module following the standard structure is shown below. -This example includes all optional elements and is therefore the most -complex a module can become: - -```sh -$ tree complete-module/ -. -├── README.md -├── main.tf -├── variables.tf -├── outputs.tf -├── ... -├── modules/ -│   ├── nestedA/ -│   │   ├── README.md -│   │   ├── variables.tf -│   │   ├── main.tf -│   │   ├── outputs.tf -│   ├── nestedB/ -│   ├── .../ -├── examples/ -│   ├── exampleA/ -│   │   ├── main.tf -│   ├── exampleB/ -│   ├── .../ -``` diff --git a/website/docs/language/modules/index.mdx b/website/docs/language/modules/index.mdx deleted file mode 100644 index 6b72ae3e9e..0000000000 --- a/website/docs/language/modules/index.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -page_title: Modules Overview - Configuration Language -description: >- - Modules are containers for multiple resources that are used together in a - configuration. Find resources for using, developing, and publishing 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Modules - -> **Hands-on:** Try the [Reuse Configuration with Modules](/terraform/tutorials/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. - -_Modules_ are containers for multiple resources that are used together. A module -consists of a collection of `.tf` and/or `.tf.json` files kept together in a -directory. - -Modules are the main way to package and reuse resource configurations with -Terraform. - -## The Root Module - -Every Terraform configuration has at least one module, known as its -_root module_, which consists of the resources defined in the `.tf` files in -the main working directory. - -## Child Modules - -A Terraform module (usually the root module of a configuration) can _call_ other -modules to include their resources into the configuration. A module that has -been called by another module is often referred to as a _child module._ - -Child modules can be called multiple times within the same configuration, and -multiple configurations can use the same child module. - -## Published Modules - -In addition to modules from the local filesystem, Terraform can load modules -from a public or private registry. This makes it possible to publish modules for -others to use, and to use modules that others have published. - -The [Terraform Registry](https://registry.terraform.io/browse/modules) hosts a -broad collection of publicly available Terraform modules for configuring many -kinds of common infrastructure. These modules are free to use, and Terraform can -download them automatically if you specify the appropriate source and version in -a module call block. - -Also, members of your organization might produce modules specifically crafted -for your own infrastructure needs. [HCP Terraform](https://cloud.hashicorp.com/products/terraform) and -[Terraform Enterprise](/terraform/enterprise) both include a private -module registry for sharing modules internally within your organization. - -## Using Modules - -- [Module Blocks](/terraform/language/modules/syntax) documents the syntax for - calling a child module from a parent module, including meta-arguments like - `for_each`. - -- [Module Sources](/terraform/language/modules/sources) documents what kinds of paths, - addresses, and URIs can be used in the `source` argument of a module block. - -- The Meta-Arguments section documents special arguments that can be used with - every module, including - [`providers`](/terraform/language/meta-arguments/module-providers), - [`depends_on`](/terraform/language/meta-arguments/depends_on), - [`count`](/terraform/language/meta-arguments/count), - and [`for_each`](/terraform/language/meta-arguments/for_each). - -## Developing Modules - -For information about developing reusable modules, see -[Module Development](/terraform/language/modules/develop). diff --git a/website/docs/language/modules/sources.mdx b/website/docs/language/modules/sources.mdx deleted file mode 100644 index 4047c94955..0000000000 --- a/website/docs/language/modules/sources.mdx +++ /dev/null @@ -1,489 +0,0 @@ ---- -page_title: Module Sources -description: >- - The source argument tells Terraform where to find child modules's - configurations in locations like GitHub, the Terraform Registry, Bitbucket, - Git, Mercurial, S3, and GCS. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Sources - -The `source` argument in [a `module` block](/terraform/language/modules/syntax) -tells Terraform where to find the source code for the desired child module. - -Terraform uses this during the module installation step of `terraform init` -to download the source code to a directory on local disk so that other Terraform commands can use it. - -> **Hands-on:** Try the [Use Modules From the Registry](/terraform/tutorials/modules/module-use) or [Build and Use a Local Module](/terraform/tutorials/modules/module-create) tutorials. - -The module installer supports installation from a number of different source -types. - -- [Local paths](#local-paths) - -- [Terraform Registry](#terraform-registry) - -- [GitHub](#github) - -- [Bitbucket](#bitbucket) - -- Generic [Git](#generic-git-repository), [Mercurial](#generic-mercurial-repository) repositories - -- [HTTP URLs](#http-urls) - -- [S3 buckets](#s3-bucket) - -- [GCS buckets](#gcs-bucket) - -- [Modules in Package Sub-directories](#modules-in-package-sub-directories) - -Each of these is described in the following sections. Module source addresses -use a _URL-like_ syntax, but with extensions to support unambiguous selection -of sources and additional features. - -We recommend using local file paths for closely-related modules used primarily -for the purpose of factoring out repeated code elements, and using a native -Terraform module registry for modules intended to be shared by multiple calling -configurations. We support other sources so that you can potentially distribute -Terraform modules internally with existing infrastructure. - -Many of the source types will make use of "ambient" credentials available -when Terraform is run, such as from environment variables or credentials files -in your home directory. This is covered in more detail in each of the following -sections. - -We recommend placing each module that is intended to be re-usable in the root -of its own repository or archive file, but it is also possible to -[reference modules from subdirectories](#modules-in-package-sub-directories). - -## Local Paths - -Local path references allow for factoring out portions of a configuration -within a single source repository. - -```hcl -module "consul" { - source = "./consul" -} -``` - -A local path must begin with either `./` or `../` to indicate that a local -path is intended, to distinguish from -[a module registry address](#terraform-registry). - -Local paths are special in that they are not "installed" in the same sense -that other sources are: the files are already present on local disk (possibly -as a result of installing a parent module) and so can just be used directly. -Their source code is automatically updated if the parent module is upgraded. - -Note that Terraform does not consider an _absolute_ filesystem path (starting -with a slash, a drive letter, or similar) to be a local path. Instead, -Terraform will treat that in a similar way as a remote module and copy it into -the local module cache. An absolute path is a "package" in the sense described -in [Modules in Package Sub-directories](#modules-in-package-sub-directories). -We don't recommend using absolute filesystem paths to refer to Terraform -modules, because it will tend to couple your configuration to the filesystem -layout of a particular computer. - -## Terraform Registry - -A module registry is the native way of distributing Terraform modules for use -across multiple configurations, using a Terraform-specific protocol that -has full support for module versioning. - -[Terraform Registry](https://registry.terraform.io/) is an index of modules -shared publicly using this protocol. This public registry is the easiest way -to get started with Terraform and find modules created by others in the -community. - -You can also use a -[private registry](/terraform/registry/private), either -via the built-in feature from HCP Terraform, or by running a custom -service that implements -[the module registry protocol](/terraform/registry/api-docs). - -Modules on the public Terraform Registry can be referenced using a registry -source address of the form `//`, with each -module's information page on the registry site including the exact address -to use. - -```hcl -module "consul" { - source = "hashicorp/consul/aws" - version = "0.1.0" -} -``` - -The above example will use the -[Consul module for AWS](https://registry.terraform.io/modules/hashicorp/consul/aws) -from the public registry. - -For modules hosted in other registries, prefix the source address with an -additional `/` portion, giving the hostname of the private registry: - -```hcl -module "consul" { - source = "app.terraform.io/example-corp/k8s-cluster/azurerm" - version = "1.1.0" -} -``` - -If you are using the SaaS version of HCP Terraform, its private -registry hostname is `app.terraform.io`. If you use a self-hosted Terraform -Enterprise instance, its private registry hostname is the same as the host -where you'd access the web UI and the host you'd use when configuring -the [HCP Terraform CLI integration](/terraform/cli/cloud). - -Both HCP Terraform and self-hosted Terraform Enterprise support a [generic hostname](/terraform/cloud-docs/registry/using#generic-hostname-terraform-cloud-and-terraform-enterprise) `localterraform.com`. - -Registry modules support versioning. You can provide a specific version as shown -in the above examples, or use flexible -[version constraints](/terraform/language/modules/syntax#version). - -You can learn more about the registry at the -[Terraform Registry documentation](/terraform/registry/modules/use#using-modules). - -To access modules from a private registry, you may need to configure an access -token [in the CLI config](/terraform/cli/config/config-file#credentials). Use the -same hostname as used in the module source string. For a private registry -within HCP Terraform, use the same authentication token as you would -use with the Enterprise API or command-line clients. - -## GitHub - -Terraform will recognize unprefixed `github.com` URLs and interpret them -automatically as Git repository sources. - -```hcl -module "consul" { - source = "github.com/hashicorp/example" -} -``` - -The above address scheme will clone over HTTPS. To clone over SSH, use the -following form: - -```hcl -module "consul" { - source = "git@github.com:hashicorp/example.git" -} -``` - -These GitHub schemes are treated as convenient aliases for -[the general Git repository address scheme](#generic-git-repository), and so -they obtain credentials in the same way and support the `ref` argument for -selecting a specific revision. You will need to configure credentials in -particular to access private repositories. - -## Bitbucket - -Terraform will recognize unprefixed `bitbucket.org` URLs and interpret them -automatically as BitBucket repositories: - -```hcl -module "consul" { - source = "bitbucket.org/hashicorp/terraform-consul-aws" -} -``` - -This shorthand works only for public repositories, because Terraform must -access the BitBucket API to learn if the given repository uses Git or Mercurial. - -Terraform treats the result either as [a Git source](#generic-git-repository) -or [a Mercurial source](#generic-mercurial-repository) depending on the -repository type. See the sections on each version control type for information -on how to configure credentials for private repositories and how to specify -a specific revision to install. - -## Generic Git Repository - -Arbitrary Git repositories can be used by prefixing the address with the -special `git::` prefix. After this prefix, any valid -[Git URL](https://git-scm.com/docs/git-clone#_git_urls) -can be specified to select one of the protocols supported by Git. - -For example, to use HTTPS or SSH: - -```hcl -module "vpc" { - source = "git::https://example.com/vpc.git" -} - -module "storage" { - source = "git::ssh://username@example.com/storage.git" -} -``` - -Terraform installs modules from Git repositories by running `git clone`, and -so it will respect any local Git configuration set on your system, including -credentials. To access a non-public Git repository, configure Git with -suitable credentials for that repository. - -If you use the SSH protocol then any configured SSH keys will be used -automatically. This is the most common way to access non-public Git -repositories from automated systems because it allows access to private -repositories without interactive prompts. - -If using the HTTP/HTTPS protocol, or any other protocol that uses -username/password credentials, configure -[Git Credentials Storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage) -to select a suitable source of credentials for your environment. - -If your Terraform configuration will be used within [HCP Terraform](https://www.hashicorp.com/products/terraform), -only SSH key authentication is supported, and -[keys can be configured on a per-workspace basis](/terraform/cloud-docs/workspaces/settings/ssh-keys). - -### Selecting a Revision - -By default, Terraform will clone and use the default branch (referenced by -`HEAD`) in the selected repository. You can override this using the -`ref` argument. The value of the `ref` argument can be any reference that would be accepted -by the `git checkout` command, such as branch, SHA-1 hash (short or full), or tag names. -For a full list of the possible values, see -[Git Tools - Revision Selection](https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#_single_revisions) -in [the Git Book](https://git-scm.com/book/en/v2). - -```hcl -# select a specific tag -module "vpc" { - source = "git::https://example.com/vpc.git?ref=v1.2.0" -} - -# directly select a commit using its SHA-1 hash -module "storage" { - source = "git::https://example.com/storage.git?ref=51d462976d84fdea54b47d80dcabbf680badcdb8" -} -``` - -### Shallow Clone - -For larger repositories you may prefer to make only a shallow clone in order -to reduce the time taken to retrieve the remote repository. - -The `depth` URL argument corresponds to -[the `--depth` argument to `git clone`](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt), -which instructs Git to create a shallow clone that includes -only the specified number of commits in the history. -Setting `depth` to `1` is suitable for most cases. This is because Terraform only uses the most recently selected commit to find the source. -```hcl -module "vpc" { - source = "git::https://example.com/vpc.git?depth=1&ref=v1.2.0" -} -``` - -However, because shallow clone requires different Git protocol behavior, -setting the `depth` argument makes Terraform pass your [`ref` argument](#selecting-a-revision), -if any, to -[the `--branch` argument to `git clone`](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---branchltnamegt) -instead. That means it must specify a named branch or tag known to the remote -repository, and that raw commit IDs are not acceptable. - - -### "scp-like" address syntax - -When using Git over SSH, we recommend using the `ssh://`-prefixed URL form -for consistency with all of the other URL-like git address forms. -You may opt to use the alternative "scp-like" syntax instead, in which case you -must omit the `ssh://` scheme part and include only the `git::` part. -For example: - -```hcl -module "storage" { - source = "git::username@example.com:storage.git" -} -``` - -If you use the `ssh://` URL scheme then Terraform will assume that the colon -marks the beginning of a port number, rather than the beginning of the path. -This matches how Git itself interprets these different forms, aside from -the Terraform-specific `git::` selector prefix. - -## Generic Mercurial Repository - -You can use arbitrary Mercurial repositories by prefixing the address with the -special `hg::` prefix. After this prefix, any valid -[Mercurial URL](https://www.mercurial-scm.org/repo/hg/help/urls) -can be specified to select one of the protocols supported by Mercurial. - -```hcl -module "vpc" { - source = "hg::http://example.com/vpc.hg" -} -``` - -Terraform installs modules from Mercurial repositories by running `hg clone`, and -so it will respect any local Mercurial configuration set on your system, -including credentials. To access a non-public repository, configure Mercurial -with suitable credentials for that repository. - -If you use the SSH protocol then any configured SSH keys will be used -automatically. This is the most common way to access non-public Mercurial -repositories from automated systems because it allows access to private -repositories without interactive prompts. - -If your Terraform configuration will be used within [HCP Terraform](https://www.hashicorp.com/products/terraform), -only SSH key authentication is supported, and -[keys can be configured on a per-workspace basis](/terraform/cloud-docs/workspaces/settings/ssh-keys). - -### Selecting a Revision - -You can select a non-default branch or tag using the optional `ref` argument: - -```hcl -module "vpc" { - source = "hg::http://example.com/vpc.hg?ref=v1.2.0" -} -``` - -## HTTP URLs - -When you use an HTTP or HTTPS URL, Terraform will make a `GET` request to -the given URL, which can return _another_ source address. This indirection -allows using HTTP URLs as a sort of "vanity redirect" over a more complicated -module source address. - -Terraform will append an additional query string argument `terraform-get=1` to -the given URL before sending the `GET` request, allowing the server to -optionally return a different result when Terraform is requesting it. - -If the response is successful (`200`-range status code), Terraform looks in -the following locations in order for the next address to access: - -- The value of a response header field named `X-Terraform-Get`. - -- If the response is an HTML page, a `meta` element with the name `terraform-get`: - - ```html - - ``` - -In either case, the result is interpreted as another module source address -using one of the forms documented elsewhere on this page. - -If an HTTP/HTTPS URL requires authentication credentials, use a `.netrc` -file to configure the credentials. By default, Terraform searches for the `.netrc` file -in your HOME directory. However, you can override the default filesystem location by setting the `NETRC` environment variable. For information on the `.netrc` format, -refer to [the documentation for using it in `curl`](https://everything.curl.dev/usingcurl/netrc). - -### Fetching archives over HTTP - -As a special case, if Terraform detects that the URL has a common file -extension associated with an archive file format then it will bypass the -special `terraform-get=1` redirection described above and instead just use -the contents of the referenced archive as the module source code: - -```hcl -module "vpc" { - source = "https://example.com/vpc-module.zip" -} -``` - -The extensions that Terraform recognizes for this special behavior are: - -- `zip` -- `bz2`, `tar.bz2`, `tar.tbz2`, and `tbz2` -- `gz`, `tar.gz`, and `tgz` -- `xz`, `tar.xz`, and `txz` - -If your URL _doesn't_ have one of these extensions but refers to an archive -anyway, use the `archive` argument to force this interpretation: - -```hcl -module "vpc" { - source = "https://example.com/vpc-module?archive=zip" -} -``` - --> **Note:** If the content of the archive file is a directory, you will need to -include that directory in the module source. Read the section on -[Modules in Package Sub-directories](#modules-in-package-sub-directories) for more -information. - -## S3 Bucket - -You can use archives stored in S3 as module sources using the special `s3::` -prefix, followed by -[an S3 bucket object URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html). - -```hcl -module "consul" { - source = "s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/vpc.zip" -} -``` - --> **Note:** Buckets in AWS's us-east-1 region must use the hostname `s3.amazonaws.com` (instead of `s3-us-east-1.amazonaws.com`). - -The `s3::` prefix causes Terraform to use AWS-style authentication when -accessing the given URL. As a result, this scheme may also work for other -services that mimic the S3 API, as long as they handle authentication in the -same way as AWS. - -The resulting object must be an archive with one of the same file -extensions as for [archives over standard HTTP](#fetching-archives-over-http). -Terraform will extract the archive to obtain the module source tree. - -The module installer looks for AWS credentials in the following locations, -preferring those earlier in the list when multiple are available: - -- The `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. -- The default profile in the `.aws/credentials` file in your home directory. -- If running on an EC2 instance, temporary credentials associated with the - instance's IAM Instance Profile. - -## GCS Bucket - -You can use archives stored in Google Cloud Storage as module sources using the special `gcs::` -prefix, followed by -[a GCS bucket object URL](https://cloud.google.com/storage/docs/request-endpoints#typical). - -For example - -- `gcs::https://www.googleapis.com/storage/v1/BUCKET_NAME/PATH_TO_MODULE` -- `gcs::https://www.googleapis.com/storage/v1/BUCKET_NAME/PATH/TO/module.zip` - -```hcl -module "consul" { - source = "gcs::https://www.googleapis.com/storage/v1/modules/foomodule.zip" -} -``` - -The module installer uses Google Cloud SDK to authenticate with GCS. You can -use any of the following methods to set Google Cloud Platform credentials: - -* Set the `GOOGLE_OAUTH_ACCESS_TOKEN` environment variable to a raw Google Cloud Platform OAuth access token. -* Enter the path of your service account key file in the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. -* If you're running Terraform from a GCE instance, default credentials are automatically available. See [Creating and Enabling Service Accounts](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances) for Instances for more details. -* On your computer, you can make your Google identity available by running `gcloud auth application-default login`. - -## Modules in Package Sub-directories - -When the source of a module is a version control repository or archive file -(generically, a "package"), the module itself may be in a sub-directory relative -to the root of the package. - -A special double-slash syntax `//` is interpreted by Terraform to indicate that -the remaining path after that point is a sub-directory within the package. -For example: - -- `hashicorp/consul/aws//modules/consul-cluster` -- `git::https://example.com/network.git//modules/vpc` -- `https://example.com/network-module.zip//modules/vpc` -- `s3::https://s3-eu-west-1.amazonaws.com/examplecorp-terraform-modules/network.zip//modules/vpc` - -If the source address has arguments, such as the `ref` argument supported for -the version control sources, the sub-directory portion must be _before_ those -arguments: - -- `git::https://example.com/network.git//modules/vpc?ref=v1.2.0` -- `github.com/hashicorp/example//modules/vpc?ref=v1.2.0` - -Terraform will still extract the entire package to local disk, but will read -the module from the subdirectory. As a result, it is safe for a module in -a sub-directory of a package to use [a local path](#local-paths) to another -module as long as it is in the _same_ package. diff --git a/website/docs/language/modules/syntax.mdx b/website/docs/language/modules/syntax.mdx deleted file mode 100644 index cade86ef6b..0000000000 --- a/website/docs/language/modules/syntax.mdx +++ /dev/null @@ -1,227 +0,0 @@ ---- -page_title: Modules - Configuration Language -description: >- - Modules are containers for multiple resources that are used together in - configurations. Learn how to call one module from another and access module - output. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Blocks - -> **Hands-on:** Try the [Reuse Configuration with Modules](/terraform/tutorials/modules?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials. - -A _module_ is a container for multiple resources that are used together. - -Every Terraform configuration has at least one module, known as its -_root module_, which consists of the resources defined in the `.tf` files in -the main working directory. - -A module can call other modules, which lets you include the child module's -resources into the configuration in a concise way. Modules -can also be called multiple times, either within the same configuration or -in separate configurations, allowing resource configurations to be packaged -and re-used. - -This page describes how to call one module from another. For more information -about creating re-usable child modules, see [Module Development](/terraform/language/modules/develop). - -## Calling a Child Module - -To _call_ a module means to include the contents of that module into the -configuration with specific values for its -[input variables](/terraform/language/values/variables). Modules are called -from within other modules using `module` blocks: - -```hcl -module "servers" { - source = "./app-cluster" - - servers = 5 -} -``` - -A module that includes a `module` block like this is the _calling module_ of the -child module. - -The label immediately after the `module` keyword is a local name, which the -calling module can use to refer to this instance of the module. - -Within the block body (between `{` and `}`) are the arguments for the module. -Module calls use the following kinds of arguments: - -- The `source` argument is mandatory for all modules. - -- The `version` argument is recommended for modules from a registry. - -- Most other arguments correspond to [input variables](/terraform/language/values/variables) - defined by the module. (The `servers` argument in the example above is one of - these.) - -- Terraform defines a few other meta-arguments that can be used with all - modules, including `for_each` and `depends_on`. - -### Source - -All modules **require** a `source` argument, which is a meta-argument defined by -Terraform. Its value is either the path to a local directory containing the -module's configuration files, or a remote module source that Terraform should -download and use. This value must be a literal string with no template -sequences; arbitrary expressions are not allowed. For more information on -possible values for this argument, see [Module Sources](/terraform/language/modules/sources). - -The same source address can be specified in multiple `module` blocks to create -multiple copies of the resources defined within, possibly with different -variable values. - -After adding, removing, or modifying `module` blocks, you must re-run -`terraform init` to allow Terraform the opportunity to adjust the installed -modules. By default this command will not upgrade an already-installed module; -use the `-upgrade` option to instead upgrade to the newest available version. - -### Version - -When using modules installed from a module registry, we recommend explicitly -constraining the acceptable version numbers to avoid unexpected or unwanted -changes. - -Use the `version` argument in the `module` block to specify versions: - -```shell -module "consul" { - source = "hashicorp/consul/aws" - version = "0.0.5" - - servers = 3 -} -``` - -The `version` argument accepts a [version constraint string](/terraform/language/expressions/version-constraints). -Terraform will use the newest installed version of the module that meets the -constraint; if no acceptable versions are installed, it will download the newest -version that meets the constraint. - -Version constraints are supported only for modules installed from a module -registry, such as the public [Terraform Registry](https://registry.terraform.io/) -or [HCP Terraform's private module registry](/terraform/cloud-docs/registry). -Other module sources can provide their own versioning mechanisms within the -source string itself, or might not support versions at all. In particular, -modules sourced from local file paths do not support `version`; since -they're loaded from the same source repository, they always share the same -version as their caller. - -### Meta-arguments - -Along with `source` and `version`, Terraform defines a few more -optional meta-arguments that have special meaning across all modules, -described in more detail in the following pages: - -- `count` - Creates multiple instances of a module from a single `module` block. - See [the `count` page](/terraform/language/meta-arguments/count) - for details. - -- `for_each` - Creates multiple instances of a module from a single `module` - block. See - [the `for_each` page](/terraform/language/meta-arguments/for_each) - for details. - -- `providers` - Passes provider configurations to a child module. See - [the `providers` page](/terraform/language/meta-arguments/module-providers) - for details. If not specified, the child module inherits all of the default - (un-aliased) provider configurations from the calling module. - -- `depends_on` - Creates explicit dependencies between the entire - module and the listed targets. See - [the `depends_on` page](/terraform/language/meta-arguments/depends_on) - for details. - -Terraform does not use the `lifecycle` argument. However, the `lifecycle` block is reserved for future versions. - -## Accessing Module Output Values - -The resources defined in a module are encapsulated, so the calling module -cannot access their attributes directly. However, the child module can -declare [output values](/terraform/language/values/outputs) to selectively -export certain values to be accessed by the calling module. - -For example, if the `./app-cluster` module referenced in the example above -exported an output value named `instance_ids` then the calling module -can reference that result using the expression `module.servers.instance_ids`: - -```hcl -resource "aws_elb" "example" { - # ... - - instances = module.servers.instance_ids -} -``` - -For more information about referring to named values, see -[Expressions](/terraform/language/expressions). - -## Transferring Resource State Into Modules - -Moving `resource` blocks from one module into several child modules causes -Terraform to see the new location as an entirely different resource. As a -result, Terraform plans to destroy all resource instances at the old address -and create new instances at the new address. - -To preserve existing objects, you can use -[refactoring blocks](/terraform/language/modules/develop/refactoring) to record the old and new -addresses for each resource instance. This directs Terraform to treat existing -objects at the old addresses as if they had originally been created at the -corresponding new addresses. - -## Replacing resources within a module - -You may have an object that needs to be replaced with a new object for a reason -that isn't automatically visible to Terraform, such as if a particular virtual -machine is running on degraded underlying hardware. In this case, you can use -[the `-replace=...` planning option](/terraform/cli/commands/plan#replace-address) -to force Terraform to propose replacing that object. - -If the object belongs to a resource within a nested module, specify the full -path to that resource including all of the nested module steps leading to it. -For example: - -```shellsession -$ terraform plan -replace=module.example.aws_instance.example -``` - -The above selects a `resource "aws_instance" "example"` declared inside a -`module "example"` child module declared inside your root module. - -Because replacing is a very disruptive action, Terraform only allows selecting -individual resource instances. There is no syntax to force replacing _all_ -resource instances belonging to a particular module. - -## Removing Modules - --> **Note:** The `removed` block is available in Terraform v1.7 and later. For earlier Terraform versions, you can use the [`terraform state rm` CLI command](/terraform/cli/commands/state/rm) as a separate step. - -To remove a module from Terraform, simply delete the module call from your Terraform configuration. - -By default, after you remove the `module` block, Terraform will plan to destroy any resources it is managing that were declared in that module. This is because when you remove the module call, that module's configuration is no longer included in your Terraform configuration. - -Sometimes you may wish to remove a module from your Terraform configuration without destroying the real infrastructure objects it manages. In this case, the resources will be removed from the [Terraform state](/terraform/language/state), but the real infrastructure objects will not be destroyed. - -To declare that a module was removed from Terraform configuration but that its managed objects should not be destroyed, remove the `module` block from your configuration and replace it with a `removed` block: - -```hcl -removed { - from = module.example - - lifecycle { - destroy = false - } -} -``` - -The `from` argument is the address of the module you want to remove, without any instance keys (such as "module.example[1]"). - -The `lifecycle` block is required. The `destroy` argument determines whether Terraform will attempt to destroy the objects managed by the module or not. A value of `false` means that Terraform will remove the resources from state without destroying them. diff --git a/website/docs/language/moved.mdx b/website/docs/language/moved.mdx deleted file mode 100644 index 840246e8b7..0000000000 --- a/website/docs/language/moved.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -page_title: moved block configuration reference -description: Learn about the `moved` block that you can specify in Terraform configurations. The `moved` block programmatically changes the location of a resource. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# `moved` block reference - -This topic provides reference information for the `moved` block. Use this block to programmatically change the address of a resource. Refer to [Refactoring](/terraform/language/modules/develop/refactoring) for details about how to use the `moved` block in your Terraform configurations. - -## Configuration model - -The `moved` block supports the following arguments: - -- [`moved`](#moved):   block - - [`from`](#moved):   reference | required - - [`to`](#moved):   reference | required - -## Complete configuration - -The following `moved` block defines all of the supported built-in arguments you can set: - -```hcl -moved { - from = - to = -} -``` - -## Specification - -A `moved` block supports the following configuration. - -### `moved` - -The `moved` block specifies the previous address and the new address for the resource. The following table describes the arguments you can set in the `moved` block. - -| Argument | Description | Type | Required | -| --- | --- | --- | --- | -| `from` | Specifies a resource's previous address. The syntax allows Terraform to select modules, resources, and resources inside child modules. | string | required | -| `to` | Specifies the new address to relocate the resource to. The syntax allows Terraform to select modules, resources, and resources inside child modules. | string | required | - -Before creating a new plan for the resource specified in the `to` field, Terraform checks the state for an existing object at the address specified in the `from` field. Terraform renames existing objects to the string specified in the `to` field and then creates a plan. The plan directs Terraform to provision the resource specified in the `from` field as the resource specified in the `to` field. As a result, Terraform does not destroy the resource during the Terraform run. - -## Example - -The following example moves an AWS instance from address `aws_instance.a` to `aws_instance.b`: - -```hcl -moved { - from = aws_instance.a - to = aws_instance.b -} -``` \ No newline at end of file diff --git a/website/docs/language/providers/configuration.mdx b/website/docs/language/providers/configuration.mdx deleted file mode 100644 index 5ca1d9c3f2..0000000000 --- a/website/docs/language/providers/configuration.mdx +++ /dev/null @@ -1,204 +0,0 @@ ---- -page_title: Provider Configuration - Configuration Language -description: >- - Learn how to set up providers, including how to use the alias meta-argument to - specify multiple configurations for a single provider. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Configuration - -Providers allow Terraform to interact with cloud providers, SaaS providers, and -other APIs. - -Some providers require you to configure them with endpoint URLs, cloud regions, -or other settings before Terraform can use them. This page documents how to -configure settings for providers. - -Additionally, all Terraform configurations must declare which providers they -require so that Terraform can install and use them. The -[Provider Requirements](/terraform/language/providers/requirements) -page documents how to declare providers so Terraform can install them. - -## Provider Configuration - -Provider configurations belong in the root module of a Terraform configuration. -(Child modules receive their provider configurations from the root module; for -more information, see -[The Module `providers` Meta-Argument](/terraform/language/meta-arguments/module-providers) -and [Module Development: Providers Within Modules](/terraform/language/modules/develop/providers).) - -A provider configuration is created using a `provider` block: - -```hcl -provider "google" { - project = "acme-app" - region = "us-central1" -} -``` - -The name given in the block header (`"google"` in this example) is the -[local name](/terraform/language/providers/requirements#local-names) of the provider to -configure. This provider should already be included in a `required_providers` -block. - -The body of the block (between `{` and `}`) contains configuration arguments for -the provider. Most arguments in this section are defined by the provider itself; -in this example both `project` and `region` are specific to the `google` -provider. - -You can use [expressions](/terraform/language/expressions) in the values of these -configuration arguments, but can only reference values that are known before the -configuration is applied. This means you can safely reference input variables, -but not attributes exported by resources (with an exception for resource -arguments that are specified directly in the configuration). - -A provider's documentation should list which configuration arguments it expects. -For providers distributed on the -[Terraform Registry](https://registry.terraform.io), versioned documentation is -available on each provider's page, via the "Documentation" link in the -provider's header. - -Some providers can use shell environment variables (or other alternate sources, -like VM instance profiles) as values for some of their arguments; when -available, we recommend using this as a way to keep credentials out of your -version-controlled Terraform code. - -There are also two "meta-arguments" that are defined by Terraform itself -and available for all `provider` blocks: - -- [`alias`, for using the same provider with different configurations for different resources][inpage-alias] -- [`version`, which we no longer recommend][inpage-versions] (use - [provider requirements](/terraform/language/providers/requirements) instead) - -Unlike many other objects in the Terraform language, a `provider` block may -be omitted if its contents would otherwise be empty. Terraform assumes an -empty default configuration for any provider that is not explicitly configured. - -## `alias`: Multiple Provider Configurations - -[inpage-alias]: #alias-multiple-provider-configurations - -You can optionally define multiple configurations for the same provider, and -select which one to use on a per-resource or per-module basis. The primary -reason for this is to support multiple regions for a cloud platform; other -examples include targeting multiple Docker hosts, multiple Consul hosts, etc. - -To create multiple configurations for a given provider, include multiple -`provider` blocks with the same provider name. For each additional non-default -configuration, use the `alias` meta-argument to provide an extra name segment. -For example: - -```hcl -# The default provider configuration; resources that begin with `aws_` will use -# it as the default, and it can be referenced as `aws`. -provider "aws" { - region = "us-east-1" -} - -# Additional provider configuration for west coast region; resources can -# reference this as `aws.west`. -provider "aws" { - alias = "west" - region = "us-west-2" -} -``` - -To declare a configuration alias within a module in order to receive an -alternate provider configuration from the parent module, add the -`configuration_aliases` argument to that provider's `required_providers` -entry. The following example declares both the `mycloud` and -`mycloud.alternate` provider configuration names within the containing module: - -```hcl -terraform { - required_providers { - mycloud = { - source = "mycorp/mycloud" - version = "~> 1.0" - configuration_aliases = [ mycloud.alternate ] - } - } -} -``` - -### Default Provider Configurations - -A `provider` block without an `alias` argument is the _default_ configuration -for that provider. Resources that don't set the `provider` meta-argument will -use the default provider configuration that matches the first word of the -resource type name. (For example, an `aws_instance` resource uses the default -`aws` provider configuration unless otherwise stated.) - -If every explicit configuration of a provider has an alias, Terraform uses the -implied empty configuration as that provider's default configuration. (If the -provider has any required configuration arguments, Terraform will raise an error -when resources default to the empty configuration.) - -### Referring to Alternate Provider Configurations - -When Terraform needs the name of a provider configuration, it expects a -reference of the form `.`. In the example above, -`aws.west` would refer to the provider with the `us-west-2` region. - -These references are special expressions. Like references to other named -entities (for example, `var.image_id`), they aren't strings and don't need to be -quoted. But they are only valid in specific meta-arguments of `resource`, -`data`, and `module` blocks, and can't be used in arbitrary expressions. - -### Selecting Alternate Provider Configurations - -By default, resources use a default provider configuration (one without an -`alias` argument) inferred from the first word of the resource type name. - -To use an alternate provider configuration for a resource or data source, set -its `provider` meta-argument to a `.` reference: - -```hcl -resource "aws_instance" "foo" { - provider = aws.west - - # ... -} -``` - -To select alternate provider configurations for a child module, use its -`providers` meta-argument to specify which provider configurations should be -mapped to which local provider names inside the module: - -```hcl -module "aws_vpc" { - source = "./aws_vpc" - providers = { - aws = aws.west - } -} -``` - -Modules have some special requirements when passing in providers; see -[The Module `providers` Meta-Argument](/terraform/language/meta-arguments/module-providers) -for more details. In most cases, only _root modules_ should define provider -configurations, with all child modules obtaining their provider configurations -from their parents. - - - -## `version` (Deprecated) - -[inpage-versions]: #provider-versions - -The `version` meta-argument specifies a version constraint for a provider, and -works the same way as the `version` argument in a -[`required_providers` block](/terraform/language/providers/requirements). The version -constraint in a provider configuration is only used if `required_providers` -does not include one for that provider. - -~**Warning:** The `version` argument in provider configurations is deprecated, and we will remove it in a future Terraform version. - -In Terraform 0.13 and later, always declare provider version constraints in -[the `required_providers` block](/terraform/language/providers/requirements). diff --git a/website/docs/language/providers/index.mdx b/website/docs/language/providers/index.mdx deleted file mode 100644 index 76b0a0c596..0000000000 --- a/website/docs/language/providers/index.mdx +++ /dev/null @@ -1,142 +0,0 @@ ---- -page_title: Providers - Configuration Language -description: >- - An overview of how to install and use providers, Terraform plugins that - interact with services, cloud providers, and other APIs. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Providers - -> **Hands-on:** Try the [Perform CRUD Operations with Providers](/terraform/tutorials/configuration-language/provider-use?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -Terraform relies on plugins called providers to interact with cloud providers, -SaaS providers, and other APIs. - -Terraform configurations must declare which providers they require so that -Terraform can install and use them. Additionally, some providers require -configuration (like endpoint URLs or cloud regions) before they can be used. - -## What Providers Do - -Each provider adds a set of [resource types](/terraform/language/resources) -and/or [data sources](/terraform/language/data-sources) that Terraform can -manage. - -Every resource type is implemented by a provider; without providers, Terraform -can't manage any kind of infrastructure. - -Most providers configure a specific infrastructure platform (either cloud or -self-hosted). Providers can also offer local utilities for tasks like -generating random numbers for unique resource names. - -## Where Providers Come From - -Providers are distributed separately from Terraform itself, and each provider -has its own release cadence and version numbers. - -The [Terraform Registry](https://registry.terraform.io/browse/providers) -is the main directory of publicly available Terraform providers, and hosts -providers for most major infrastructure platforms. - -## Provider Documentation - -Each provider has its own documentation, describing its resource -types and their arguments. - -The [Terraform Registry](https://registry.terraform.io/browse/providers) -includes documentation for a wide range of providers developed by HashiCorp, third-party vendors, and our Terraform community. Use the -"Documentation" link in a provider's header to browse its documentation. - -Provider documentation in the Registry is versioned; you can use the version -menu in the header to change which version you're viewing. - -For details about writing, generating, and previewing provider documentation, -see the [provider publishing documentation](/terraform/registry/providers/docs). - -## How to Use Providers - -Providers are released separately from Terraform itself and have their own version numbers. In production we recommend constraining the acceptable provider versions in the configuration's provider requirements block, to make sure that `terraform init` does not install newer versions of the provider that are incompatible with the configuration. - -To use resources from a given provider, you need to include some information -about it in your configuration. See the following pages for details: - -- [Provider Requirements](/terraform/language/providers/requirements) - documents how to declare providers so Terraform can install them. - -- [Provider Configuration](/terraform/language/providers/configuration) - documents how to configure settings for providers. - -- [Dependency Lock File](/terraform/language/files/dependency-lock) - documents an additional HCL file that can be included with a configuration, - which tells Terraform to always use a specific set of provider versions. - -## Provider Installation - -- HCP Terraform and Terraform Enterprise install providers as part of every run. - -- Terraform CLI finds and installs providers when - [initializing a working directory](/terraform/cli/init). It can - automatically download providers from a Terraform registry, or load them from - a local mirror or cache. If you are using a persistent working directory, you - must reinitialize whenever you change a configuration's providers. - - To save time and bandwidth, Terraform CLI supports an optional plugin - cache. You can enable the cache using the `plugin_cache_dir` setting in - [the CLI configuration file](/terraform/cli/config/config-file). - -To ensure Terraform always installs the same provider versions for a given -configuration, you can use Terraform CLI to create a -[dependency lock file](/terraform/language/files/dependency-lock) -and commit it to version control along with your configuration. If a lock file -is present, HCP Terraform, CLI, and Enterprise will all obey it when -installing providers. - -> **Hands-on:** Try the [Lock and Upgrade Provider Versions](/terraform/tutorials/configuration-language/provider-versioning?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -### Private Providers - -If you are using a provider that is not in a Hashicorp-hosted registry, you may -need to attach additional credentials to your requests to external registries. -You do not need these credentials if your provider is in the Terraform public -registry or the HCP Terraform private registry. - -By default, Terraform only authenticates the opening request from a provider to -the registry. The registry responds with -[follow-up URLs](/terraform/internals/provider-registry-protocol#find-a-provider-package) -that Terraform makes requests to, such as telling Terraform to download the -provider or the `SHASUMS` file. Hashicorp-hosted registries do not require -additional authentication for these follow-up requests. If your registry does -require additional credentials for follow-up requests, you can use a `.netrc` -file to provide those credentials. - -By default, Terraform searches for the `.netrc` file in your `HOME` directory. -However, you can override the default filesystem location by setting the `NETRC` -environment variable. For information on the format of`.netrc`, refer to the -[`curl` documentation](https://everything.curl.dev/usingcurl/netrc). - -## How to Find Providers - -To find providers for the infrastructure platforms you use, browse -[the providers section of the Terraform Registry](https://registry.terraform.io/browse/providers). - -Some providers on the Registry are developed and published by HashiCorp, some -are published by platform maintainers, and some are published by users and -volunteers. The provider listings use the following badges to indicate who -develops and maintains a given provider. - - -

- -## How to Develop Providers - -Providers are written in Go, using the Terraform Plugin SDK. For more -information on developing providers, see: - -- The [Plugin Development](/terraform/plugin) documentation -- The [Call APIs with Terraform Providers](/terraform/tutorials/providers-plugin-framework?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials diff --git a/website/docs/language/providers/requirements.mdx b/website/docs/language/providers/requirements.mdx deleted file mode 100644 index e15eb28ebf..0000000000 --- a/website/docs/language/providers/requirements.mdx +++ /dev/null @@ -1,434 +0,0 @@ ---- -page_title: Provider Requirements - Configuration Language -description: >- - Providers are plugins that allow Terraform to interact with services, cloud - providers, and other APIs. Learn how to declare providers in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Provider Requirements - -Terraform relies on plugins called "providers" to interact with remote systems. -Terraform configurations must declare which providers they require, so that -Terraform can install and use them. This page documents how to declare providers -so Terraform can install them. - -Additionally, some providers require configuration (like endpoint URLs or cloud -regions) before they can be used. The [Provider -Configuration](/terraform/language/providers/configuration) page documents how -to configure settings for providers. - --> **Note:** This page is about a feature of Terraform 0.13 and later; it also -describes how to use the more limited version of that feature that was available -in Terraform 0.12. - -## Requiring Providers - -Each Terraform module must declare which providers it requires, so that -Terraform can install and use them. Provider requirements are declared in a -`required_providers` block. - -A provider requirement consists of a local name, a source location, and a -version constraint: - -```hcl -terraform { - required_providers { - mycloud = { - source = "mycorp/mycloud" - version = "~> 1.0" - } - } -} -``` - -The `required_providers` block must be nested inside the top-level -[`terraform` block](/terraform/language/terraform) (which can also contain other settings). - -Each argument in the `required_providers` block enables one provider. The key -determines the provider's [local name](#local-names) (its unique identifier -within this module), and the value is an object with the following elements: - -* `source` - the global [source address](#source-addresses) for the - provider you intend to use, such as `hashicorp/aws`. - -* `version` - a [version constraint](#version-constraints) specifying - which subset of available provider versions the module is compatible with. - --> **Note:** The `name = { source, version }` syntax for `required_providers` -was added in Terraform v0.13. Previous versions of Terraform used a version -constraint string instead of an object (like `mycloud = "~> 1.0"`), and had no -way to specify provider source addresses. If you want to write a module that -works with both Terraform v0.12 and v0.13, see [v0.12-Compatible Provider -Requirements](#v0-12-compatible-provider-requirements) below. - -## Names and Addresses - -Each provider has two identifiers: - -* A unique _source address,_ which is only used when requiring a provider. -* A _local name,_ which is used everywhere else in a Terraform module. - --> **Note:** Prior to Terraform 0.13, providers only had local names, since -Terraform could only automatically download providers distributed by HashiCorp. - -### Local Names - -Local names are module-specific, and are assigned when requiring a provider. -Local names must be unique per-module. - -Outside of the `required_providers` block, Terraform configurations always refer -to providers by their local names. For example, the following configuration -declares `mycloud` as the local name for `mycorp/mycloud`, then uses that local -name when [configuring the provider](/terraform/language/providers/configuration): - -```hcl -terraform { - required_providers { - mycloud = { - source = "mycorp/mycloud" - version = "~> 1.0" - } - } -} - -provider "mycloud" { - # ... -} -``` - -Users of a provider can choose any local name for it. However, nearly every -provider has a _preferred local name,_ which it uses as a prefix for all of its -resource types. (For example, resources from `hashicorp/aws` all begin with -`aws`, like `aws_instance` or `aws_security_group`.) - -Whenever possible, you should use a provider's preferred local name. This makes -your configurations easier to understand, and lets you omit the `provider` -meta-argument from most of your resources. (If a resource doesn't specify which -provider configuration to use, Terraform interprets the first word of the -resource type as a local provider name.) - -### Source Addresses - -A provider's source address is its global identifier. It also specifies the -primary location where Terraform can download it. - -Source addresses consist of three parts delimited by slashes (`/`), as -follows: - -`[/]/` - -Examples of valid provider source address formats include: -- `NAMESPACE/TYPE` -- `HOSTNAME/NAMESPACE/TYPE` - -* **Hostname** (optional): The hostname of the Terraform registry that - distributes the provider. If omitted, this defaults to - `registry.terraform.io`, the hostname of - [the public Terraform Registry](https://registry.terraform.io/). - -* **Namespace:** An organizational namespace within the specified registry. - For the public Terraform Registry and for HCP Terraform's private registry, - this represents the organization that publishes the provider. This field - may have other meanings for other registry hosts. - -* **Type:** A short name for the platform or system the provider manages. Must - be unique within a particular namespace on a particular registry host. - - The type is usually the provider's preferred local name. (There are - exceptions; for example, - [`hashicorp/google-beta`](https://registry.terraform.io/providers/hashicorp/google-beta/latest) - is an alternate release channel for `hashicorp/google`, so its preferred - local name is `google`. If in doubt, check the provider's documentation.) - -For example, -[the official HTTP provider](https://registry.terraform.io/providers/hashicorp/http) -belongs to the `hashicorp` namespace on `registry.terraform.io`, so its -source address is `registry.terraform.io/hashicorp/http` or, more commonly, just -`hashicorp/http`. - -The source address with all three components given explicitly is called the -provider's _fully-qualified address_. You will see fully-qualified address in -various outputs, like error messages, but in most cases a simplified display -version is used. This display version omits the source host when it is the -public registry, so you may see the shortened version `"hashicorp/random"` instead -of `"registry.terraform.io/hashicorp/random"`. - --> **Note:** If you omit the `source` argument when requiring a provider, -Terraform uses an implied source address of -`registry.terraform.io/hashicorp/`. This is a backward compatibility -feature to support the transition to Terraform 0.13; in modules that require -0.13 or later, we recommend using explicit source addresses for all providers. - -### Handling Local Name Conflicts - -Whenever possible, we recommend using a provider's preferred local name, which -is usually the same as the "type" portion of its source address. - -However, it's sometimes necessary to use two providers with the same preferred -local name in the same module, usually when the providers are named after a -generic infrastructure type. Terraform requires unique local names for each -provider in a module, so you'll need to use a non-preferred name for at least -one of them. - -When this happens, we recommend combining each provider's namespace with -its type name to produce compound local names with a dash: - -```hcl -terraform { - required_providers { - # In the rare situation of using two providers that - # have the same type name -- "http" in this example -- - # use a compound local name to distinguish them. - hashicorp-http = { - source = "hashicorp/http" - version = "~> 2.0" - } - mycorp-http = { - source = "mycorp/http" - version = "~> 1.0" - } - } -} - -# References to these providers elsewhere in the -# module will use these compound local names. -provider "mycorp-http" { - # ... -} - -data "http" "example" { - provider = hashicorp-http - #... -} -``` - -Terraform won't be able to guess either provider's name from its resource types, -so you'll need to specify a `provider` meta-argument for every affected -resource. However, readers and maintainers of your module will be able to easily -understand what's happening, and avoiding confusion is much more important than -avoiding typing. - -## Version Constraints - -Each provider plugin has its own set of available versions, allowing the -functionality of the provider to evolve over time. Each provider dependency you -declare should have a [version constraint](/terraform/language/expressions/version-constraints) given in -the `version` argument so Terraform can select a single version per provider -that all modules are compatible with. - -The `version` argument is optional; if omitted, Terraform will accept any -version of the provider as compatible. However, we strongly recommend specifying -a version constraint for every provider your module depends on. - -To ensure Terraform always installs the same provider versions for a given -configuration, you can use Terraform CLI to create a -[dependency lock file](/terraform/language/files/dependency-lock) -and commit it to version control along with your configuration. If a lock file -is present, HCP Terraform, CLI, and Enterprise will all obey it when -installing providers. - -> **Hands-on:** Try the [Lock and Upgrade Provider Versions](/terraform/tutorials/configuration-language/provider-versioning) tutorial. - -### Best Practices for Provider Versions - -Each module should at least declare the minimum provider version it is known -to work with, using the `>=` version constraint syntax: - -```hcl -terraform { - required_providers { - mycloud = { - source = "hashicorp/aws" - version = ">= 1.0" - } - } -} -``` - -A module intended to be used as the root of a configuration — that is, as the -directory where you'd run `terraform apply` — should also specify the -_maximum_ provider version it is intended to work with, to avoid accidental -upgrades to incompatible new versions. The `~>` operator is a convenient -shorthand for allowing the rightmost component of a version to increment. The -following example uses the operator to allow only patch releases within a -specific minor release: - -```hcl -terraform { - required_providers { - mycloud = { - source = "hashicorp/aws" - version = "~> 1.0.4" - } - } -} -``` - -Do not use `~>` (or other maximum-version constraints) for modules you intend to -reuse across many configurations, even if you know the module isn't compatible -with certain newer versions. Doing so can sometimes prevent errors, but more -often it forces users of the module to update many modules simultaneously when -performing routine upgrades. Specify a minimum version, document any known -incompatibilities, and let the root module manage the maximum version. - -## Built-in Providers - -Most Terraform providers are distributed separately as plugins, but there -is one provider that is built into Terraform itself. This provider enables -[the `terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -Because this provider is built into Terraform, you don't need to declare it -in the `required_providers` block in order to use its features. However, for -consistency it _does_ have a special provider source address, which is -`terraform.io/builtin/terraform`. This address may sometimes appear in -Terraform's error messages and other output in order to unambiguously refer -to the built-in provider, as opposed to a hypothetical third-party provider -with the type name "terraform". - -There is also an existing provider with the source address -`hashicorp/terraform`, which is an older version of the now-built-in provider -that was used by older versions of Terraform. `hashicorp/terraform` is not -compatible with Terraform v0.11 or later and should never be declared in a -`required_providers` block. - -## In-house Providers - -Anyone can develop and distribute their own Terraform providers. See -the [Call APIs with Terraform Providers](/terraform/tutorials/providers) -tutorials for more about provider development. - -Some organizations develop their own providers to configure -proprietary systems, and wish to use these providers from Terraform without -publishing them on the public Terraform Registry. - -One option for distributing such a provider is to run an in-house _private_ -registry, by implementing -[the provider registry protocol](/terraform/internals/provider-registry-protocol). - -Running an additional service just to distribute a single provider internally -may be undesirable, so Terraform also supports -[other provider installation methods](/terraform/cli/config/config-file#provider-installation), -including placing provider plugins directly in specific directories in the -local filesystem, via _filesystem mirrors_. - -All providers must have a [source address](#source-addresses) that includes -(or implies) the hostname of a registry, but that hostname does not need to -provide an actual registry service. For in-house providers that you intend to -distribute from a local filesystem directory, you can use an arbitrary hostname -in a domain your organization controls. - -For example, if your corporate domain were `example.com` then you might choose -to use `terraform.example.com` as your placeholder hostname, even if that -hostname doesn't actually resolve in DNS. You can then choose any namespace and -type you wish to represent your in-house provider under that hostname, giving -a source address like `terraform.example.com/examplecorp/ourcloud`: - -```hcl -terraform { - required_providers { - mycloud = { - source = "terraform.example.com/examplecorp/ourcloud" - version = ">= 1.0" - } - } -} -``` - -To make version 1.0.0 of this provider available for installation from the -local filesystem, choose one of the -[implied local mirror directories](/terraform/cli/config/config-file#implied-local-mirror-directories) -and create a directory structure under it like this: - -``` -terraform.example.com/examplecorp/ourcloud/1.0.0 -``` - -Under that `1.0.0` directory, create one additional directory representing the -platform where you are running Terraform, such as `linux_amd64` for Linux on -an AMD64/x64 processor, and then place the provider plugin executable and any -other needed files in that directory. - -Thus, on a Windows system, the provider plugin executable file might be at the -following path: - -``` -terraform.example.com/examplecorp/ourcloud/1.0.0/windows_amd64/terraform-provider-ourcloud.exe -``` - -If you later decide to switch to using a real private provider registry rather -than distribute binaries out of band, you can deploy the registry server at -`terraform.example.com` and retain the same namespace and type names, in which -case your existing modules will require no changes to locate the same provider -using your registry server. - -## v0.12-Compatible Provider Requirements - -Explicit provider source addresses were introduced with Terraform v0.13, so the -full provider requirements syntax is not supported by Terraform v0.12. - -However, in order to allow writing modules that are compatible with both -Terraform v0.12 and v0.13, versions of Terraform between v0.12.26 and v0.13 -will accept but ignore the `source` argument in a `required_providers` block. - -Consider the following example written for Terraform v0.13: - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 1.0" - } - } -} -``` - -Terraform v0.12.26 will accept syntax like the above but will understand it -in the same way as the following v0.12-style syntax: - -```hcl -terraform { - required_providers { - aws = "~> 1.0" - } -} -``` - -In other words, Terraform v0.12.26 ignores the `source` argument and considers -only the `version` argument, using the given [local name](#local-names) as the -un-namespaced provider type to install. - -When writing a module that is compatible with both Terraform v0.12.26 and -Terraform v0.13.0 or later, you must follow the following additional rules so -that both versions will select the same provider to install: - -* Use only providers that can be automatically installed by Terraform v0.12. - Third-party providers, such as community providers in the Terraform Registry, - cannot be selected by Terraform v0.12 because it does not support the - hierarchical source address namespace. - -* Ensure that your chosen local name exactly matches the "type" portion of the - source address given in the `source` argument, such as both being "aws" in - the examples above, because Terraform v0.12 will use the local name to - determine which provider plugin to download and install. - -* If the provider belongs to the `hashicorp` namespace, as with the - `hashicorp/aws` provider shown above, omit the `source` argument and allow - Terraform v0.13 to select the `hashicorp` namespace by default. - -* Provider type names must always be written in lowercase. Terraform v0.13 - treats provider source addresses as case-insensitive, but Terraform v0.12 - considers its legacy-style provider names to be case-sensitive. Using - lowercase will ensure that the name is selectable by both Terraform major - versions. - -This compatibility mechanism is provided as a temporary transitional aid only. -When Terraform v0.12 detects a use of the new `source` argument it doesn't -understand, it will emit a warning to alert the user that it is disregarding -the source address given in that argument. diff --git a/website/docs/language/resources/behavior.mdx b/website/docs/language/resources/behavior.mdx deleted file mode 100644 index 03556958eb..0000000000 --- a/website/docs/language/resources/behavior.mdx +++ /dev/null @@ -1,117 +0,0 @@ ---- -page_title: Resource Behavior - Configuration Language -description: >- - Learn how Terraform uses resource blocks to create infrastructure objects. - Also learn about resource dependencies and how to access resource attributes. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Behavior - -A `resource` block declares that you want a particular infrastructure object -to exist with the given settings. If you are writing a new configuration for -the first time, the resources it defines will exist _only_ in the configuration, -and will not yet represent real infrastructure objects in the target platform. - -_Applying_ a Terraform configuration is the process of creating, updating, -and destroying real infrastructure objects in order to make their settings -match the configuration. - -## How Terraform Applies a Configuration - -When Terraform creates a new infrastructure object represented by a `resource` -block, the identifier for that real object is saved in Terraform's -[state](/terraform/language/state), allowing it to be updated and destroyed -in response to future changes. For resource blocks that already have an -associated infrastructure object in the state, Terraform compares the -actual configuration of the object with the arguments given in the -configuration and, if necessary, updates the object to match the configuration. - -In summary, applying a Terraform configuration will: - -- _Create_ resources that exist in the configuration but are not associated with a real infrastructure object in the state. -- _Destroy_ resources that exist in the state but no longer exist in the configuration. -- _Update in-place_ resources whose arguments have changed. -- _Destroy and re-create_ resources whose arguments have changed but which cannot be updated in-place due to remote API limitations. - -This general behavior applies for all resources, regardless of type. The -details of what it means to create, update, or destroy a resource are different -for each resource type, but this standard set of verbs is common across them -all. - -The meta-arguments within `resource` blocks, documented in the -sections below, allow some details of this standard resource behavior to be -customized on a per-resource basis. - -## Accessing Resource Attributes - -[Expressions](/terraform/language/expressions) within a Terraform module can access -information about resources in the same module, and you can use that information -to help configure other resources. Use the `..` -syntax to reference a resource attribute in an expression. - -In addition to arguments specified in the configuration, resources often provide -read-only attributes with information obtained from the remote API; this often -includes things that can't be known until the resource is created, like the -resource's unique random ID. - -Many providers also include [data sources](/terraform/language/data-sources), -which are a special type of resource used only for looking up information. - -For a list of the attributes a resource or data source type provides, consult -its documentation; these are generally included in a second list below its list -of configurable arguments. - -For more information about referencing resource attributes in expressions, see -[Expressions: References to Resource Attributes](/terraform/language/expressions/references#references-to-resource-attributes). - -## Resource Dependencies - -Most resources in a configuration don't have any particular relationship, and -Terraform can make changes to several unrelated resources in parallel. - -However, some resources must be processed after other specific resources; -sometimes this is because of how the resource works, and sometimes the -resource's configuration just requires information generated by another -resource. - -Most resource dependencies are handled automatically. Terraform analyses any -[expressions](/terraform/language/expressions) within a `resource` block to find references -to other objects, and treats those references as implicit ordering requirements -when creating, updating, or destroying resources. Since most resources with -behavioral dependencies on other resources also refer to those resources' data, -it's usually not necessary to manually specify dependencies between resources. - -However, some dependencies cannot be recognized implicitly in configuration. For -example, if Terraform must manage access control policies _and_ take actions -that require those policies to be present, there is a hidden dependency between -the access policy and a resource whose creation depends on it. In these rare -cases, -[the `depends_on` meta-argument](/terraform/language/meta-arguments/depends_on) -can explicitly specify a dependency. - -You can also use the [`replace_triggered_by` meta-argument](/terraform/language/meta-arguments/lifecycle#replace_triggered_by) to add dependencies between otherwise independent resources. It forces Terraform to replace the parent resource when there is a change to a referenced resource or resource attribute. - -## Local-only Resources - -While most resource types correspond to an infrastructure object type that -is managed via a remote network API, there are certain specialized resource -types that operate only within Terraform itself, calculating some results and -saving those results in the state for future use. - -For example, local-only resource types exist for -[generating private keys](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key), -[issuing self-signed TLS certificates](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/self_signed_cert), -and even [generating random ids](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id). -While these resource types often have a more marginal purpose than those -managing "real" infrastructure objects, they can be useful as glue to help -connect together other resources. - -The behavior of local-only resources is the same as all other resources, but -their result data exists only within the Terraform state. "Destroying" such -a resource means only to remove it from the state, discarding its data. diff --git a/website/docs/language/resources/ephemeral/index.mdx b/website/docs/language/resources/ephemeral/index.mdx deleted file mode 100644 index c66fe42a6c..0000000000 --- a/website/docs/language/resources/ephemeral/index.mdx +++ /dev/null @@ -1,87 +0,0 @@ ---- -page_title: Ephemeral resources -description: Learn how to keep sensitive resource data out of state and plan files in Terraform with ephemeral resource blocks and write-only arguments. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Ephemerality in resources - -Managing infrastructure often requires creating and handling sensitive values that you may not want Terraform to persist outside of the current operation. Terraform provides two tools for resources to manage data you do not want to store in state or plan files: the `ephemeral` resource block and ephemeral write-only arguments on specific resources. - -## Ephemeral resources - -Ephemeral resources are Terraform resources that are essentially temporary. Ephemeral resources have a unique lifecycle, and Terraform does not store information about ephemeral resources in state or plan files. Each `ephemeral` block describes one or more ephemeral resources, such as a temporary password or connection to another system. - -In your configuration, you can only reference an `ephemeral` block in [other ephemeral contexts](/terraform/language/resources/ephemeral/reference#reference-ephemeral-resources). - -### Lifecycle - -The lifecycle of an `ephemeral` resource is different from other resources and data sources. When Terraform provisions ephemeral resources, it performs the following steps: - -1. If Terraform needs to access the result of an ephemeral resource, it opens -that ephemeral resource. For example, if Terraform opens an ephemeral resource for a Vault secret, the Vault provider obtains a lease and returns a secret. - -1. If Terraform needs access to the ephemeral resource for longer than the -remote system's enforced expiration time, Terraform asks the provider -to periodically renew it. For example, if Terraform renews a Vault secret `ephemeral` resource, the Vault provider calls Vault's lease renewal API endpoint to extend the expiration time. - -1. Once Terraform no longer needs an ephemeral resource, Terraform closes -it. This happens after the providers that depend on an ephemeral resource -complete all of their work for the current Terraform run phase. For example, closing a Vault secret ephemeral resource means the Vault provider explicitly ends the lease, allowing Vault to immediately revoke the associated credentials. - -Terraform follows these lifecycle steps for each instance of an ephemeral -resource in a given configuration. - -### Configuration model - -To learn more about the `ephemeral` resource block, refer to the [Ephemeral resource reference](/terraform/language/resources/ephemeral/reference). - -## Write-only arguments - -Terraform's managed resources, defined by `resource` blocks, can include ephemeral arguments, called **write-only arguments**. Write-only arguments are only available during the current Terraform operation, and Terraform does not store them in state or plan files. - -Use write-only arguments to securely pass temporary values to resources during a Terraform operation without worrying about Terraform persisting those values. For example, the `aws_db_instance` resource has a write-only `password_wo` argument that accepts a database password: - - - -```hcl -ephemeral "random_password" "db_password" { - length = 16 - override_special = "!#$%&*()-_=+[]{}<>:?" -} - -resource "aws_secretsmanager_secret" "db_password" { - name = "db_password" -} - -resource "aws_secretsmanager_secret_version" "db_password" { - secret_id = aws_secretsmanager_secret.db_password.id - secret_string_wo = ephemeral.random_password.db_password.result - secret_string_wo_version = 1 -} - -ephemeral "aws_secretsmanager_secret_version" "db_password" { - secret_id = aws_secretsmanager_secret_version.db_password.secret_id -} - -resource "aws_db_instance" "example" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = ephemeral.aws_secretsmanager_secret_version.db_password.secret_string - password_wo_version = aws_secretsmanager_secret_version.db_password.secret_string_wo_version -} -``` - - - -When Terraform creates the `aws_db_instance` resource, Terraform sends the `password_wo` value to the `aws` provider. The `aws` provider then uses the `password_wo` value to create the database instance, and then Terraform discards the password value without ever storing it. - -To learn more about this example and using write-only arguments, refer to the [Use write-only arguments](/terraform/language/resources/ephemeral/write-only). \ No newline at end of file diff --git a/website/docs/language/resources/ephemeral/reference.mdx b/website/docs/language/resources/ephemeral/reference.mdx deleted file mode 100644 index c2ec16dc69..0000000000 --- a/website/docs/language/resources/ephemeral/reference.mdx +++ /dev/null @@ -1,101 +0,0 @@ ---- -page_title: Ephemeral block configuration reference -description: Learn to define ephemeral blocks in Terraform configurations to keep temporary and sensitive information out of Terraform state and plan 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Ephemeral block configuration reference - -This topic provides reference information for the `ephemeral` block. - --> **Note**: Ephemeral resources are available in Terraform v1.10 and later. - -## Introduction - -Ephemeral resources are Terraform resources that are essentially temporary. Ephemeral resources have a unique lifecycle, and Terraform does not store them in its state. Each `ephemeral` block describes one or more ephemeral resources, such as a temporary password or connection to another system. - -## Dependency graph - -Ephemeral resources form nodes in Terraform's dependency graph, which interact similarly as resources and data sources. For example, when a resource or data source depends on an attribute of an ephemeral resource, Terraform automatically provisions the ephemeral resource first. - -## Defer provisioning - -If an input argument of an ephemeral resource references a value that Terraform does not know yet, but can learn during or after a plan, Terraform defers executing that resource until the apply stage. Deferring execution lets Terraform ensure it has all of the information it needs to properly provision the ephemeral resource. - -## Configuration model - -An `ephemeral` block declares an ephemeral resource of a specific type with a -specific local name, much like a `resource` block. Terraform uses an ephemeral resource's name to refer to that resource in the same module, but an ephemeral resource's name has no meaning outside that module's scope. - -Most of the arguments within the body of an `ephemeral` block are specific to the ephemeral resource you are defining. As with resources and data sources, each provider in the [Terraform Registry](https://registry.terraform.io/browse/providers) includes documentation for the ephemeral resources it supports, if any. An ephemeral resource type's documentation lists which arguments are available and how you should format your resource's values. - -The following list outlines general field hierarchy, language-specific data types, and requirements in the `ephemeral` block. - -- [`ephemeral`](#ephemeral): map - - [`attributes`](#ephemeral) - - [`meta-arguments`](#ephemeral) - -## Complete configuration - -An `ephemeral` block has the following form: - -```hcl -ephemeral "" "" { - - -} -``` - -## Reference ephemeral resources - -You can only reference ephemeral resources in specific ephemeral contexts or -Terraform throws an error. The following are valid contexts for referencing -ephemeral resources: - -* In a [write-only argument](/terraform/language/resources/ephemeral/write-only) -* In another ephemeral resource -* In [local values](/terraform/language/values/locals#ephemeral-values) -* In [ephemeral variables](/terraform/language/values/variables#exclude-values-from-state) -* In [ephemeral outputs](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files) -* Configuring providers in the `provider` block -* In [provisioner](/terraform/language/resources/provisioners/syntax) and [connection](/terraform/language/resources/provisioners/connection) blocks - -## Meta-arguments - -You can use the following meta-arguments with ephemeral resources to change the behavior of those resources. The following meta-arguments work the same way for resources, data sources, and ephemeral -resources: - -- [`depends_on`, for specifying hidden dependencies](/terraform/language/meta-arguments/depends_on) -- [`count`, for creating multiple resource instances according to a count](/terraform/language/meta-arguments/count) -- [`for_each`, to create multiple instances according to a map or set of strings](/terraform/language/meta-arguments/for_each) -- [`provider`, for selecting a non-default provider configuration](/terraform/language/meta-arguments/resource-provider) -- [`lifecycle`, for lifecycle customizations](/terraform/language/meta-arguments/lifecycle) - -Ephemeral resources do not support the `provisioner` meta-argument. - -## Example - -The following example configures the `postgresql` provider with credentials from -an ephemeral resource. Since these credentials are managed by an ephemeral resource, Terraform does not store them in your state or plan files. - -```hcl -ephemeral "aws_secretsmanager_secret_version" "db_master" { - secret_id = aws_secretsmanager_secret_version.db_password.secret_id -} - -locals { - credentials = jsondecode(ephemeral.aws_secretsmanager_secret_version.db_master.secret_string) -} - -provider "postgresql" { - host = aws_db_instance.example.address - port = aws_db_instance.example.port - username = local.credentials["username"] - password = local.credentials["password"] -} -``` diff --git a/website/docs/language/resources/ephemeral/write-only.mdx b/website/docs/language/resources/ephemeral/write-only.mdx deleted file mode 100644 index a3b1854519..0000000000 --- a/website/docs/language/resources/ephemeral/write-only.mdx +++ /dev/null @@ -1,256 +0,0 @@ ---- -page_title: Use write-only arguments -description: Learn how to use write-only arguments to set temporary values that are not stored in Terraform's state or plan 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Use write-only arguments - -Write-only arguments let you securely pass temporary values to Terraform's managed resources during an operation without persisting those values to state or plan files. Use write-only arguments to handle sensitive data such as passwords, API tokens, and other secrets. - -## Background - -Write-only arguments complement [other ephemeral values](/terraform/language/resources/ephemeral/reference#reference-ephemeral-resources) in Terraform, letting you securely pass sensitive data throughout your configuration without ever storing it in Terraform's artifacts. For example, you can generate a random password using an `ephemeral` resource then pass it to a write-only argument on another `resource` block. The provider uses the write-only argument value to configure the resource, then Terraform discards the value without storing it. - -> **Hands-on**: Declare a write-only argument in the [Upgrade RDS major version](/terraform/tutorials/aws/rds-upgrade) tutorial. - -Unlike other ephemeral constructs in Terraform, such as ephemeral resources or variables, write-only arguments accept both ephemeral and non-ephemeral values. - -## Requirements - -To use write-only arguments, you must use Terraform v.1.11 or later and use a resource that supports write-only arguments. - -## Declare a write-only argument - -Providers indicate in the Terraform registry whether an argument is write-only. For example, the `aws` provider's `aws_db_instance` resource has a write-only `password_wo` argument. The `password_wo` argument accepts a value to use as the database password: - - - -```hcl -resource "aws_db_instance" "test" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = - password_wo_version = 1 -} -``` - - - -Write-only arguments accept both ephemeral and non-ephemeral values. For example, you could also use a string as the value of a write-only argument: - -```hcl -resource "aws_db_instance" "test" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = "my-password-here" - password_wo_version = 1 -} -``` - -However, we recommend using write-only arguments for passing ephemeral values to resources. For example, you can use an `ephemeral` resource to generate a random password and pass it to the `password_wo` write-only argument: - - - -```hcl -ephemeral "random_password" "db_password" { - length = 16 - override_special = "!#$%&*()-_=+[]{}<>:?" -} - -resource "aws_db_instance" "example" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = ephemeral.random_password.db_password.result - password_wo_version = 1 -} -``` - - - -During a Terraform operation, the provider uses the `password_wo` value to create the database instance, and then Terraform discards that value without storing it in the plan or state file. - -Note that Terraform does not store the generated value for `password_wo`, but you can capture it in another resource or output. For an example of generating, storing, retrieving, and using an ephemeral password as a write-only argument, refer to the [Examples](#examples). - -## Update write-only arguments with versions - -Terraform does not store write-only arguments in state files, so Terraform has no way of knowing if a write-only argument value has changed. Because Terraform cannot track write-only argument values, it sends write-only arguments to the provider during every operation. - -Terraform also cannot create plan diffs for write-only arguments because it does not store those values in plan files. However, providers typically include version arguments alongside write-only arguments. Terraform stores version arguments in state, and can track if a version argument changes. - -Providers implement version arguments to let practitioners track write-only argument values and control when a provider uses those write-only arguments. The implementation of write-only arguments and their version arguments is provider-specific, so consult the Registry for more details about your specific provider. - -For example, the `aws_db_instance` resource has an accompanying `password_wo_version` argument for the `password_wo` write-only argument: - - - -```hcl -resource "aws_db_instance" "test" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = "old-password-here" - password_wo_version = 1 -} -``` - - - -The provider uses the write-only argument value when creating the `aws_db_instance` resource and Terraform stores the `password_wo_version` argument value in state. - -To trigger an update of a write-only argument, increment the version argument's value in your configuration: - -```hcl -resource "aws_db_instance" "main" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - password_wo = "new-password-here" - password_wo_version = 2 -} -``` - -When you increment the `password_wo_version` argument, Terraform notices that change in its plan and notifies the `aws` provider. The `aws` provider then uses the new `password_wo` value to update the `aws_db_instance` resource. - - -## Examples - -The following demonstrates how to use write-only arguments with different cloud providers. - -### Set and store an ephemeral password in AWS Secrets Manager - -You can use an `ephemeral` resource to generate a random password, store it in AWS Secrets Manager, and then retrieve it using another `ephemeral` resource. Finally, you can pass the password to the `password_wo` write-only argument of the `aws_db_instance` resource: - - - -```hcl -ephemeral "random_password" "db_password" { - length = 16 - override_special = "!#$%&*()-_=+[]{}<>:?" -} - -resource "aws_secretsmanager_secret" "db_password" { - name = "db_password" -} - -resource "aws_secretsmanager_secret_version" "db_password" { - secret_id = aws_secretsmanager_secret.db_password.id - secret_string_wo = ephemeral.random_password.db_password.result - secret_string_wo_version = 1 -} - -ephemeral "aws_secretsmanager_secret_version" "db_password" { - secret_id = aws_secretsmanager_secret_version.db_password.secret_id -} - -resource "aws_db_instance" "example" { - instance_class = "db.t3.micro" - allocated_storage = "5" - engine = "postgres" - username = "example" - skip_final_snapshot = true - password_wo = ephemeral.aws_secretsmanager_secret_version.db_password.secret_string - password_wo_version = aws_secretsmanager_secret_version.db_password.secret_string_wo_version -} -``` - - - -In the above example, the ephemeral resource `aws_secretsmanager_secret_version` references an argument that Terraform initially does not know. Terraform defers executing `aws_secretsmanager_secret_version` until the apply stage, to ensure that Terraform evaluates the resource after it has the information it needs. - -Terraform first creates the secret in AWS Secrets Manager using the ephemeral `random_password`, then retrieve it using the ephemeral `aws_secretsmanager_secret_version` resource, and finally write the password to the write-only `password_wo` argument of the `aws_db_instance` resource. - -### Set and store an ephemeral password in Azure Key Vault - -You can use a write-only argument to store a password in Azure's Key Vault, then use that password to create a MySQL database in Azure. In the following example, Terraform generates an password using an `ephemeral` resource, stores that password in a `azurerm_key_vault_secret`, then retrieves it in the `azurerm_mysql_flexible_server` resource: - -```hcl -provider "azurerm" { - features {} -} - -ephemeral "random_password" "db_password" { - length = 16 - override_special = "!#$%&*()-_=+[]{}<>:?" -} - -locals { - db_password_version = 1 -} - -resource "azurerm_resource_group" "example" { - name = "example-resource-group" - location = "westeurope" -} - -data "azurerm_client_config" "current" {} - -resource "azurerm_key_vault" "example" { - name = "example-key-vault" - location = azurerm_resource_group.example.location - resource_group_name = azurerm_resource_group.example.name - tenant_id = data.azurerm_client_config.current.tenant_id - sku_name = "standard" - soft_delete_retention_days = 7 - - access_policy { - tenant_id = data.azurerm_client_config.current.tenant_id - object_id = data.azurerm_client_config.current.object_id - - key_permissions = [ - "Get", - ] - - secret_permissions = [ - "Get", - "Delete", - "List", - "Purge", - "Recover", - "Set", - ] - } -} - -resource "azurerm_key_vault_secret" "example" { - name = "example-secret" - value_wo = ephemeral.random_password.db_password.result - value_wo_version = local.db_password_version - key_vault_id = azurerm_key_vault.example.id -} - -ephemeral "azurerm_key_vault_secret" "db_password" { - name = azurerm_key_vault_secret.example.name - key_vault_id = azurerm_key_vault.example.id -} - -resource "azurerm_mysql_flexible_server" "example" { - name = "example-mysql-flexible-server" - resource_group_name = azurerm_resource_group.example.name - location = azurerm_resource_group.example.location - sku_name = "B_Standard_B1s" - - administrator_login = "newuser" - administrator_password_wo = ephemeral.azurerm_key_vault_secret.db_password.value - administrator_password_wo_version = local.db_password_version -} -``` - -The above configuration stores your password in Azure's Key Vault and uses it to create a database in Azure without ever storing that password in a Terraform artifact. \ No newline at end of file diff --git a/website/docs/language/resources/index.mdx b/website/docs/language/resources/index.mdx deleted file mode 100644 index 2a79e55301..0000000000 --- a/website/docs/language/resources/index.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -page_title: Resources Overview - Configuration Language -description: >- - Resources describe infrastructure objects in Terraform configurations. Find - documentation for resource syntax, behavior, and meta-arguments. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Resources - -> **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. - -_Resources_ are the most important element in the Terraform language. -Each resource block describes one or more infrastructure objects, such -as virtual networks, compute instances, or higher-level components such -as DNS records. - -- [Resource Blocks](/terraform/language/resources/syntax) documents - the syntax for declaring resources. - -- [Resource Behavior](/terraform/language/resources/behavior) explains in - more detail how Terraform handles resource declarations when applying a - configuration. - -- The Meta-Arguments section documents special arguments that can be used with - every resource type, including - [`depends_on`](/terraform/language/meta-arguments/depends_on), - [`count`](/terraform/language/meta-arguments/count), - [`for_each`](/terraform/language/meta-arguments/for_each), - [`provider`](/terraform/language/meta-arguments/resource-provider), - and [`lifecycle`](/terraform/language/meta-arguments/lifecycle). - -- [Provisioners](/terraform/language/resources/provisioners/syntax) - documents configuring post-creation actions for a resource using the - `provisioner` and `connection` blocks. Since provisioners are non-declarative - and potentially unpredictable, we strongly recommend that you treat them as a - last resort. diff --git a/website/docs/language/resources/provisioners/connection.mdx b/website/docs/language/resources/provisioners/connection.mdx deleted file mode 100644 index 019c26af96..0000000000 --- a/website/docs/language/resources/provisioners/connection.mdx +++ /dev/null @@ -1,220 +0,0 @@ ---- -page_title: Provisioner Connection Settings -description: >- - The connection block allows you to manage provisioner connection defaults for - SSH and WinRM. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Provisioner Connection Settings - -Most provisioners require access to the remote resource via SSH or WinRM and -expect a nested `connection` block with details about how to connect. - -~> **Important:** Use provisioners as a last resort. There are better alternatives for most situations. Refer to -[Declaring Provisioners](/terraform/language/resources/provisioners/syntax) for more details. - -## Connection Block - -You can create one or more `connection` blocks that describe how to access the remote resource. One use case for providing multiple connections is to have an initial provisioner connect as the `root` user to set up user accounts and then have subsequent provisioners connect as a user with more limited permissions. - -Connection blocks don't take a block label and can be nested within either a -`resource` or a `provisioner`. - -* A `connection` block nested directly within a `resource` affects all of - that resource's provisioners. -* A `connection` block nested in a `provisioner` block only affects that - provisioner and overrides any resource-level connection settings. - -Since the SSH connection type is most often used with -newly-created remote resources, validation of SSH host keys is disabled by -default. If this is not acceptable, you can establish a separate mechanism for key distribution and explicitly set the `host_key` argument (details below) to verify against a specific key or signing CA. - --> **Note:** In Terraform 0.11 and earlier, providers could set default values -for some connection settings, so that `connection` blocks could sometimes be -omitted. This feature was removed in 0.12 in order to make Terraform's behavior -more predictable. - -### Ephemeral values - --> **Note**: Ephemeral values are available in Terraform v1.10 and later. - -The configuration for a `connection` block may use ephemeral values, such as -[`ephemeral` resources](/terraform/language/resources/ephemeral), [`ephemeral` -local values](/terraform/language/values/locals#ephemeral-values), [`ephemeral` -variables](/terraform/language/values/variables#ephemeral), or [`ephemeral` -output -values](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files). - -Terraform will not store these values in your plan or state, or output them in -logs. - -### Example usage - -```hcl -# Copies the file as the root user using SSH -provisioner "file" { - source = "conf/myapp.conf" - destination = "/etc/myapp.conf" - - connection { - type = "ssh" - user = "root" - password = var.root_password - host = var.host - } -} - -# Copies the file as the Administrator user using WinRM -provisioner "file" { - source = "conf/myapp.conf" - destination = "C:/App/myapp.conf" - - connection { - type = "winrm" - user = "Administrator" - password = var.admin_password - host = var.host - } -} -``` - -### The `self` Object - -Expressions in `connection` blocks cannot refer to their parent resource by name. References create dependencies, and referring to a resource by name within its own block would create a dependency cycle. Instead, expressions can use the `self` object, which represents the connection's parent resource and has all of that resource's attributes. For example, use `self.public_ip` to reference an `aws_instance`'s `public_ip` attribute. - - -### Argument Reference - -The `connection` block supports the following arguments. Some arguments are only supported by either the SSH or the WinRM connection type. - - -| Argument | Connection Type | Description | Default | -|---------------|--------------|-------------|---------| -| `type` | Both | The connection type. Valid values are `"ssh"` and `"winrm"`. Provisioners typically assume that the remote system runs Microsoft Windows when using WinRM. Behaviors based on the SSH `target_platform` will force Windows-specific behavior for WinRM, unless otherwise specified.| `"ssh"` | -| `user` | Both | The user to use for the connection. | `root` for type `"ssh"`
`Administrator` for type `"winrm"` | -| `password` | Both | The password to use for the connection. | | -| `host` | Both | **Required** - The address of the resource to connect to. | | -| `port` | Both| The port to connect to. | `22` for type `"ssh"`
`5985` for type `"winrm"` | -| `timeout` | Both | The timeout to wait for the connection to become available. Should be provided as a string (e.g., `"30s"` or `"5m"`.) | `"5m"` | -| `script_path` | Both | The path used to copy scripts meant for remote execution. Refer to [How Provisioners Execute Remote Scripts](#how-provisioners-execute-remote-scripts) below for more details. | (details below) | -| `private_key` | SSH | The contents of an SSH key to use for the connection. These can be loaded from a file on disk using [the `file` function](/terraform/language/functions/file). This takes preference over `password` if provided. | | -| `certificate` | SSH | The contents of a signed CA Certificate. The certificate argument must be used in conjunction with a `private_key`. These can be loaded from a file on disk using the [the `file` function](/terraform/language/functions/file). | | -| `agent` | SSH | Set to `false` to disable using `ssh-agent` to authenticate. On Windows the only supported SSH authentication agent is [Pageant](http://the.earth.li/\~sgtatham/putty/0.66/htmldoc/Chapter9.html#pageant). | | -| `agent_identity` | SSH | The preferred identity from the ssh agent for authentication. | | -| `host_key` | SSH | The public key from the remote host or the signing CA, used to verify the connection. | | -| `target_platform` | SSH | The target platform to connect to. Valid values are `"windows"` and `"unix"`. If the platform is set to `windows`, the default `script_path` is `c:\windows\temp\terraform_%RAND%.cmd`, assuming [the SSH default shell](https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_server_configuration#configuring-the-default-shell-for-openssh-in-windows) is `cmd.exe`. If the SSH default shell is PowerShell, set `script_path` to `"c:/windows/temp/terraform_%RAND%.ps1"` | `"unix"` | -| `https` | WinRM | Set to `true` to connect using HTTPS instead of HTTP. | | -| `insecure` | WinRM | Set to `true` to skip validating the HTTPS certificate chain. | | -| `use_ntlm` | WinRM | Set to `true` to use NTLM authentication rather than default (basic authentication), removing the requirement for basic authentication to be enabled within the target guest. Refer to [Authentication for Remote Connections](https://docs.microsoft.com/en-us/windows/win32/winrm/authentication-for-remote-connections) in the Windows App Development documentation for more details. | | -| `cacert` | WinRM | The CA certificate to validate against. | | - - - - -## Connecting through a Bastion Host with SSH - -The `ssh` connection also supports the following arguments to connect -indirectly with a [bastion host](https://en.wikipedia.org/wiki/Bastion_host). - -| Argument | Description | Default | -|---------------|-------------|---------| -| `bastion_host` | Setting this enables the bastion Host connection. The provisioner will connect to `bastion_host` first, and then connect from there to `host`. | | -| `bastion_host_key` | The public key from the remote host or the signing CA, used to verify the host connection. | | -| `bastion_port` | The port to use connect to the bastion host. | The value of the `port` field.| -| `bastion_user`| The user for the connection to the bastion host. | The value of the `user` field. | -| `bastion_password` | The password to use for the bastion host. | The value of the `password` field. | -| `bastion_private_key` | The contents of an SSH key file to use for the bastion host. These can be loaded from a file on disk using [the `file` function](/terraform/language/functions/file). | The value of the `private_key` field. | -| `bastion_certificate` | The contents of a signed CA Certificate. The certificate argument must be used in conjunction with a `bastion_private_key`. These can be loaded from a file on disk using the [the `file` function](/terraform/language/functions/file). | - -## Connection through HTTP and SOCKS5 proxies with SSH - -The `ssh` connection also supports the following fields to facilitate connections by SSH over HTTP or SOCKS5 proxy. - -| Argument | Description | Default | -|---------------|-------------|---------| -| `proxy_scheme` | You can specify one of the following values: `http`, `https`, `socks5` | | -| `proxy_host` | Setting this enables the SSH over HTTP connection. This host will be connected to first, and then the `host` or `bastion_host` connection will be made from there. | | -| `proxy_port` | The port to use connect to the proxy host. | | -| `proxy_user_name` | The username to use connect to the private proxy host. This argument should be specified only if authentication is required for the HTTP Proxy server. | | -| `proxy_user_password` | The password to use connect to the private proxy host. This argument should be specified only if authentication is required for the HTTP Proxy server. | | - -## How Provisioners Execute Remote Scripts - -Provisioners which execute commands on a remote system via a protocol such as -SSH typically achieve that by uploading a script file to the remote system -and then asking the default shell to execute it. Provisioners use this strategy -because it then allows you to use all of the typical scripting techniques -supported by that shell, including preserving environment variable values -and other context between script statements. - -However, this approach does have some consequences which can be relevant in -some unusual situations, even though this is just an implementation detail -in typical use. - -Most importantly, there must be a suitable location in the remote filesystem -where the provisioner can create the script file. By default, Terraform -chooses a path containing a random number using the following patterns -depending on how `target_platform` is set: - -* `"unix"`: `/tmp/terraform_%RAND%.sh` -* `"windows"`: `C:/windows/temp/terraform_%RAND%.cmd` - -In both cases above, the provisioner replaces the sequence `%RAND%` with -some randomly-chosen decimal digits. - -Provisioners cannot react directly to remote environment variables such as -`TMPDIR` or use functions like `mktemp` because they run on the system where -Terraform is running, not on the remote system. Therefore if your remote -system doesn't use the filesystem layout expected by these default paths -then you can override it using the `script_path` option in your `connection` -block: - -```hcl -connection { - # ... - script_path = "H:/terraform-temp/script_%RAND%.sh" -} -``` - -As with the default patterns, provisioners will replace the sequence `%RAND%` -with randomly-selected decimal digits, to reduce the likelihood of collisions -between multiple provisioners running concurrently. - -If your target system is running Windows, we recommend using forward slashes -instead of backslashes, despite the typical convention on Windows, because -the Terraform language uses backslash as the quoted string escape character. - -### Executing Scripts using SSH/SCP - -When using the SSH protocol, provisioners upload their script files using -the Secure Copy Protocol (SCP), which requires that the remote system have -the `scp` service program installed to act as the server for that protocol. - -Provisioners will pass the chosen script path (after `%RAND%` -expansion) directly to the remote `scp` process, which is responsible for -interpreting it. With the default configuration of `scp` as distributed with -OpenSSH, you can place temporary scripts in the home directory of the remote -user by specifying a relative path: - -```hcl -connection { - type = "ssh" - # ... - script_path = "terraform_provisioner_%RAND%.sh" -} -``` - -!> **Warning:** In Terraform v1.0 and earlier, the built-in provisioners -incorrectly passed the `script_path` value to `scp` through a remote shell and -thus allowed it to be subject to arbitrary shell expansion, and thus created an -unintended opportunity for remote code execution. Terraform v1.1 and later -will now correctly quote and escape the script path to ensure that the -remote `scp` process can always interpret it literally. For modules that will -be used with Terraform v1.0 and earlier, avoid using untrusted external -values as part of the `script_path` argument. diff --git a/website/docs/language/resources/provisioners/file.mdx b/website/docs/language/resources/provisioners/file.mdx deleted file mode 100644 index 2816092650..0000000000 --- a/website/docs/language/resources/provisioners/file.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -page_title: 'Provisioner: file' -description: >- - The `file` provisioner is used to copy files or directories from the machine - executing Terraform to the newly created resource. The `file` provisioner - supports both `ssh` and `winrm` type connections. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# File Provisioner - -The `file` provisioner copies files or directories from the machine -running Terraform to the newly created resource. The `file` provisioner -supports both `ssh` and `winrm` type [connections](/terraform/language/resources/provisioners/connection). - -~> **Important:** Use provisioners as a last resort. There are better alternatives for most situations. Refer to -[Declaring Provisioners](/terraform/language/resources/provisioners/syntax) for more details. - -## Example usage - -```hcl -resource "aws_instance" "web" { - # ... - - # Copies the myapp.conf file to /etc/myapp.conf - provisioner "file" { - source = "conf/myapp.conf" - destination = "/etc/myapp.conf" - } - - # Copies the string in content into /tmp/file.log - provisioner "file" { - content = "ami used: ${self.ami}" - destination = "/tmp/file.log" - } - - # Copies the configs.d folder to /etc/configs.d - provisioner "file" { - source = "conf/configs.d" - destination = "/etc" - } - - # Copies all files and folders in apps/app1 to D:/IIS/webapp1 - provisioner "file" { - source = "apps/app1/" - destination = "D:/IIS/webapp1" - } -} -``` - --> **Note:** When the `file` provisioner communicates with a Windows system over SSH, you must configure OpenSSH to run the commands with `cmd.exe` and not PowerShell. PowerShell causes file parsing errors because it is incompatible with both Unix shells and the Windows command interpreter. - -## Argument Reference - -The following arguments are supported: - -* `source` - The source file or directory. Specify it either relative to the - current working directory or as an absolute path. - This argument cannot be combined with `content`. - -* `content` - The direct content to copy on the destination. - If destination is a file, the content will be written on that file. In case - of a directory, a file named `tf-file-content` is created inside that - directory. We recommend using a file as the destination when using `content`. - This argument cannot be combined with `source`. - -* `destination` - (Required) The destination path to write to on the remote - system. See [Destination Paths](#destination-paths) below for more - information. - -## Destination Paths - -The path you provide in the `destination` argument will be evaluated by the -remote system, rather than by Terraform itself. Therefore the valid values -for that argument can vary depending on the operating system and remote access -software running on the target. - -When connecting over SSH, the `file` provisioner passes the given destination -path verbatim to the `scp` program on the remote host. By default, OpenSSH's -`scp` implementation runs in the remote user's home directory and so you can -specify a relative path to upload into that home directory, or an absolute -path to upload to some other location. The remote `scp` process will run with -the access level of the user specified in the `connection` block, and so -permissions may prevent writing directly to locations outside of the home -directory. - -Because WinRM has no corresponding file transfer protocol, for WinRM -connections the `file` provisioner uses a more complex process: - -1. Generate a temporary filename in the directory given in the remote system's - `TEMP` environment variable, using a pseudorandom UUID for uniqueness. -2. Use sequential generated `echo` commands over WinRM to gradually append - base64-encoded chunks of the source file to the chosen temporary file. -3. Use an uploaded PowerShell script to read the temporary file, base64-decode, - and write the raw result into the destination file. - -In the WinRM case, the destination path is therefore interpreted by PowerShell -and so you must take care not to use any meta-characters that PowerShell might -interpret. In particular, avoid including any untrusted external input in -your `destination` argument when using WinRM, because it can serve as a vector -for arbitrary PowerShell code execution on the remote system. - -Modern Windows systems support running an OpenSSH server, so we strongly -recommend choosing SSH over WinRM whereever possible, and using WinRM only as -a last resort when working with obsolete Windows versions. - -## Directory Uploads - -The `file` provisioner can upload a complete directory to the remote machine. -When uploading a directory, there are some additional considerations. - -When using the `ssh` connection type the destination directory must already -exist. If you need to create it, use a remote-exec provisioner just prior to -the file provisioner in order to create the directory - -When using the `winrm` connection type the destination directory will be -created for you if it doesn't already exist. - -The existence of a trailing slash on the source path will determine whether the -directory name will be embedded within the destination, or whether the -destination will be created. For example: - -* If the source is `/foo` (no trailing slash), and the destination is `/tmp`, - then the contents of `/foo` on the local machine will be uploaded to - `/tmp/foo` on the remote machine. The `foo` directory on the remote machine - will be created by Terraform. - -* If the source, however, is `/foo/` (a trailing slash is present), and the - destination is `/tmp`, then the contents of `/foo` will be uploaded directly - into `/tmp`. diff --git a/website/docs/language/resources/provisioners/local-exec.mdx b/website/docs/language/resources/provisioners/local-exec.mdx deleted file mode 100644 index 6e31cc637b..0000000000 --- a/website/docs/language/resources/provisioners/local-exec.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -page_title: 'Provisioner: local-exec' -description: >- - The `local-exec` provisioner invokes a local executable after a resource is - created. This invokes a process on the machine running Terraform, not on the - resource. See the `remote-exec` provisioner to run commands on the resource. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# local-exec Provisioner - -The `local-exec` provisioner invokes a local executable after a resource is -created. This invokes a process on the machine running Terraform, not on the -resource. See the `remote-exec` -[provisioner](/terraform/language/resources/provisioners/remote-exec) to run commands on the -resource. - -Note that even though the resource will be fully created when the provisioner is -run, there is no guarantee that it will be in an operable state - for example -system services such as `sshd` may not be started yet on compute resources. - -~> **Important:** Use provisioners as a last resort. There are better alternatives for most situations. Refer to -[Declaring Provisioners](/terraform/language/resources/provisioners/syntax) for more details. - -## Example usage - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - command = "echo ${self.private_ip} >> private_ips.txt" - } -} -``` - -## Argument Reference - -The following arguments are supported: - -* `command` - (Required) This is the command to execute. It can be provided - as a relative path to the current working directory or as an absolute path. - The `command` is evaluated in a shell and can use environment variables for - variable substitution. We do not recommend using Terraform variables for variable - substitution because doing so can lead to shell injection vulnerabilities. Instead, you should pass Terraform variables to a command - through the `environment` parameter and use environment variable substitution - instead. Refer to the following OWASP article for additional information about injection flaws: [Code Injection](https://owasp.org/www-community/attacks/Code_Injection). - -* `working_dir` - (Optional) If provided, specifies the working directory where - `command` will be executed. It can be provided as a relative path to the - current working directory or as an absolute path. The directory must exist. - -* `interpreter` - (Optional) If provided, this is a list of interpreter - arguments used to execute the command. The first argument is the - interpreter itself. It can be provided as a relative path to the current - working directory or as an absolute path. The remaining arguments are - appended prior to the command. This allows building command lines of the - form "/bin/bash", "-c", "echo foo". If `interpreter` is unspecified, - sensible defaults will be chosen based on the system OS. - -* `environment` - (Optional) block of key value pairs representing the - environment of the executed command. inherits the current process environment. - -* `when` - (Optional) If provided, specifies when Terraform will execute the command. - For example, `when = destroy` specifies that the provisioner will run when the associated resource - is destroyed. Refer to [Destroy-Time Provisioners](/terraform/language/resources/provisioners/syntax#destroy-time-provisioners) - for details. - -* `quiet` - (Optional) If set to `true`, Terraform will not print the command to be executed to stdout, and will instead print "Suppressed by quiet=true". Note that the output of the command will still be printed in any case. - -### Interpreter Examples - -```hcl -resource "terraform_data" "example1" { - provisioner "local-exec" { - command = "open WFH, '>completed.txt' and print WFH scalar localtime" - interpreter = ["perl", "-e"] - } -} -``` - -```hcl -resource "terraform_data" "example2" { - provisioner "local-exec" { - command = "Get-Date > completed.txt" - interpreter = ["PowerShell", "-Command"] - } -} -``` - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - command = "echo $FOO $BAR $BAZ >> env_vars.txt" - - environment = { - FOO = "bar" - BAR = 1 - BAZ = "true" - } - } -} -``` diff --git a/website/docs/language/resources/provisioners/null_resource.mdx b/website/docs/language/resources/provisioners/null_resource.mdx deleted file mode 100644 index a286451ceb..0000000000 --- a/website/docs/language/resources/provisioners/null_resource.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -page_title: Provisioners Without a Resource -description: >- - A terraform_data managed resource allows you to configure provisioners that - are not directly associated with a single existing resource. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Provisioners Without a Resource - -If you need to run provisioners that aren't directly associated with a specific -resource, you can associate them with a `terraform_data`. - -Instances of [`terraform_data`](/terraform/language/resources/terraform-data) are treated -like normal resources, but they don't do anything. Like with any other resource -type, you can configure [provisioners](/terraform/language/resources/provisioners/syntax) -and [connection details](/terraform/language/resources/provisioners/connection) on a -`terraform_data` resource. You can also use its `input` argument, `triggers_replace` argument, and any -meta-arguments to control exactly where in the dependency graph its -provisioners will run. - -~> **Important:** Use provisioners as a last resort. There are better alternatives for most situations. Refer to -[Declaring Provisioners](/terraform/language/resources/provisioners/syntax) for more details. - -## Example usage - -```hcl -resource "aws_instance" "cluster" { - count = 3 - - # ... -} - -resource "terraform_data" "cluster" { - # Replacement of any instance of the cluster requires re-provisioning - triggers_replace = aws_instance.cluster[*].id - - # Bootstrap script can run on any instance of the cluster - # So we just choose the first in this case - connection { - host = aws_instance.cluster[0].public_ip - } - - provisioner "remote-exec" { - # Bootstrap script called with private_ip of each node in the cluster - inline = [ - "bootstrap-cluster.sh ${join(" ", aws_instance.cluster[*].private_ip)}", - ] - } -} -``` diff --git a/website/docs/language/resources/provisioners/remote-exec.mdx b/website/docs/language/resources/provisioners/remote-exec.mdx deleted file mode 100644 index 0b477f223a..0000000000 --- a/website/docs/language/resources/provisioners/remote-exec.mdx +++ /dev/null @@ -1,95 +0,0 @@ ---- -page_title: 'Provisioner: remote-exec' -description: >- - The `remote-exec` provisioner invokes a script on a remote resource after it - is created. This can be used to run a configuration management tool, bootstrap - into a cluster, etc. To invoke a local process, see the `local-exec` - provisioner instead. The `remote-exec` provisioner supports both `ssh` and - `winrm` type connections. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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-exec Provisioner - -The `remote-exec` provisioner invokes a script on a remote resource after it -is created. This can be used to run a configuration management tool, bootstrap -into a cluster, etc. To invoke a local process, see the `local-exec` -[provisioner](/terraform/language/resources/provisioners/local-exec) instead. The `remote-exec` -provisioner requires a [connection](/terraform/language/resources/provisioners/connection) -and supports both `ssh` and `winrm`. - -~> **Important:** Use provisioners as a last resort. There are better alternatives for most situations. Refer to -[Declaring Provisioners](/terraform/language/resources/provisioners/syntax) for more details. - -## Example usage - -```hcl -resource "aws_instance" "web" { - # ... - - # Establishes connection to be used by all - # generic remote provisioners (i.e. file/remote-exec) - connection { - type = "ssh" - user = "root" - password = var.root_password - host = self.public_ip - } - - provisioner "remote-exec" { - inline = [ - "puppet apply", - "consul join ${aws_instance.web.private_ip}", - ] - } -} -``` - -## Argument Reference - -The following arguments are supported: - -* `inline` - This is a list of command strings. The provisioner uses a default - shell unless you specify a shell as the first command (eg., `#!/bin/bash`). - You cannot provide this with `script` or `scripts`. - -* `script` - This is a path (relative or absolute) to a local script that will - be copied to the remote resource and then executed. This cannot be provided - with `inline` or `scripts`. - -* `scripts` - This is a list of paths (relative or absolute) to local scripts - that will be copied to the remote resource and then executed. They are executed - in the order they are provided. This cannot be provided with `inline` or `script`. - --> **Note:** Since `inline` is implemented by concatenating commands into a script, [`on_failure`](/terraform/language/resources/provisioners/syntax#failure-behavior) applies only to the final command in the list. In particular, with `on_failure = fail` (the default behaviour) earlier commands will be allowed to fail, and later commands will also execute. If this behaviour is not desired, consider using `"set -o errexit"` as the first command. - -## Script Arguments - -You cannot pass any arguments to scripts using the `script` or -`scripts` arguments to this provisioner. If you want to specify arguments, -upload the script with the -[file provisioner](/terraform/language/resources/provisioners/file) -and then use `inline` to call it. Example: - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "file" { - source = "script.sh" - destination = "/tmp/script.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/script.sh", - "/tmp/script.sh args", - ] - } -} -``` diff --git a/website/docs/language/resources/provisioners/syntax.mdx b/website/docs/language/resources/provisioners/syntax.mdx deleted file mode 100644 index c39f9c2e88..0000000000 --- a/website/docs/language/resources/provisioners/syntax.mdx +++ /dev/null @@ -1,357 +0,0 @@ ---- -page_title: Provisioners -description: >- - Provisioners run scripts on a local or remote machine during resource creation - or destruction. Learn how to declare provisioners in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Provisioners - -You can use provisioners to model specific actions on the local machine or on -a remote machine in order to prepare servers or other infrastructure objects -for service. - --> **Note:** We removed the Chef, Habitat, Puppet, and Salt Masterless provisioners in Terraform v0.15.0. Information about these legacy provisioners is still available in the documentation for [Terraform v1.1 (and earlier)](/terraform/language/v1.1.x/resources/provisioners/syntax). - -## Provisioners are a Last Resort - -> **Hands-on:** Try the [Provision Infrastructure Deployed with Terraform](/terraform/tutorials/provision?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorials to learn about more declarative ways to handle provisioning actions. - -Terraform includes the concept of provisioners as a measure of pragmatism, -knowing that there are always certain behaviors that cannot be directly -represented in Terraform's declarative model. - -However, they also add a considerable amount of complexity and uncertainty to -Terraform usage. Firstly, Terraform cannot model the actions of provisioners -as part of a plan because they can in principle take any action. Secondly, -successful use of provisioners requires coordinating many more details than -Terraform usage usually requires: direct network access to your servers, -issuing Terraform credentials to log in, making sure that all of the necessary -external software is installed, etc. - -The following sections describe some situations which can be solved with -provisioners in principle, but where better solutions are also available. We do -not recommend using provisioners for any of the use-cases described in the -following sections. - -Even if your specific use-case is not described in the following sections, we -still recommend attempting to solve it using other techniques first, and use -provisioners only if there is no other option. - -### Passing data into virtual machines and other compute resources - -When deploying virtual machines or other similar compute resources, we often -need to pass in data about other related infrastructure that the software on -that server will need to do its job. - -The various provisioners that interact with remote servers over SSH or WinRM -can potentially be used to pass such data by logging in to the server and -providing it directly, but most cloud computing platforms provide mechanisms -to pass data to instances at the time of their creation such that the data -is immediately available on system boot. For example: - -* Alibaba Cloud: `user_data` on - [`alicloud_instance`](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance) - or [`alicloud_launch_template`](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/launch_template). -* Amazon EC2: `user_data` or `user_data_base64` on - [`aws_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance), - [`aws_launch_template`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template), - and [`aws_launch_configuration`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_configuration). -* Amazon Lightsail: `user_data` on - [`aws_lightsail_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lightsail_instance). -* Microsoft Azure: `custom_data` on - [`azurerm_virtual_machine`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine) - or [`azurerm_virtual_machine_scale_set`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_scale_set). -* Google Cloud Platform: `metadata` on - [`google_compute_instance`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) - or [`google_compute_instance_group`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_group). -* Oracle Cloud Infrastructure: `metadata` or `extended_metadata` on - [`oci_core_instance`](https://registry.terraform.io/providers/oracle/oci/) - or [`oci_core_instance_configuration`](https://registry.terraform.io/providers/oracle/oci/). -* VMware vSphere: Attach a virtual CDROM to - [`vsphere_virtual_machine`](https://registry.terraform.io/providers/hashicorp/vsphere/latest/docs/resources/virtual_machine) - using the `cdrom` block, containing a file called `user-data.txt`. - -Many official Linux distribution disk images include software called -[cloud-init](https://cloudinit.readthedocs.io/en/latest/) that can automatically -process in various ways data passed via the means described above, allowing -you to run arbitrary scripts and do basic system configuration immediately -during the boot process and without the need to access the machine over SSH. - -> **Hands-on:** Try the [Provision Infrastructure with Cloud-Init](/terraform/tutorials/provision/cloud-init?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -If you are building custom machine images, you can make use of the "user data" -or "metadata" passed by the above means in whatever way makes sense to your -application, by referring to your vendor's documentation on how to access the -data at runtime. - -This approach is _required_ if you intend to use any mechanism in your cloud -provider for automatically launching and destroying servers in a group, -because in that case individual servers will launch unattended while Terraform -is not around to provision them. - -Even if you're deploying individual servers directly with Terraform, passing -data this way will allow faster boot times and simplify deployment by avoiding -the need for direct network access from Terraform to the new server and for -remote access credentials to be provided. - -### Provisioning files using cloud-config - -You can add the [`cloudinit_config`](https://registry.terraform.io/providers/hashicorp/cloudinit/latest/docs) data source to your Terraform configuration and specify the files you want to provision as `text/cloud-config` content. The `cloudinit_config` data source renders multi-part MIME configurations for use with [cloud-init](https://cloudinit.readthedocs.io/en/latest/). Pass the files in the `content` field as YAML-encoded configurations using the `write_files` block. - -In the following example, the `my_cloud_config` data source specifies a `text/cloud-config` MIME part named `cloud.conf`. The `part.content` field is set to [`yamlencode`](/terraform/language/functions/yamlencode), which encodes the `write_files` JSON object as YAML so that the system can provision the referenced files. - -```hcl -data "cloudinit_config" "my_cloud_config" { - gzip = false - base64_encode = false - - part { - content_type = "text/cloud-config" - filename = "cloud.conf" - content = yamlencode( - { - "write_files" : [ - { - "path" : "/etc/foo.conf", - "content" : "foo contents", - }, - { - "path" : "/etc/bar.conf", - "content" : file("bar.conf"), - }, - { - "path" : "/etc/baz.conf", - "content" : templatefile("baz.tpl.conf", { SOME_VAR = "qux" }), - }, - ], - } - ) - } -} -``` - -### Running configuration management software - -As a convenience to users who are forced to use generic operating system -distribution images, Terraform includes a number of specialized provisioners -for launching specific configuration management products. - -We strongly recommend not using these, and instead running system configuration -steps during a custom image build process. For example, -[HashiCorp Packer](https://www.packer.io/) offers a similar complement of -configuration management provisioners and can run their installation steps -during a separate build process, before creating a system disk image that you -can deploy many times. - -> **Hands-on:** Try the [Provision Infrastructure with Packer](/terraform/tutorials/provision/packer?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial. - -If you are using configuration management software that has a centralized server -component, you will need to delay the _registration_ step until the final -system is booted from your custom image. To achieve that, use one of the -mechanisms described above to pass the necessary information into each instance -so that it can register itself with the configuration management server -immediately on boot, without the need to accept commands from Terraform over -SSH or WinRM. - -### First-class Terraform provider functionality may be available - -It is technically possible to use the `local-exec` provisioner to run the CLI -for your target system in order to create, update, or otherwise interact with -remote objects in that system. - -If you are trying to use a new feature of the remote system that isn't yet -supported in its Terraform provider, that might be the only option. However, -if there _is_ provider support for the feature you intend to use, prefer to -use that provider functionality rather than a provisioner so that Terraform -can be fully aware of the object and properly manage ongoing changes to it. - -Even if the functionality you need is not available in a provider today, we -suggest to consider `local-exec` usage a temporary workaround and to also -open an issue in the relevant provider's repository to discuss adding -first-class provider support. Provider development teams often prioritize -features based on interest, so opening an issue is a way to record your -interest in the feature. - -Provisioners are used to execute scripts on a local or remote machine -as part of resource creation or destruction. Provisioners can be used to -bootstrap a resource, cleanup before destroy, run configuration management, etc. - -## How to use Provisioners - --> **Note:** Provisioners should only be used as a last resort. For most -common situations there are better alternatives. For more information, see -the sections above. - -If you are certain that provisioners are the best way to solve your problem -after considering the advice in the sections above, you can add a -`provisioner` block inside the `resource` block of a compute instance. - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - command = "echo The server's IP address is ${self.private_ip}" - } -} -``` - -The `local-exec` provisioner requires no other configuration, but most other -provisioners must connect to the remote system using SSH or WinRM. -You must include [a `connection` block](/terraform/language/resources/provisioners/connection) so that Terraform knows how to communicate with the server. - -Terraform includes several built-in provisioners. You can also use third-party provisioners as plugins, by placing them -in `%APPDATA%\terraform.d\plugins`, `~/.terraform.d/plugins`, or the same -directory where the Terraform binary is installed. However, we do not recommend -using any provisioners except the built-in `file`, `local-exec`, and -`remote-exec` provisioners. - -All provisioners support the `when` and `on_failure` meta-arguments, which -are described below (see [Destroy-Time Provisioners](#destroy-time-provisioners) -and [Failure Behavior](#failure-behavior)). - -### The `self` Object - -Expressions in `provisioner` blocks cannot refer to their parent resource by -name. Instead, they can use the special `self` object. - -The `self` object represents the provisioner's parent resource, and has all of -that resource's attributes. For example, use `self.public_ip` to reference an -`aws_instance`'s `public_ip` attribute. - --> **Technical note:** Resource references are restricted here because -references create dependencies. Referring to a resource by name within its own -block would create a dependency cycle. - -### Ephemeral values - --> **Note**: Ephemeral values are available in Terraform v1.10 and later. - -The configuration for a `provisioner` block may use ephemeral values, such as -[`ephemeral` resources](/terraform/language/resources/ephemeral), [`ephemeral` -local values](/terraform/language/values/locals#ephemeral-values), [`ephemeral` -variables](/terraform/language/values/variables#ephemeral), or [`ephemeral` -output -values](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files). - -Terraform does not store these values in your plan or state, or output them in -logs. - -### Sensitive values - -The configuration for a `provisioner` block may use sensitive values, such as -[`sensitive` variables](/terraform/language/values/variables#suppressing-values-in-cli-output) -or [`sensitive` output values](/terraform/language/values/outputs#sensitive-suppressing-values-in-cli-output). -Terraform suppresses sensitive values in all log output. - -## Creation-Time Provisioners - -By default, provisioners run when the resource they are defined within is -created. Creation-time provisioners are only run during _creation_, not -during updating or any other lifecycle. They are meant as a means to perform -bootstrapping of a system. - -If a creation-time provisioner fails, the resource is marked as **tainted**. -A tainted resource will be planned for destruction and recreation upon the -next `terraform apply`. Terraform does this because a failed provisioner -can leave a resource in a semi-configured state. Because Terraform cannot -reason about what the provisioner does, the only way to ensure proper creation -of a resource is to recreate it. This is tainting. - -You can change this behavior by setting the `on_failure` attribute to `continue`. Refer to [Failure Behavior](#failure-behavior) for additional information. - -## Destroy-Time Provisioners - -If `when = destroy` is specified, the provisioner will run when the -resource it is defined within is _destroyed_. - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - when = destroy - command = "echo 'Destroy-time provisioner'" - } -} -``` - -Destroy provisioners are run before the resource is destroyed. If they -fail, Terraform will error and rerun the provisioners again on the next -`terraform apply`. Due to this behavior, care should be taken for destroy -provisioners to be safe to run multiple times. - -~> **Note**: A resource's destroy-time provisioners do not run if you enable [`create_before_destroy`](/terraform/language/meta-arguments/lifecycle#syntax-and-arguments) on that resource. - -Destroy-time provisioners can only run if they remain in the configuration -at the time a resource is destroyed. If a resource block with a destroy-time -provisioner is removed entirely from the configuration, its provisioner -configurations are removed along with it and thus the destroy provisioner -won't run. To work around this, a multi-step process can be used to safely -remove a resource with a destroy-time provisioner: - -* Update the resource configuration to include `count = 0`. -* Apply the configuration to destroy any existing instances of the resource, including running the destroy provisioner. -* Remove the resource block entirely from configuration, along with its `provisioner` blocks. -* Apply again, at which point no further action should be taken since the resources were already destroyed. - -Because of this limitation, you should use destroy-time provisioners sparingly and with care. - -~> **NOTE:** A destroy-time provisioner within a resource that is tainted _will not_ run. This includes resources that are marked tainted from a failed creation-time provisioner or tainted manually using `terraform taint`. - -## Multiple Provisioners - -Multiple provisioners can be specified within a resource. Multiple provisioners -are executed in the order they're defined in the configuration file. - -You may also mix and match creation and destruction provisioners. Only -the provisioners that are valid for a given operation will be run. Those -valid provisioners will be run in the order they're defined in the configuration -file. - -Example of multiple provisioners: - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - command = "echo first" - } - - provisioner "local-exec" { - command = "echo second" - } -} -``` - -## Failure Behavior - -By default, provisioners that fail will also cause the Terraform apply -itself to fail. The `on_failure` setting can be used to change this. The -allowed values are: - -* `continue` - Ignore the error and continue with creation or destruction. - -* `fail` - Raise an error and stop applying (the default behavior). If this is a creation provisioner, - taint the resource. - -Example: - -```hcl -resource "aws_instance" "web" { - # ... - - provisioner "local-exec" { - command = "echo The server's IP address is ${self.private_ip}" - on_failure = continue - } -} -``` diff --git a/website/docs/language/resources/syntax.mdx b/website/docs/language/resources/syntax.mdx deleted file mode 100644 index 240aae4a88..0000000000 --- a/website/docs/language/resources/syntax.mdx +++ /dev/null @@ -1,220 +0,0 @@ ---- -page_title: Resources - Configuration Language -description: >- - Resources correspond to infrastructure objects like virtual networks or - compute instances. Learn about resource types, syntax, behavior, and - arguments. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Blocks - -> **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. - -_Resources_ are the most important element in the Terraform language. -Each resource block describes one or more infrastructure objects, such -as virtual networks, compute instances, or higher-level components such -as DNS records. - -For information about how Terraform manages resources after applying a configuration, refer to -[Resource Behavior](/terraform/language/resources/behavior). - -## Resource Syntax - -A `resource` block declares a resource of a specific type -with a specific local name. Terraform uses the name when referring to the resource -in the same module, but it has no meaning outside that module's scope. - -In the following example, the `aws_instance` resource type is named `web`. The resource type and name must be unique within a module because they serve as an identifier for a given resource. - -```hcl -resource "aws_instance" "web" { - ami = "ami-a1b2c3d4" - instance_type = "t2.micro" -} -``` - -Within the block body (between `{` and `}`) are the configuration arguments -for the resource itself. The arguments often depend on the -resource type. In this example, both `ami` and `instance_type` are special -arguments for [the `aws_instance` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance). - --> **Note:** Resource names must start with a letter or underscore, and may -contain only letters, digits, underscores, and dashes. - -Resource declarations can include more advanced features, such as single -resource declarations that produce multiple similar remote objects, but only -a small subset is required for initial use. - -## Resource Types - -Each resource is associated with a single _resource type_, which determines -the kind of infrastructure object it manages and what arguments and other -attributes the resource supports. - -### Providers - -A [provider](/terraform/language/providers/requirements) is a plugin for Terraform -that offers a collection of resource types. Each resource type is implemented by a provider. A -provider provides resources to manage a single cloud or on-premises -infrastructure platform. Providers are distributed separately from Terraform, -but Terraform can automatically install most providers when initializing -a working directory. - -To manage resources, a Terraform module must specify the required providers. Refer to -[Provider Requirements](/terraform/language/providers/requirements) for additional information. - -Most providers need some configuration to access their remote API, -which is provided by the root module. Refer to -[Provider Configuration](/terraform/language/providers/configuration) for additional information. - -Based on a resource type's name, Terraform can usually determine which provider to use. -By convention, resource type names start with their provider's preferred local name. -When using multiple configurations of a provider or non-preferred local provider names, -you must use [the `provider` meta-argument](/terraform/language/meta-arguments/resource-provider) -to manually choose a provider configuration. - -### Resource Arguments - -Most of the arguments within the body of a `resource` block are specific to the -selected resource type. The resource type's documentation lists which arguments -are available and how their values should be formatted. - -The values for resource arguments can make full use of -[expressions](/terraform/language/expressions) and other dynamic Terraform -language features. - -[Meta-arguments](#meta-arguments) are defined by Terraform -and apply across all resource types. - -### Documentation for Resource Types - -Every Terraform provider has its own documentation, describing its resource -types and their arguments. - -Some provider documentation is still part of Terraform's core documentation, -but the [Terraform Registry](https://registry.terraform.io/browse/providers) -is the main home for all publicly available provider docs. - -When viewing a provider's page on the Terraform -Registry, you can click the **Documentation** link in the header to browse its -documentation. The documentation is versioned. To choose a different version of the provider documentation, click on the version in the provider breadcrumbs to choose a version from the drop-down menu. - -## Meta-Arguments - -The Terraform language defines the following meta-arguments, which can be used with -any resource type to change the behavior of resources: - -- [`depends_on`, for specifying hidden dependencies](/terraform/language/meta-arguments/depends_on) -- [`count`, for creating multiple resource instances according to a count](/terraform/language/meta-arguments/count) -- [`for_each`, to create multiple instances according to a map, or set of strings](/terraform/language/meta-arguments/for_each) -- [`provider`, for selecting a non-default provider configuration](/terraform/language/meta-arguments/resource-provider) -- [`lifecycle`, for lifecycle customizations](/terraform/language/meta-arguments/lifecycle) -- [`provisioner`, for taking extra actions after resource creation](/terraform/language/resources/provisioners/syntax) - -## Removing Resources - --> **Note:** The `removed` block is available in Terraform v1.7 and later. For earlier Terraform versions, you can use the [`terraform state rm` CLI command](/terraform/cli/commands/state/rm) as a separate step. - -To remove a resource from Terraform, simply delete the `resource` block from your Terraform configuration. - -By default, after you remove the `resource` block, Terraform will plan to destroy any real infrastructure object managed by that resource. - -Sometimes you may wish to remove a resource from your Terraform configuration without destroying the real infrastructure object it manages. In this case, the resource will be removed from the [Terraform state](/terraform/language/state), but the real infrastructure object will not be destroyed. - -To declare that a resource was removed from Terraform configuration but that its managed object should not be destroyed, remove the `resource` block from your configuration and replace it with a `removed` block: - -```hcl -removed { - from = aws_instance.example - - lifecycle { - destroy = false - } -} -``` - -The `from` argument is the address of the resource you want to remove, without any instance keys (such as "aws_instance.example[1]"). - -The `lifecycle` block is required. The `destroy` argument determines whether Terraform will attempt to destroy the object managed by the resource or not. A value of `false` means that Terraform will remove the resource from state without destroying it. - -A `removed` block may also contain a [Destroy-Time Provisioner](/terraform/language/resources/provisioners/syntax#destroy-time-provisioners), so that the provisioner can remain in the configuration even though the `resource` block has been removed. - -```hcl -removed { - from = aws_instance.example - - lifecycle { - destroy = true - } - - provisioner "local-exec" { - when = destroy - command = "echo 'Instance ${self.id} has been destroyed.'" - } -} -``` - -The same referencing rules apply as in normal destroy-time provisioners, with only `count.index`, `each.key`, and `self` allowed. The provisioner must specify `when = destroy`, and the `removed` block must use `destroy = true` in order for the provisioner to execute. - -## Custom Condition Checks - -You can use `precondition` and `postcondition` blocks to specify assumptions and guarantees about how the resource operates. The following example creates a precondition that checks whether the AMI is properly configured. - -```hcl -resource "aws_instance" "example" { - instance_type = "t2.micro" - ami = "ami-abc123" - - lifecycle { - # The AMI ID must refer to an AMI that contains an operating system - # for the `x86_64` architecture. - precondition { - condition = data.aws_ami.example.architecture == "x86_64" - error_message = "The selected AMI must be for the x86_64 architecture." - } - } -} -``` - -[Custom condition checks](/terraform/language/expressions/custom-conditions#preconditions-and-postconditions) -can help capture assumptions so that future maintainers -understand the configuration design and intent. They also return useful -information about errors earlier and in context, helping consumers to diagnose -issues in their configuration. - -## Operation Timeouts - -Some resource types provide a special `timeouts` nested block argument that -allows you to customize how long certain operations are allowed to take -before being considered to have failed. -For example, [`aws_db_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance) -allows configurable timeouts for `create`, `update`, and `delete` operations. - -Timeouts are handled entirely by the resource type implementation in the -provider, but resource types offering these features follow the convention -of defining a child block called `timeouts` that has a nested argument -named after each operation that has a configurable timeout value. -Each of these arguments takes a string representation of a duration, such -as `"60m"` for 60 minutes, `"10s"` for ten seconds, or `"2h"` for two hours. - -```hcl -resource "aws_db_instance" "example" { - # ... - - timeouts { - create = "60m" - delete = "2h" - } -} -``` - -The set of configurable operations is chosen by each resource type. Most -resource types do not support the `timeouts` block at all. Consult the -documentation for each resource type to see which operations it offers -for configuration, if any. diff --git a/website/docs/language/resources/terraform-data.mdx b/website/docs/language/resources/terraform-data.mdx deleted file mode 100644 index 8153445b70..0000000000 --- a/website/docs/language/resources/terraform-data.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -page_title: The terraform_data Managed Resource Type -description: >- - Retrieves the root module output values from a Terraform state snapshot stored - in a remote backend. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `terraform_data` Managed Resource Type - -The `terraform_data` implements the standard resource lifecycle, but does not directly take any other actions. -You can use the `terraform_data` resource without requiring or configuring a provider. It is always available through a built-in provider with the [source address](/terraform/language/providers/requirements#source-addresses) `terraform.io/builtin/terraform`. - -The `terraform_data` resource is useful for storing values which need to follow a manage resource lifecycle, and for triggering provisioners when there is no other logical managed resource in which to place them. - - -## Example Usage (data for `replace_triggered_by`) - - -[The `replace_triggered_by` lifecycle argument](/terraform/language/meta-arguments/lifecycle#replace_triggered_by) requires all of the given addresses to be for resources, because the decision to force replacement is based on the planned actions for all of the mentioned resources. - -Plain data values such as [Local Values](/terraform/language/values/locals) and [Input Variables](/terraform/language/values/variables) don't have any side-effects to plan against and so they aren't valid in `replace_triggered_by`. You can use `terraform_data`'s behavior of planning an action each time `input` changes to _indirectly_ use a plain value to trigger replacement. - - -```hcl -variable "revision" { - default = 1 -} - -resource "terraform_data" "replacement" { - input = var.revision -} - -# This resource has no convenient attribute which forces replacement, -# but can now be replaced by any change to the revision variable value. -resource "example_database" "test" { - lifecycle { - replace_triggered_by = [terraform_data.replacement] - } -} -``` - -## Example Usage (`null_resource` replacement) - -```hcl -resource "aws_instance" "web" { - # ... -} - -resource "aws_instance" "database" { - # ... -} - -# A use-case for terraform_data is as a do-nothing container -# for arbitrary actions taken by a provisioner. -resource "terraform_data" "bootstrap" { - triggers_replace = [ - aws_instance.web.id, - aws_instance.database.id - ] - - provisioner "local-exec" { - command = "bootstrap-hosts.sh" - } -} -``` - - -## Argument Reference - -The following arguments are supported: - -* `input` - (Optional) A value which will be stored in the instance state, and reflected in the `output` attribute after apply. - -* `triggers_replace` - (Optional) A value which is stored in the instance state, and will force replacement when the value changes. - -## Attributes Reference - -In addition to the above, the following attributes are exported: - -* `id` - A string value unique to the resource instance. - -* `output` - The computed value derived from the `input` argument. During a plan where `output` is unknown, it will still be of the same type as `input`. diff --git a/website/docs/language/stacks/create/config.mdx b/website/docs/language/stacks/create/config.mdx deleted file mode 100644 index 11c811b888..0000000000 --- a/website/docs/language/stacks/create/config.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -page_title: Define configuration -description: Learn to write Stack configuration files to declare what infrastructure your Stack deploys. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Define configuration - -In the Stack configuration file, you declare what infrastructure components are part of the Stack. - -Your Stack configuration file defines multiple components that share a lifecycle you can repeatedly deploy. This helps ensure consistency across environments and reduces the complexity of provisioning at scale. - -## Background - -You declare the infrastructure that makes up your Stack in the Stack configuration file. Stack configuration files replace Terraform’s traditional root module and serve as the blueprint for what your Stack deploys. - -Stack configuration files use a new file type, `tfstack.hcl`, to define everything that shares your Stack’s lifecycle. After writing your Stack configuration, you can write a deployment configuration to dictate how HCP Terraform deploys your Stack’s infrastructure. - -As with Terraform configuration files, HCP Terraform processes all of the blocks in your Stack configuration and deployment configuration files in your Stack's root directory in dependency order. You can organize your Stack configuration into multiple files as in traditional Terraform configurations. - -### Requirements - -Before you begin writing your Stack configuration, ensure you have the `terraform-stacks-cli` for initializing and validating your Stack configurations. For installation guidance, refer to the [Stacks CLI reference](/terraform/language/stacks/reference/tfstacks-cli). - -## Define your Stack configuration - -We recommend [designing your Stack](/terraform/language/stacks/design) before you begin writing your configuration files. - -All of your Stack’s configuration files must use the `.tfstack.hcl` file type. You can set up your Stack configuration into multiple files as in traditional Terraform configurations. For example, you can have `variables.tfstack.hcl`, `providers.tfstack.hcl`, and we recommend creating one root-level file for your `component` blocks, such as `components.tfstack.hcl`. - -The `component` block defines the pieces that make up your Stack. Add a `component` block for each top-level module you want to include in the Stack. Specify the source module, inputs, and providers for each component. - -```hcl -# components.tfstack.hcl - -component "cluster" { - source = "./eks" - inputs = { - aws_region = var.aws_region - cluster_name_prefix = var.prefix - instance_type = "t2.medium" - } - providers = { - aws = provider.aws.this - random = provider.random.this - tls = provider.tls.this - cloudinit = provider.cloudinit.this - } -} -``` - -After establishing your top-level modules, you can use child modules without adding additional `component` blocks. - -The Stack configuration file type accepts most classic Terraform configuration blocks but with some key differences. For more details on declaring providers in Stacks, refer to [Declare providers](/terraform/language/stacks/create/declare-providers). For more information on the Stack configuration file type and all the blocks and attributes it accepts, refer to the [Configuration file reference](/terraform/language/stacks/reference/tfstack). - -The `component` block supports the `for_each` meta-argument if you need to replicate components across multiple instances. For example, the following configuration uses `for_each` to provision modules in multiple AWS regions for a given environment. - -```hcl -# components.tfstack.hcl - -component "s3" { - for_each = var.regions - - source = "./s3" - - inputs = { - region = each.value - } - - providers = { - aws = provider.aws.configurations[each.value] - random = provider.random.this - } -} -``` - -After writing your Stack configuration, use the Terraform Stacks CLI to validate it. - -## Validate your configuration - -Once you have finished your Stack configuration, use the `terraform-stacks-cli` tool to validate your configuration and generate the necessary provider lock files. - -```shell-session -$ tfstacks init -$ tfstacks validate -``` - -For installation guidance and more details, refer to the [Stacks CLI](/terraform/language/stacks/reference/tfstacks-cli). - -## Next steps - -If you have not yet defined the providers for your Stack, proceed to [Declare providers](/terraform/language/stacks/create/declare-providers). You can also learn how to [Authenticate your Stack](/terraform/language/stacks/deploy/authenticate) to ensure your providers are properly set up. diff --git a/website/docs/language/stacks/create/declare-providers.mdx b/website/docs/language/stacks/create/declare-providers.mdx deleted file mode 100644 index 042cf9c24e..0000000000 --- a/website/docs/language/stacks/create/declare-providers.mdx +++ /dev/null @@ -1,158 +0,0 @@ ---- -page_title: Declare providers -description: Learn how to declare providers in Stack configurations. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Declare providers - -Terraform relies on plugins called providers to interact with cloud providers, SaaS providers, and other APIs. - -Like traditional Terraform configurations, Terraform Stack configurations declare which providers they require at the top level so that Terraform can install and use them. - -Providers in Stack configurations differ from normal Terraform configurations in the following ways: -* Modules sourced by `component` blocks cannot declare their own providers. Instead, each `component` block accepts a top-level map of providers. -* You must pass attributes to providers using a `config` block. -* You define provider alias names in the header of its block. -* Providers in Stack configurations support the [`for_each`](/terraform/language/meta-arguments/for_each) meta argument. - -After defining your providers, you must use the Terraform Stacks CLI to install the providers and create a provider lock file before you can use deploy your Stack. - -## Use a provider in a Stack - -Define your Stack’s `provider` blocks in a top-level `.tfstack.hcl` file. The following example file named `providers.tfstack.hcl` defines an AWS provider. - -```hcl -# providers.tfstack.hcl - -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } -} - -# Setting "this" as the alias name -provider "aws" "this" { - config { - region = var.region - - assume_role_with_web_identity { - role_arn = var.role_arn - web_identity_token = var.identity_token - } - - default_tags { - tags = var.default_tags - } - } -} -``` - -When you define a provider, you must also add that provider to a `required_providers` to ensure the Terraform Stacks CLI knows which provider version to download. For more details on Stack-specific provider syntax, refer to the [Stack configuration file reference](/terraform/language/stacks/reference/tfstack). - -You must authenticate that provider to ensure the provider can create your infrastructure. Refer to [Authenticate a Stack](/terraform/language/stacks/deploy/authenticate) for details and examples. - -After you define your providers, you can pass them to your Stack’s `component` blocks. A `component` block accepts a mapping of provider names to the provider(s) on which your component’s module relies. - -After defining your Stack’s providers, pass each `component` block the provider(s) it requires. - -```hcl -# components.tfstack.hcl - -component "s3" { - source = "./s3" - inputs = { - aws_region = var.aws_region - } - providers = { - aws = provider.aws.this - } -} -``` - -After configuring your provider, you can use the Terraform Stacks CLI to [generate a provider lock file](/terraform/language/stacks/reference/tfstacks-cli#tfstack-providers-lock-command). - -### Dynamic provider configurations - -Unlike traditional Terraform providers, Stack providers also support the `for_each` meta-argument. The `for_each` meta-argument lets you dynamically create provider configurations based on your inputs, which is beneficial for multi-region deployments. - -```hcl -# providers.tfstack.hcl - -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } -} - - -provider "aws" "configurations" { -# This provider configuration iterates through and creates a configuration -# for each region. - for_each = var.regions - - config { - region = each.value - - assume_role_with_web_identity { - role_arn = var.role_arn - web_identity_token = var.identity_token - } - } -} -``` - -This example lets your Stack’s deployments use a separate AWS provider configuration for each region you defined in a `regions` variable. - -In your component configuration, you could the `for_each` block to define configuration in with multiple AWS providers. - - -```hcl -# components.tfstack.hcl - -component "s3" { - for_each = var.regions - - source = "./s3" - - inputs = { - region = each.value - } - - providers = { - aws = provider.aws.configurations[each.value] - random = provider.random.this - } -} -``` - -The components in this example use the `for_each` meta-argument to deploy their Terraform module in the region for the current deployment. - -### Provider support for Stack features - -For most providers, the version you use does not affect your Stack’s functionality. However, only certain providers and versions support [deferred changes](/terraform/cloud-docs/stacks/deploy/plans#deferred-changes). For example, you must use version 2.32.0 or higher of the Kubernetes provider to take advantage of deferred changes. - -Check your provider in the [Terraform registry](https://registry.terraform.io/) for more information on versions that support various Stack features. - -## Provider lock file - -A Stack cannot run without a lock file for its providers. After defining your providers, use the Terraform Stacks CLI to generate a `.terraform.lock.hcl` lock file. The `tfstacks providers lock` command creates and updates your `.terraform.lock.hcl` file. - -```shell-session -$ tfstacks providers lock -``` - -The `tfstacks providers lock` command uses the `required_providers` block from your configuration to download the listed providers and compute the provider lock hashes. The `tfstacks providers lock` command only checks the `required_providers` block, so you must list all of the providers you use in that block to ensure that the `tfstacks` CLI can find them. - -If you update your Stack’s providers, you must rerun the `tfstacks providers lock` command to update your Stack’s providers lock file. For more details, refer to [Terraform Stacks CLI](/terraform/language/stacks/reference/tfstacks-cli). - -## Next steps - -After declaring your providers, you can either finish [defining the rest of your Stack configuration](/terraform/language/stacks/create/config) or move on to [define your Stack’s deployment configuration](/terraform/language/stacks/deploy/config). diff --git a/website/docs/language/stacks/deploy/authenticate.mdx b/website/docs/language/stacks/deploy/authenticate.mdx deleted file mode 100644 index 41c84f6852..0000000000 --- a/website/docs/language/stacks/deploy/authenticate.mdx +++ /dev/null @@ -1,315 +0,0 @@ ---- -page_title: Authenticate a Stack -description: Learn how to set up OIDC authentication or use the store block to authenticate Stacks with their 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Authenticate a Stack - -You can authenticate a Stack in two ways: by using OIDC to dynamically authenticate with the built-in `identity_token` block or by accessing existing authentication credentials with the `store` block. We recommend authenticating your Stack with OIDC because using static credentials to authenticate providers presents a security risk, even if you rotate your credentials regularly. - -## Authenticate with OIDC - -[OpenID Connect](https://openid.net/connect/) (OIDC) is an identity layer on top of the OAuth 2.0 protocol. You can use HCP Terraform’s [Workload identity](/terraform/cloud-docs/workspaces/dynamic-provider-credentials/workload-identity-tokens) tokens, built on the OpenID Connect protocol, to securely connect and authenticate your Stacks with cloud providers. - --> **Hands on**: Walk through setting up OIDC for a Stack in the [Deploy a Stack with HCP Terraform](/terraform/tutorials/cloud/stacks-deploy) tutorial. - -Stacks have a built-in `identity_token` block that creates workload identity tokens, also known as JWT tokens. You can use these tokens to authenticate Stacks with Terraform providers securely. - -This guide covers how to set up OIDC for Stacks using the `identity_token` block. - -### Overview - -The details of Stack authentication differ based on which cloud provider you are setting up, but the basic steps remain the same: - -1. Set up the trust configuration between your cloud provider and HCP Terraform, which usually includes creating roles and policies for your cloud provider. -1. Add an `identity_token` block to your Stack’s deployment file using the audience and roles you created in the previous step. - -Your deployments can reference the value of the `identity_token` block to pass the trust relationship role to your Stack’s operations. - -### Configure trust configuration - -In this example, you will set up an example trust policy with AWS. For examples of setting up trust policies with other providers, refer to our [repository of example configurations](https://github.com/hashicorp-guides/terraform-stacks-identity-tokens/tree/main). - -We recommend using Terraform to create and configure the trust relationship and permissions for the cloud provider you want to authenticate with. Using the following Terraform configuration, [create a new workspace](/terraform/cloud-docs/workspaces/create) and configure the `aws_region`, `tf_organization`, `tf_project,` and `tf_stack` variables for your specific set up. - -```hcl -# main.tf - -variable "aws_region" { - type = string - description = "The AWS region to create the role in." -} - -variable "tf_organization" { - type = string - description = "The name of the organization that this workspace and Stack live in." -} - -variable "tf_project" { - type = string - description = "The name of the project that this workspace and Stack live in." -} - -variable "tf_stack" { - type = string - description = "The name of the Stack you will you use this token in." -} - -provider "aws" { - region = var.aws_region -} - -resource "aws_iam_openid_connect_provider" "stacks_openid_provider" { - url = "https://app.terraform.io" - client_id_list = ["aws.workload.identity"] - - # This is the thumbprint of https://app.terraform.io as of 2024/08/07 - # Refer to "Adjust access of trust" to learn how to update this thumbprint - thumbprint_list = ["9e99a48a9960b14926bb7f3b02e22da2b0ab7280"] -} - -resource "aws_iam_role" "stacks_role" { - name = "stacks-${var.tf_organization}-${var.tf_project}-${var.tf_stack}" - assume_role_policy = data.aws_iam_policy_document.stacks_role_policy.json -} - -data "aws_iam_policy_document" "stacks_role_policy" { - statement { - effect = "Allow" - principals { - type = "Federated" - identifiers = [aws_iam_openid_connect_provider.stacks_openid_provider.arn] - } - actions = ["sts:AssumeRoleWithWebIdentity"] - condition { - test = "StringEquals" - variable = "app.terraform.io:aud" - values = ["aws.workload.identity"] - } - condition { - test = "StringLike" - variable = "app.terraform.io:sub" - # This value dictates which HCP Terraform organizations, projects, - # and stacks can assume the new role you are creating. - # - # You can widen access to an entire organization or project by - # tweaking the value below. You can also restrict access to specific - # deployments or operations. Refer to Configure trust for more information. - values = ["organization:${var.tf_organization}:project:${var.tf_project}:stack:${var.tf_stack}:*"] - } - } -} - -# Now, you give the new role access to things you want to manage in your Stack. -# -# The policies below are too broad for a production use case, but you set them -# broadly for now to ensure this Stacks can do anything during development and -# testing. In practice, only give your Stack access to what it needs to manage. - -resource "aws_iam_role_policy_attachment" "iam" { - role = aws_iam_role.stacks_role.name - policy_arn = "arn:aws:iam::aws:policy/IAMFullAccess" -} - -resource "aws_iam_role_policy_attachment" "sudo" { - role = aws_iam_role.stacks_role.name - policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess" -} - -# Your workspace returns this output role, which you use to configure your -# deployments. -output "role_arn" { - value = aws_iam_role.stacks_role.arn -} -``` - -After setting up your workspace in HCP Terraform, perform a plan and apply operation. HCP Terraform will create your OpenID provider, policy, and role before outputting your new role’s ARN with the `role_arn` output. Copy your new AWS ARN role because this is the value you use to configure your cloud provider with your Stack and HCP Terraform. - -#### Adjust access of trust - -Workload identity tokens contain useful metadata in their payloads, known as claims. Once a cloud platform verifies a token using HCP Terraform’s public key, it can look at the identity token's claims to match it to the correct permissions or reject it. - -You do not need to understand the full token specification or what every claim means, but you can use the claims to adjust your trust relationship. - -Workload identity tokens commonly reference the following claims. - -| Claim | Explanation | -| :---- | :---- | -| `jti` (JWT ID) | A unique identifier for each token, which is a UUID. | -| `iss` (issuer) | Full URL of the HCP Terraform instance that signed the token. For example, “https://app.terraform.io”. | -| `iat` (issued at) | Unix timestamp when the token was issued. May be required by certain relying parties. | -| `nbf` (not before) | Unix Timestamp when the token can start being used. Should be the same as `iat` for your purposes and may be required by certain relying parties. | -| `aud` (audience) | Intended audience for the token. For example, “api://AzureADTokenExchange” for Azure. | -| `exp` (expiration) | Unix timestamp based on the timeout of the operation phase that it was issued for. | -| `sub` (subject) | Fully qualified path to a Stack deployment, followed by the operation type:
`organization::project::stack::deployment:my-deployment-name:operation:`

For example:
`organization:My_Org:project:My_Project:stack:My_Stack:deployment:staging:operation:apply` | - -You can further customize your token’s permissions using the following custom claims. - -| Claim | Explanation | -| :---- | :---- | -| `terraform_operation` ("run phase") | The Terraform operation this token was issued for. For example, “plan” or “apply”. | -| `terraform_stack_deployment_name` | Name of the deployment that the operation is for. | -| `terraform_stack_id` (stack ID) | External ID of the Stack that the operation is for. | -| `terraform_stack_name` (stack name) | Name of the Stack that the operation is for. | -| `terraform_project_id` (project ID) | External ID of the project that the operation is taking place in. Useful if you want to use the same role across Stacks in a given project. | -| `terraform_project_name` (project name) | Name of the project that the operation is taking place in. | -| `terraform_organization_id` (organization ID) | External ID of the HCP Terraform organization that the operation is taking place in. Useful if you are in a large company that may have more than one organization or if you want to use the same role across your entire organization. | -| `terraform_organization_name` (organization name) | Name of the HCP Terraform organization that the operation is taking place in. | -| `terraform_plan_id` (plan ID) | External ID of the plan that this token is being used for creating or applying. This might be used to track down where a token has been leaked from or to block a specific token if it has been leaked. | - -You can also update your configuration to use the current thumbprint for HCP Terraform by running the following command and removing the colons from the value it returns. - -```shell-session -$ echo | openssl s_client -showcerts -servername app.terraform.io -connect app.terraform.io:443 2>/dev/null | openssl x509 -fingerprint -noout -sha1 -sha1 Fingerprint=FD:88:23:AE:FB:96:13:28:A1:34:70:6D:C8:57:5A:17:0F:0B:B3:7C -``` - -### Configure HCP Terraform - -Stacks use the [`identity_token` block](/terraform/language/stacks/reference/tfdeploy#identity_token-block-configuration) to define a JSON Web Token (JWT) for a specific deployment. This token enables OIDC-based authentication, allowing your Stack deployments to securely connect to cloud providers like AWS, Azure, and GCP. - -When you define the `identity_token` block, you specify its audience. For example, the example Stack deployment configuration defines an `identity_token` block specifying the AWS audience. - -```hcl -identity_token "aws" { - audience = ["aws.workload.identity"] -} -``` - -Once defined, you can reference an identity token in a deployment's input variables and reference that token in a provider’s configuration. - -You also need to add your trust relationship, your role ARN, to configure your token with the trust relationship to authenticate AWS resources. - -```hcl -# deployments.tfdeploy.hcl - -identity_token "aws" { - audience = ["aws.workload.identity"] -} - -deployment "development" { - inputs = { - role_arn = "" - identity_token = identity_token.aws.jwt - } -} -``` - -Now, the deployments are authenticated with AWS and can pass the trust configuration to your Stack’s providers for authentication. - -```hcl -# variables.tfstack.hcl - -variable "role_arn" { - type = string -} - -variable "identity_token" { - type = string - ephemeral = true -} - -# providers.tfstack.hcl - -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } -} - -provider "aws" "this" { - config { - region = var.region - assume_role_with_web_identity { - role_arn = var.aws_role - web_identity_token = var.aws_token - } - } -} -``` - -With this setup, each of your deployments pass the ARN of your trust relationship role and a JWT token generated by AWS each time you plan or apply your Stack. Each of your deployments uses their own role, configured with the specific permissions you require. - -For more examples of setting up OIDC with different providers, refer to our [repository of example configurations](https://github.com/hashicorp-guides/terraform-stacks-identity-tokens/tree/main). - -## Authenticate with existing credentials - -You can use the `store` block to define key-value secrets in your deployment configuration and then access those values in your deployments. - -You can use the `store` block to access credentials stored in an [HCP Terraform variable set](/terraform/cloud-docs/workspaces/variables/managing-variables#variable-sets). This example uses a `store` block with a variable set to access credentials stored in HCP Terraform. For more information about using `store` blocks, refer to the [Deployment configuration reference](/terraform/language/stacks/reference/tfdeploy). - -Before writing any configuration, ensure your Stack can access the variable set you are targeting by allowing your project to access the set or making the set globally available. - -Next, add a `store` block to your deployment configuration file to access your variable set. Once defined, your deployments can access your variable set’s values. - -```hcl -# deployments.tfdeploy.hcl - -# Source environment secrets from your HCP Terraform variable set -store "varset" "tokens" { - id = "varset-" - category = "env" -} - -# Access your variable set's value using your store and pass them into your -# deployment's inputs. -deployment "test" { - inputs = { - access_key = store.varset.tokens.AWS_ACCESS_KEY_ID - secret_key = store.varset.tokens.AWS_SECRET_ACCESS_KEY - session_token = store.varset.tokens.AWS_SESSION_TOKEN - } -} -``` - -For example, if your `test` deployment can use your `store` to access your variable set’s keys, and therefore, your variable set’s AWS provider credentials. - -Your `test` deployment can define your AWS credentials as `inputs`, allowing your `providers` to access those credentials. - -```hcl -# providers.tfstack.hcl - -variable "access_key" { - description = "AWS access key" - type = string - ephemeral = true -} - -variable "secret_key" { - description = "AWS sensitive secret key." - type = string - sensitive = true - ephemeral = true -} - -variable "session_token" { - description = "AWS session token." - type = string - sensitive = true - ephemeral = true -} - -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } -} - -provider "aws" "this" { - config { - access_key = var.access_key - secret_key = var.secret_key - token = var.session_token - } -} -``` - -This example allows your `aws.this` provider to authenticate to AWS using the credentials from a variable set stored in HCP Terraform. For more information about using `store` blocks, refer to the [Deployment configuration reference](/terraform/language/stacks/reference/tfdeploy). \ No newline at end of file diff --git a/website/docs/language/stacks/deploy/conditions.mdx b/website/docs/language/stacks/deploy/conditions.mdx deleted file mode 100644 index 55cb03b91b..0000000000 --- a/website/docs/language/stacks/deploy/conditions.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -page_title: Set conditions for deployment plans -description: Learn how to use the orchestrate block to automatically approve Stack deployment plans and help you manage your Stack deployments at scale. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Set conditions for deployment plans - -Orchestration rules allow you to automate aspects of your Stack deployments, such as auto-approving plans when those plans meet certain conditions. By setting orchestration rules, you can help streamline managing many deployments. - -## Create orchestration rules - -Add `orchestrate` blocks to define rules for handling deployment plans in your deployment configuration file (`tfdeploy.hcl`). - -The `orchestrate` block uses a `check` block to determine if a condition has passed or not, and every condition must pass for the `orchestrate` rule to take effect. For details on the syntax of an `orchestrate` block, refer to the [Deployment configuration file reference](/terraform/language/stacks/reference/tfdeploy). - -### Orchestrate rule types - -There are two orchestration rule types to choose from: - -1. The `auto_approve` rule executes after a Stack creates a plan and automatically approves a plan if all checks pass. -1. The `replan` rule executes after a Stack applies a plan, automatically triggering a replan if all the checks pass. - -The `auto_approve` rule is helpful when you know you want a certain type of plan to go ahead without manual intervention. For example, Stacks have a default `auto_approve` rule named `empty_plan`, which automatically approves a plan if it has no changes. - -As another example, you could create a rule that automatically approves deployments if a component has not changed. - -```hcl -# deployments.tfdeploy.hcl - -orchestrate "auto_approve" "no_pet_changes" { - check { - # Check that the pet component has no changes - condition = context.plan.component_changes["component.pet"].total == 0 - reason = "Not automatically approved because changes proposed to pet component." - } -} -``` - -The above `orchestrate` block automatically approves plans if they do not include any changes for the `pet` component. - -The `replan` rule is helpful when you need your Stack to perform another plan after it applies the last one. You could create a rule to automatically replan a deployment if the production deployment errors out. - -```hcl -# deployments.tfdeploy.hcl - -orchestrate "replan" "replan_prod_for_errors" { - check { - condition = context.plan.deployment == deployment.production - reason = "Only automatically replan production deployments." - } - - check { - condition = context.plan.applyable == false - reason = "Only automatically replan plans that were not applyable." - } - - check { - condition = context.plan.replans < 2 - reason = "Only automatically replan failed plans once." - } -} -``` - -The above `orchestrate` block triggers a replan if the production deployment of a Stack errors out and if HCP Terraform hasn't already attempted to replan. - -### Leverage orchestration context - -The `orchestrate` block can use the `context` variable, which provides access to detailed information about the deployment plan, such as the number of changes, the specific components involved, and the deployment’s status. - -Use `context` to create more sophisticated checks and conditions. For example, you can automatically approve all planning operations. - -```hcl -# deployments.tfdeploy.hcl - -orchestrate "auto_approve" "allow_plans" { - check { - # Check that the operation is a plan - condition = context.operation == "plan" - reason = "Apply operations need manual approval." - } -} -``` - -Another example of using `context` is automatically approving plans that do not remove resources in non-production deployments. - -```hcl -# deployments.tfdeploy.hcl -orchestrate "auto_approve" "safe_plans" { - # Ensure that no resource is removed. - check { - condition = context.plan.changes.remove == 0 - reason = "Plan is destroying ${context.plan.changes.remove} resources." - } - - # Ensure that the deployment is not your production environment. - check { - condition = context.plan.deployment != deployment.production - reason = "Production plans are not eligible for auto_approve." - } -} -``` - -For more information on the information available in the context variable, refer to the [Deployment configuration file reference](/terraform/language/stacks/reference/tfdeploy). - -## Next steps - -With your Stack and deployment configurations complete, your Stack is ready to be deployed by HCP Terraform. To learn more about creating a Stack in HCP Terraform, refer to [Create a Stack](/terraform/cloud-docs/stacks/create). diff --git a/website/docs/language/stacks/deploy/config.mdx b/website/docs/language/stacks/deploy/config.mdx deleted file mode 100644 index 2f7b346dbc..0000000000 --- a/website/docs/language/stacks/deploy/config.mdx +++ /dev/null @@ -1,121 +0,0 @@ ---- -page_title: Define deployment configuration -description: Learn how to write stack deployment configuration files to define how to deploy your stack’s 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Define deployment configuration - -In Stacks, deployments allow you to replicate infrastructure across multiple environments, regions, or accounts. Each deployment runs in its own isolated agent, ensuring that changes in one deployment do not affect others. - --> **Note**: HCP Terraform supports up to a maximum of 20 deployments. - -Learn how to write deployment configuration files that allow you to specify the environments, regions, and other parameters that will vary across deployments, while keeping your stack’s configuration nonrepetitive and reusable. - -## Background - -The deployment configuration file (`tfdeploy.hcl`) defines how many times HCP Terraform should deploy a stack’s infrastructure. A stack must have at least one `deployment` block. Adding a new `deployment` block tells Terraform to redeploy a stack’s infrastructure with that `deployment` block’s input values. - -You can automatically manage plans for your deployments by defining orchestrate blocks to create orchestration rules for your stack deployments. For example, you can set up automatic approvals when a deployment meets specific criteria. Learn more about orchestrating deployments in [Set conditions for deployment plans](/terraform/language/stacks/deploy/conditions). - -## Write a deployment configuration file - -Deployment configuration files live at the top level of your repository and use the `.tfdeploy.hcl` file extension. We recommend naming your deployments file `deployments.tfdeploy.hcl`. In your deployment configuration file, create a new `deployment` block for each environment or region where you want to deploy your stack. - -```hcl -# deployments.tfdeploy.hcl - -deployment "production" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - } -} -``` - -The `deployment` block accepts a map of `inputs` where you can specify any unique configurations that deployment may need. The `deployment` block does not accept any meta-arguments. - -```hcl -# deployments.tfdeploy.hcl - -deployment "production" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - } -} - -deployment "staging" { - inputs = { - aws_region = "us-west-1" - instance_count = 1 - } -} -``` - -You can also specify `identity_token` blocks and `orchestrate` blocks in a deployment configuration file. - -## Deployment authentication - -The `identity_token` block tells HCP Terraform to generate a JSON Web Token (JWT) for that deployment’s components to authenticate to providers using OIDC. For example, you can set up your deployment to authenticate with the AWS provider using a particular role ARN. - -```hcl -# deployments.tfdeploy.hcl - -identity_token "aws" { - audience = ["aws.workload.identity"] -} - -deployment "staging" { - inputs = { - aws_region = "eu-west-1" - role_arn = "arn:aws:iam::123456789101:role/my-oidc-role" - aws_token = identity_token.aws.jwt - } -} -``` - -That deployment generates a JWT token named `aws_token`, which is available to that deployment’s components and providers. - -```hcl -# providers.tfstack.hcl - -provider "aws" "this" { - config { - region = var.aws_region - assume_role_with_web_identity { - role_arn = var.aws_role - web_identity_token = var.aws_token - } - } -} -``` - -For more details and examples of using the `identity_token` block, refer to [Authenticate a stack](/terraform/language/stacks/deploy/authenticate). - -## Automatically manage deployments - -The `orchestrate` block lets you codify your stack’s behavior by creating orchestration rules, enabling you to manage deployments at scale. For example, you could set an orchestration rule to automatically approve plans or apply operations that don’t contain any changes. - -```hcl -# deployments.tfdeploy.hcl - -orchestrate "auto_approve" "no_pet_changes" { - check { - # Check that the pet component has no changes - condition = context.plan.component_changes["component.pet"].total == 0 - reason = "Changes proposed to pet component." - } -} -``` - -For more information and examples of using the `orchestrate` block, refer to [Set conditions for deployment plans](/terraform/language/stacks/deploy/conditions). - -## Next steps - -Refer to the [Deployment file reference](/terraform/language/stacks/reference/tfdeploy) to learn more about the syntax of the blocks and attributes you can use in deployment configuration files. Refer to [Create a stack](/terraform/cloud-docs/stacks/create) to learn how to deploy your stack’s infrastructure with HCP Terraform. diff --git a/website/docs/language/stacks/deploy/pass-data.mdx b/website/docs/language/stacks/deploy/pass-data.mdx deleted file mode 100644 index 7e87006ab2..0000000000 --- a/website/docs/language/stacks/deploy/pass-data.mdx +++ /dev/null @@ -1,118 +0,0 @@ ---- -page_title: Pass data from one Stack to another -description: Learn how to link Stacks together to pass data from one Stack to another using `publish_output` blocks to export data and `upstream_input` blocks to consume that 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Pass data from one Stack to another - -If you have multiple Stacks that do not share a provisioning lifecycle, you can link Stacks together to export data from one Stack for another to consume. If the output value of a Stack changes after a run, HCP Terraform automatically triggers runs for any Stacks that depend on those outputs. - -## Background - -You may need to pass data between different Stacks in your project. For example, one Stack in your organization may manage shared services, such as networking infrastructure, and another Stack may manage application components. Using separate Stacks lets you manage the infrastructure independently, but you may still need to share data from your networking Stack to your application Stack. - -To output information from a Stack, declare a `publish_output` block in the deployment configuration of the Stack exporting data. We refer to the Stack that declares a `publish_output` block as the upstream Stack. - -To consume the data exported by the upstream Stack, declare an `upstream_input` block in the deployment configuration of a different Stack in the same project. We refer to the Stack that declares an `upstream_input` block as the downstream Stack. - -## Requirements - -The `publish_output` and `upstream_input` blocks require at least Terraform version `terraform_1.10.0-alpha20241009` or higher. Download the [latest version of Terraform](https://releases.hashicorp.com/terraform/) to use the most up-to-date functionality. - -Downstream Stacks must also reside in the same project as their upstream Stacks. - -## Declare outputs - -You must declare a `publish_output` block in your deployment configuration for each value you want to output from your current Stack. - -For example, you can add a `publish_output` block for the `vpc_id` in your upstream Stack’s deployment configuration. You can directly reference a deployment's values with the `deployment.deployment_name` syntax. - - - -```hcl -# Networking Stack deployment configuration - -publish_output "vpc_id" { - description = "The networking Stack's VPC's ID." - value = deployment.network.vpc_id -} -``` - - - -After applying your configuration, any Stack in the same project can now reference your network deployment's `vpc_id` output by declaring an `upstream_input` block. - -Once you apply a Stack configuration version that includes your `publish_output` block, HCP Terraform publishes a snapshot of those values, which allows HCP Terraform to resolve them. Meaning, you must apply your Stack’s deployment configuration before any downstream Stacks can reference your Stack's outputs. - -Learn more about the [`publish_output` block](/terraform/language/stacks/reference/tfdeploy#publish_output-block-configuration). - -## Consume the output from an upstream Stack - -Declare an `upstream_input` block in your Stack’s deployment configuration to read values from another Stack's `publish_output` block. Adding an `upstream_input` block creates a dependency on the upstream Stack. - -For example, if you want to use the output `vpc_id` from an upstream Stack in the same project, declare an `upstream_input` block in your deployment configuration. - - - -```hcl -# Application Stack deployment configuration - -upstream_input "network_stack" { - type = "stack" - source = "app.terraform.io/hashicorp/Default Project/networking-stack" -} - -deployment "application" { - inputs = { - vpc_id = upstream_input.network_stack.vpc_id - } -} -``` - - - -After pushing your Stack's configuration into HCP Terraform, HCP Terraform searches for the most recently published snapshot of the upstream Stack your configuration references. If no snapshot exists, the downstream Stack's run fails. - -If HCP Terraform finds a published snapshot for your referenced upstream Stack, then all of that Stack's outputs are available to this downstream Stack. Add `upstream_input` blocks for every upstream Stack you want to reference. Learn more about the [`upstream_input` block](/terraform/language/stacks/reference/tfdeploy#upstream_input-block-configuration). - - -## Trigger runs when output values change - -If an upstream Stack's published output values change, HCP Terraform automatically triggers runs for any downstream Stacks that rely on those outputs. - -In the following example, the `application` deployment depends on the upstream networking Stack. - - - -```hcl -# Application Stack deployment configuration - -upstream_input "network_stack" { - type = "stack" - source = "app.terraform.io/hashicorp/Default Project/networking-stack" -} - -deployment "application" { - inputs = { - vpc_id = upstream_input.network_stack.vpc_id - } -} -``` - - - -The application Stack depends on the networking Stack’s output, so if the `vpc_id` changes then HCP Terraform triggers a new run for the application Stack. This approach allows you to decouple Stacks that have separate life cycles and ensures that updates in an upstream Stack propagate to downstream Stacks. - -## Remove upstream Stack dependencies - -To stop depending on an upstream Stack’s outputs, do the following in your downstream Stack's deployment configuration: - -1. Remove the upstream Stack's `upstream_input` block -1. Remove any references to the upstream Stack's outputs -1. Push your configuration changes to HCP Terraform and apply the new configuration diff --git a/website/docs/language/stacks/design.mdx b/website/docs/language/stacks/design.mdx deleted file mode 100644 index 3c82f9e7c7..0000000000 --- a/website/docs/language/stacks/design.mdx +++ /dev/null @@ -1,72 +0,0 @@ ---- -page_title: Design a Stack -description: Learn how to design a Stack that aligns with your existing infrastructure and deployment needs. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Design a Stack - -Stacks allow you to break down your existing infrastructure into logical components, making it easier to deploy and manage as a cohesive system. Designing a Stack begins with planning how to structure your infrastructure and thinking about how you intend to deploy the resources your Stack defines. - -## Background - -Every Stack requires two files: a Stack configuration file and a deployment configuration file. The Stack configuration file defines the infrastructure your Stack will provision when you deploy it. The deployment configuration files are where you define how many times to deploy the infrastructure your Stack defines. - -Before writing your Stack configuration, we recommend planning and designing how you want to use your new Stack: - -* Understand your existing infrastructure and break it down into manageable components. -* Understand how you want to deploy the infrastructure your Stack defines. -* Align your Stack’s component organization with your deployment strategy. - -You aim to create a flexible and reusable Stack configuration, enabling you to manage your infrastructure lifecycle efficiently. - -## Understand your infrastructure - -Before writing your Stack configuration, we recommend assessing your current infrastructure setup and planning how you want to deploy your Stack’s infrastructure. - -### Break down your infrastructure - -Each Stack should represent a single system or application with a shared lifecycle. Start by analyzing your current infrastructure and identifying the components HCP Terraform should manage together. Components are typically groups of related resources, such as an application’s backend, frontend, or database layer, deployed and scaled together. - -We recommend structuring your Stacks along technical boundaries to keep them modular and manageable. For example, you can create a dedicated Stack for shared services, such as networking infrastructure for VPCs, subnets, or routing tables, and separate Stacks for application components that consume those shared services. This separation allows you to manage shared services independently while passing information between Stacks. For more details, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data). - -### Sketch out your configuration - -We recommend sticking to technical boundaries when structuring a Stack configuration. A single Stack should represent a single system with a shared lifecycle. - -While keeping a Stack as self-contained as possible is ideal, there are valid cases where a Stack must consume outputs from another Stack. For example, a shared networking Stack can publish outputs, such as `vpc_id` or subnet IDs, that downstream application Stacks can consume as inputs. This approach ensures modularity and allows you to manage dependencies between Stacks using well-defined interfaces. For more details, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data). - -Plan to add a component block to your configuration for every top-level module you want to include in your Stack. After establishing your top-level modules, you can use child modules without adding additional `component` blocks. - -## Plan your deployments - -Stack deployments define how to repeat your Stack's defined infrastructure. We recommend considering how HCP Terraform should deploy the infrastructure your Stack defines. Your deployment plan can change depending on whether you need separate deployments for different environments, cloud provider accounts, or regions. - -If your deployment process requires automation, such as auto-approving specific changes in your test deployment, you can also design orchestration rules to help manage your Stack deployments. Learn more about [setting conditions for stack deployment plans](/terraform/language/stacks/deploy/conditions). - -### Plan for scalability - -When designing your Stack, consider how it should scale as your infrastructure grows. For example, if you anticipate adding more environments or regions, design your Stack to accommodate these changes. - -To keep your Stack configuration concise, you can use the [locals block](/terraform/language/values/locals) to share values across your deployments. - -```hcl -# deployments.tfdeploy.hcl - -# Define variables that multiple deployments use. -locals { - tf_organization = "" - tf_project_name = "" -} -``` - -Additionally, using meta-arguments like `for_each` in your configuration can help streamline the creation of multiple components, making your configuration more flexible and scalable. - -## Next steps - -After planning out your Stack, learn how to make your design a reality by [defining a Stack configuration](/terraform/language/stacks/create/config). diff --git a/website/docs/language/stacks/index.mdx b/website/docs/language/stacks/index.mdx deleted file mode 100644 index 6b9d7d2b7f..0000000000 --- a/website/docs/language/stacks/index.mdx +++ /dev/null @@ -1,80 +0,0 @@ ---- -page_title: Stacks overview -description: Stacks are a configuration layer that simplify managing infrastructure modules. Learn how Stacks help you provision and coordinate your infrastructure lifecycle at scale. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Stacks overview - -As your infrastructure grows, managing Terraform configurations becomes increasingly complex. Stacks are a powerful configuration layer in HCP Terraform that simplifies managing your infrastructure modules and then repeating that infrastructure. - -> **Hands-on**: Try out the [Deploy a Stack with HCP Terraform](/terraform/tutorials/cloud/stacks-deploy) tutorial to get started with Stacks quickly. - -Stacks replace Terraform's traditional root module structure with a new configuration layer of modular components built on top of your Terraform child and shared modules. Stacks enable you to provision and coordinate your infrastructure lifecycle at scale, offering an organized and reusable approach that expands upon infrastructure as code (IaC). - --> **Public Beta**: Stacks are in public beta. Once we generally release them, we do not guarantee backward compatibility support for the public beta. All APIs, workflows, and HCL syntax for Stacks are subject to change. - -## Background - -Stacks are an alternative way to organize your infrastructure and fundamentally differ from [HCP Terraform workspaces](/terraform/cloud-docs/workspaces). Stacks are not built on top of HCP Terraform workspaces, but can exist alongside them in the same project. - -Previously, those looking to deploy repeatable infrastructure using HCP Terraform would create separate workspaces and then use run triggers or other automation tools to coordinate changes between them. However, workspaces are not truly coupled to each other, hampering your ability to flexibly manage infrastructure as it scales. - -Terraform Stacks enable you to split your Terraform configuration into components and then deploy and manage those components across multiple environments. You can manage the lifecycle of each deployment separately, roll out configuration changes across your deployments, and manage your Stack as a unit in HCP Terraform. - -Each deployment in a Stack represents a group of components that work together, such as a development and production environment. The configuration for each Stack is identical across deployments, and you can further customize each environment with input variables. You can then use HCP Terraform to roll out changes to each deployment and keep track of changes across your environments. - -Stacks are unavailable for users on legacy HCP Terraform team plans. Learn more about [migrating to current HCP Terraform plan](/terraform/cloud-docs/overview/migrate-teams-standard). - -## Workflow - -Start by creating a Stack configuration file and filling it with the `component` blocks. Each `component` block includes a Terraform module as its source, and you can configure a `component` further using input arguments. Your Stack components share a lifecycle, which you can repeatedly deploy together using HCP Terraform. - -![Diagram of the architecture of a Stack. A Stack of two components (Kubernetes and Namespace) are rolled out to three deploymentes (US, Europe, and Asia) ](/img/docs/stacks-example.png) - -After configuring your Stack’s `components`, you create a separate deployment configuration file to define how you want to repeat its infrastructure. Each deployment in a Stack represents a group of infrastructure that works together. You can define `deployment` blocks for your development environments, cloud provider accounts, or regions. - -Once ready to deploy your Stack’s infrastructure, you can help manage your deployments by defining orchestration rules. For example, you can automatically approve operations whenever a deployment meets certain criteria. - -## Primary workflow - -The overall process for managing your infrastructure using Stacks consists of the following steps. - -### Design a Stack - -Consider your current infrastructure lifecycle and how the pieces interact with each other. Then, determine how to break down your infrastructure into components and think about how you want to deploy the infrastructure your Stack describes. Refer to [Design a Stack](/terraform/language/stacks/design) to learn more. - -### Write a Stack configuration - -Configure and define your Stack in a `tfstack.hcl` file. To define a Stack, add and configure `component` blocks, each representing an individual Terraform module. Refer to [Define configuration](/terraform/language/stacks/create/config) to learn more. - -Stacks declare providers in a different workflow than in traditional Terraform configurations, refer to [Declare providers](/terraform/language/stacks/create/declare-providers) to learn more. Stacks also have their own way of authenticating with providers, refer to [Authenticate a Stack](/terraform/language/stacks/deploy/authenticate) for details. - -### Define deployments - -With your Stack configuration file complete, the next step is to define how you want to deploy your Stack. Create a `tfdeploy.hcl` file defining how HCP Terraform should deploy your Stack’s infrastructure. In Stacks, deployments allow you to replicate infrastructure across multiple environments, regions, or accounts. Each deployment runs in an isolated agent, ensuring that changes in one deployment do not affect others. Refer to [Define deployment configuration](/terraform/language/stacks/deploy/config) to learn more. - -### Manage and orchestrate deployments - -Use your Stack’s context to define orchestration rules with the `orchestrate` block. You can define rules for automated approvals, error handling, and other events within your deployment configuration. Refer to [Set conditions for deployment plans](/terraform/language/stacks/deploy/conditions) to learn more. - -### Deploy - -After fully configuring your Stack, use HCP Terraform to deploy your Stack’s infrastructure. Refer to [Create a Stack](/terraform/cloud-docs/stacks/create) to learn more. - -## Guidance - -Stacks are useful when managing complex, multi-environment infrastructures where consistency and reusability are crucial. Refer to Stack [use cases](/terraform/language/stacks/use-cases) for inspiration on situations where Stacks are particularly well suited. - -## Constraints, limitations, and troubleshooting - -While Stacks provide powerful capabilities, there are some limitations to be aware of during this beta phase: - -* Each Stack currently supports a maximum of 20 deployments, which may limit scalability for large environments. -* Stacks have a limit of 500 [managed resources per HCP Terraform organization](/terraform/cloud-docs/overview/estimate-hcp-terraform-cost#what-is-a-managed-resource) while in public beta. If your organization exceeds this limit, you can no longer apply new resources until you reduce your resource count. If you need more resources, [fill out our form to request a resource extension](https://forms.gle/uGhn5CL1krf5T93m9). -* Stacks are not available for users on legacy HCP Terraform team plans. Learn more about [migrating to a current HCP Terraform plan](/terraform/cloud-docs/overview/migrate-teams-standard). diff --git a/website/docs/language/stacks/reference/tfdeploy.mdx b/website/docs/language/stacks/reference/tfdeploy.mdx deleted file mode 100644 index f65523557e..0000000000 --- a/website/docs/language/stacks/reference/tfdeploy.mdx +++ /dev/null @@ -1,433 +0,0 @@ ---- -page_title: Deployment configuration file reference -description: Stacks help you provision and coordinate your infrastructure lifecycle at scale. Learn how to write a deployment configurion to tell HCP Terraform how many times to deploy your Stack's 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Deployment configuration file reference - -A deployment configuration file defines how to deploy your Stack's infrastructure. Each Stack deployment runs in its agent, wholly isolated from other Stack deployments. - -Every Stack needs a deployment configuration file, `tfdeploy.hcl`, and this page describes all of the blocks you can use within a deployment configuration file. Note that none of the blocks in the deployment configuration file support [meta-arguments](/terraform/language/resources/syntax#meta-arguments). - -## `deployment` block configuration - -The `deployment` block is where you define how many times you want to deploy your Stack's infrastructure. Each Stack requires at least one `deployment` block, and you can add a new `deployment` block every time you want to deploy your Stack’s infrastructure again. - --> **Note**: HCP Terraform supports up to a maximum of 20 deployments. - -The following list outlines field hierarchy, language-specific data types, and requirements in the `deployment` block. - -### Complete configuration - -When every field is defined, a `deployment` block has the following form: - -```hcl -deployment "unique_name" { - inputs = { - key = "value" - } -} -``` - -For examples and guidance on defining deployments, refer to [Define deployment configuration](/terraform/language/stacks/deploy/config). - -### Specification - -This section details the fields you can configure in the `deployment` block. - -Each Stack must have at least one `deployment` block, and the label of the `deployment` block must be unique within your Stack. The `deployment` block is a map that defines the appropriate input values for each Stack instance to deploy. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `inputs` | A mapping of Stack variable names for this deployment. The keys in this map must correspond to the names of variables defined in the Stack. The values must be valid HCL literals meeting the type constraint of those variables. | map | Required | - -### Reference - -For example, the following `deployment` block accepts inputs for variables named `aws_region` and `instance_count` and creates a new deployment in HCP Terraform named “production”. - -```hcl -deployment "production" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - } -} -``` - -To learn more about defining deployments, refer to [Define deployment configuration](/terraform/language/stacks/deploy/config). - -## `orchestrate` block configuration - -The orchestrate block defines orchestration rules that you can use to manage your deployment plans. Your orchestration rules can automate tasks like auto-approving plans that meet specific conditions. - -The following list outlines field hierarchy, language-specific data types, and requirements in the `orchestrate` block. - -### Complete configuration - -When every field is defined, an `orchestrate` block has the following form: - -```hcl -# auto_approve is the rule type -orchestrate "auto_approve" "name_of_check" { - check { - condition = - reason ="Provide the reason why this check failed." - } -} -``` - -The `orchestrate` block label includes the rule type and the rule name, which together must be unique within the Stack. - -There are two orchestration rules to choose from: - -* The `auto_approve` rule executes after a Stack creates a plan and automatically approves a plan if all checks pass. -* The `replan` rule executes after a Stack applies a plan, automatically triggering a replan if all the checks pass. - -HCP Terraform evaluates the `check` blocks within your `orchestrate` block to determine if it should approve a plan. If all of the checks pass, then HCP Terraform approves the plan for you. If one or more `conditions` do not pass, then HCP Terraform shows the `reason` why, and you must manually approve that plan. - -By default, each Stack has an `auto_approve` rule named `empty_plan`, which automatically approves a plan if it contains no changes. - -### Specification - -This section provides details about the fields you can configure in the `orchestrate` block. - - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `check` | A block containing conditions and reasons for the orchestration rule. All checks must pass for an orchestration rule to be triggered. | block | Required | - -The `check` block contains the following configurable fields. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `condition` | An expression that determines whether the check passes. | expression | Required | -| `reason` | A message explaining why the check failed is shown in HCP Terraform, prompting you to manually approve a plan. | string | Required | - -### Orchestration Context - -A `check` block’s `condition` field has access to a `context` variable, which includes information about the context of the current deployment plan. The `context` variable contains the following fields. - -| Field | Description | Type | -| :---- | :---- | :---- | -| `operation` | The current operation HCP Terraform is performing. | string ("plan" or "apply") | -| `success` | Indicates whether the operation failed. If this field is `false`, then the `errors` field contains the message of why the operation failed. | boolean | -| `plan` | An object including data about the current plan. | object | -| `errors` | A set of diagnostic error message objects. | set of objects | -| `warnings` | A set of diagnostic warning message objects. | set of objects | - -The diagnostic message objects that the `context.errors` and `context.warnings` fields return includes the following information. - -| Field | Description | Type | -| :---- | :---- | :---- | -| `summary` | A brief summary of the diagnostic message | string | -| `detail` | Detailed information about the diagnostic message | string | - -The `context.plan` field returns an object including the following fields. - -| Field | Description | Type | -| :---- | :---- | :---- | -| `mode` | The plan mode. | string ("normal", "refresh-only", or "destroy") | -| `applyable` | Whether or not the plan can be applied. | boolean | -| `changes` | A change summary object. | object | -| `component_changes` | A map of change summary objects for each component instance. | map of objects | -| `replans` | The number of replans in this plan's sequence, starting at `0`. | integer | -| `deployment` | A direct reference to the current deployment. | Deployment object containing a `deployment_name` field. | - -The objects in the `context.plan.component_changes` field include the following fields. - -| Field | Description | Type | -| :---- | :---- | :---- | -| `add` | Number of resources to be added. | integer | -| `change` | Number of resources to be changed. | integer | -| `import` | Number of resources to be imported. | integer | -| `remove` | Number of resources to be removed. | integer | -| `total` | Total number of resource actions. | integer | - -The object in the `context.plan.deployment` field includes the following fields. - -| Field | Description | Type | -| :---- | :---- | :---- | -| `deployment_name` | The name of the current deployment HCP Terraform is running this plan on. You can use this field to check which deployment is running this plan. For example, you can check if this plan is on your production deployment: `context.plan.deployment == deployment.production`. | string | - -### Reference - -For example, the following `orchestrate` block automatically approves deployments if a component has not changed. - -```hcl -orchestrate "auto_approve" "no_pet_changes" { - check { - condition = context.plan.component_changes["component.pet"].total == 0 - reason = "Changes proposed to pet component." - } -} -``` - -If nothing changes in the `component.pet` component, HCP Terraform automatically approves the plan. - -## `identity_token` block configuration - -The `identity_token` block defines a JSON Web Token (JWT) that Terraform generates for a given deployment if that `deployment` block references an `identity_token` in its `inputs`. - -You can directly pass the token generated by the `identity_token` block to a provider's configuration for OIDC authentication. For more information on authenticating a Stack using OIDC, refer to [Authenticate a Stack](/terraform/language/stacks/deploy/authenticate). - -### Complete configuration - -When every field is defined, an `identity_token` block has the following form: - -```hcl -identity_token "unique_to_stack_name" { - audience = ["audience this token is intended for"] -} -``` - -### Specification - -This section provides details about the fields you can configure in the `identity_token` block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `audience` | The audience of your token is the resource(s) that uses this token after Terraform generates it. You specify an audience to ensure that the cloud service authorizing the workload is confident that the token you present is intended for that service. | set of strings | Required | - -### Reference - -Once defined, you can reference an identity token's `jwt` attribute in a deployment's inputs. For example, below we generate a token for a particular role ARN in AWS. - -```hcl -# main.tfdeploy.hcl -identity_token "aws" { - audience = ["aws.workload.identity"] -} - -deployment "staging" { - inputs = { - aws_region = "eu-west-1" - role_arn = "arn:aws:iam::123456789101:role/my-oidc-role" - aws_token = identity_token.aws.jwt - } -} -``` - -Terraform generates an identity token that you can use in your Stack configuration to configure your AWS provider with your role in AWS. - -```hcl -# providers.tfstack.hcl - -variable "aws_token" { - type = string - ephemeral = true -} - -variable "aws_region" { - type = string -} - -variable "aws_role" { - type = string -} - -provider "aws" "this" { - config { - region = var.aws_region - assume_role_with_web_identity { - role_arn = var.aws_role - web_identity_token = var.aws_token - } - } -} -``` - -With this setup, every time your `staging` deployment performs a plan or apply operation, we authenticate with AWS using your established ARN role and a new JWT token. For more information on authenticating a Stack using OIDC, refer to [Authenticate a Stack](/terraform/language/stacks/authenticate). - -## `store` block configuration - -Use the `store` block to define key-value secrets in your deployment configuration. After storing a secret, you can reference it in your deployment block input variable values. - -When you define a `store` block, you define two headers: the first specifies the store type, and the second is the store's name. - -When every field is defined, a `store` block has the following form. - -```hcl -store "store_type" "store_name" { - -} -``` - -A store’s type defines where Terraform should look for that store’s credentials and how to decode the credentials it finds. You cannot share arguments across store types. - -### `varset` specification and configuration - -Use the `varset` store to enable your Stacks to access [variable sets](/terraform/cloud-docs/workspaces/variables/managing-variables#variable-sets) in HCP Terraform. Your Stack must have access to the variable set you are targeting, meaning it must be globally available or assigned to the project containing your Stack. - -This section details the fields you can configure in the `store` block that uses the `varset` store type. - -```hcl -store "varset" "store_name" { - id = "" - category = <"terraform" or "env"> -} -``` - -The `varset` store type accepts the following fields. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `id` | The external ID of the variable set you want to access. | string | Required | -| `category` | The `category` argument specifies whether to use Terraform or environment variables from the variable set. Specify "terraform" or "env" depending on the variable you want to access. | string | Required | - -The `store.varset` block can only use a variable set’s Terraform or environment variables. You can define two `store` blocks if you need to access Terraform and environment variables in your deployment configuration. - -```hcl -store "varset" "tokens" { - id = "varset-###" - category = "terraform" -} - -store "varset" "available_regions" { - id = "varset-###" - category = "env" -} - -deployment "main" { - inputs = { - regions = store.varset.available_regions.regions - tfe_token = store.varset.tokens.tfe_token - } -} -``` - -You can access specific environment variables by key from the `store.varset.available_regions` store, and you can access specific Terraform variables by key using the `store.varset.tokens` store. - -### Reference - -For example, if you have an HCP Terraform [variable set](/terraform/cloud-docs/workspaces/variables/managing-variables#variable-sets) that contains a value you want to use in your deployment, you can create a `store` block to access that variable set. - -```hcl -store "varset" "tokens" { - id = "" - category = "terraform" -} - -deployment "main" { - inputs = { - token = store.varset.tokens.example_token - } -} -``` - -You cannot access an entire store and must specifically access individual keys within that store. Meaning, we can access your example’s `example_token` variable by accessing the store’s `varset` type, `store.varset`, then accessing the specific store, `store.varset.tokens.example_token`. - -## `locals` block configuration - -A local value assigns a name to an expression, so you can use the name multiple times within your Stack configuration instead of repeating the expression. The `locals` block works exactly as it does in traditional Terraform configurations. Learn more about [the `locals` block](/terraform/language/values/locals). - -## `publish_output` block configuration - -The `publish_output` block requires at least Terraform version `terraform_1.10.0-alpha20241009` or higher. Download [latest version of Terraform](https://releases.hashicorp.com/terraform/) to use the most up-to-date functionality. - -The `publish_output` block specifies a value to export from your current Stack, which other Stacks in the same project can consume. Declare one `publish_output` block for each value to export from your Stack. - -### Complete configuration - -When every field is defined, a `publish_output` block has the following form: - - - -```hcl -publish_output "output_name" { - description = "Description of the purpose of this output" - value = deployment.deployment_name.some_value -} -``` - - - -### Specification - -This section provides details about the fields you can configure in the output block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `description` | A human-friendly description for the output. | string | Optional | -| `value` | The value to output. | any | Required | - -### Reference - -For example, you could output the VPC ID from your networking deployment, making it available to other Stacks to input. - - - -```hcl -# Network Stack's deployment configuration - -publish_output "vpc_id" { - description = "The networking Stack's VPC's ID." - value = deployment.network.vpc_id -} -``` - - - -To learn more about passing information between Stacks, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data). - -## `upstream_input` block configuration - -The `upstream_input` block requires at least Terraform version `terraform_1.10.0-alpha20241009` or higher. Download [latest version of Terraform](https://releases.hashicorp.com/terraform/) to use the most up-to-date functionality. - -The `upstream_input` block specifies another Stack in the same project to consume outputs from. Declare an `upstream_input` block for each Stack you want to reference. If an output from a upstream Stack changes, HCP Terraform automatically triggers runs for any Stacks that depend on those outputs. - -To learn more about passing information between Stacks, refer to [Pass data from one Stack to another](/terraform/language/stacks/deploy/link-stacks). - -### Complete configuration - -When every field is defined, an `upstream_input` block has the following form: - - - -```hcl -upstream_input "upstream_stack_name" { - type = "stack" - source = "app.terraform.io/{organization_name}/{project_name}/{upstream_stack_name}" -} -``` - - - -### Specification - -This section provides details about the fields you can configure in the `upstream_input` block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `type` | The only supported type is “stack”. | string | Required | -| `source` | The upstream Stack’s URL, in the format: `"app.terraform.io/{organization_name}/{project_name}/{upstream_stack_name}"` | string | Required | - -### Reference - -For example, you could input a VPC ID from an upstream Stack that manages your shared networking service. You can use the `upstream_input` block to pass information from your network Stack into your application Stack. - - - -```hcl -# Application Stack's deployment configuration - -upstream_input "network_stack" { - type = "stack" - source = "app.terraform.io/hashicorp/Default Project/networking-stack" -} - -deployment "application" { - inputs = { - vpc_id = upstream_input.network_stack.vpc_id - } -} -``` - - - -Your application Stack can now securely consume and use outputs from your network Stack. To learn more about passing information between Stacks, reference [Pass data from one Stack to another](/terraform/language/stacks/deploy/pass-data). diff --git a/website/docs/language/stacks/reference/tfstack.mdx b/website/docs/language/stacks/reference/tfstack.mdx deleted file mode 100644 index 1edad1b930..0000000000 --- a/website/docs/language/stacks/reference/tfstack.mdx +++ /dev/null @@ -1,313 +0,0 @@ ---- -page_title: Stack configuration file reference -description: Stacks help you provision and coordinate your infrastructure lifecycle at scale. Learn how to write a Stack configurion file to create a Stack for 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Stack configuration file reference - -A Stack configuration file defines all the infrastructure pieces included in a Stack. Every Stack needs a configuration file, `tfstack.hcl`, and this page describes all the blocks you can use within a Stack configuration file. - -## `component` block configuration - -The `component` block defines the infrastructure to include in your Stack. Each Stack requires at least one `component` block. Add a `component` block to your configuration for every module you want to include in your Stack. - -The following list outlines field hierarchy, language-specific data types, and requirements in the `component` block. - -### Complete configuration - -When every field is defined, a `component` block has the following form: - -```hcl -component "unique_name" { - source = - inputs = { - input_name = - } - providers = { - random = provider.provider_name.provider_alias - } -} -``` - -### Specification - -This section details the fields you can configure in the `component` block. - -Each Stack must have at least one `component` block, and the label of the component block must be unique within your Stack. The `component` block is a map that defines a module to source, input variables for that module, and the names of the providers that your module requires. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `source` | The Terraform module to [source](https://developer.hashicorp.com/terraform/language/modules/sources) for this component. | string | Required | -| `version` | If you declare a module from the public Terraform registry in the source field, you can define which module version to use. | string | Optional | -| `inputs` | A mapping of module input variable names to values. The keys of this map must correspond to the variable names defined by the `source` module. The values can be one of three types: A variable reference such as `var.variable_name`, a component output such as `component.component_name.output_name`, or a literal valid HCL value such as "string value". | map | Required | -| `providers` | A mapping of provider names to providers declared in your Stack configuration. Modules cannot configure their own providers. You must [declare providers](/terraform/language/stacks/create/declare-providers) in the top level of the Stack and pass them into each module in the Stack. | map | Required | -| `depends_on` | A list of other components that HCP Terraform must execute before this component. You do not need to include another component’s outputs in this list, because Terraform automatically recognizes them. | list | Optional | - -### Reference - -The `component` block also supports the `for_each` meta-argument. For example, the following configuration uses `for_each` to provision modules in multiple AWS regions for a given environment. - -```hcl -component "s3" { - for_each = var.regions - - source = "./s3" - - inputs = { - region = each.value - } - - providers = { - aws = provider.aws.configurations[each.value] - random = provider.random.this - } -} -``` - -To learn more about breaking down your infrastructure into components, refer to [Define Stack configuration](/terraform/language/stacks/create/config). - -## `variable` block configuration - -Use the `variable` block to declare input variables for your Stack configuration. Using `variable` blocks in Stacks is similar to traditional Terraform configurations but with a few minor differences. - -In Stack configurations, `variable` blocks must define a `type` field and do not support the `validation` argument. Learn more about Terraform [Variables](/terraform/language/values/variables). - -### Complete configuration - -When every field is defined, a `variable` block has the following form: -```hcl -variable "unique_variable_name" { - description = "Description of the purpose of this variable" - type = string - default = "Default variable value" - sensitive = false - nullable = false -} -``` - -### Specification - -This section provides details about the fields you can configure in the `variable` block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `type` | A type constraint for the variable's value. Can be string, number, bool, list, map, set, tuple, or object. Stacks require you to declare a `type` for your variables. | string | Required | -| `description` | A human-friendly description for the variable. | string | Optional | -| `default` | A default value for the variable which Terraform uses if no value is provided. | any | Optional | -| `sensitive` | Marks the variable as sensitive, which prevents its value from being displayed in logs or in the HCP Terraform user interface. | bool | Optional | -| `nullable` | Specifies whether the variable can be null. | bool | Optional | -| `ephemeral` | Marks that this variable’s value is dynamic. For example, an expiring authentication token is `ephemeral`. Learn more about [Ephemeral variables](/terraform/language/values/variables#exclude-values-from-state). | bool | Optional | - -## `output` block configuration - -Use the `output` block to make information about your infrastructure available in the HCP Terraform UI to expose information about your Stack. The `output` block functions the same way in Stack configuration as it does in traditional Terraform configurations with a few small differences. - -In Stack configurations, `output` blocks require the `type` argument, and they do not support the `preconditions` block. Learn more about [Outputs](/terraform/language/values/outputs). - -### Complete configuration - -When every field is defined, an `output` block has the following form: -```hcl -output "unique_name_of_output" { - description = "Description of the purpose of this output" - type = string - value = component.component_name.some_value - sensitive = false - ephemeral = false -} -``` - -### Specification - -This section provides details about the fields you can configure in the `output` block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `description` | A human-friendly description for the output. | string | Optional | -| `type` | The type of the output. | type constraint | Required | -| `value` | The value to output. | any | Required | -| `sensitive` | Marks the variable as sensitive, which prevents its value from being displayed in logs or in the HCP Terraform UI. | bool | Optional | -| `ephemeral` | Whether to exclude the value from plans and state data. | bool | Optional | - -## `required_providers` and `provider` block configuration - -Terraform relies on plugins called providers to interact with cloud providers, SaaS providers, and other APIs. - -The `required_providers` block works exactly as it does in traditional Terraform configurations. Learn more about [the `required_providers` block](/terraform/language/providers/requirements). The `provider` block functions mostly the same way in Stack configuration as it does in traditional Terraform configurations, with a few differences. - -The `provider` block differs in Stack configurations in the following ways: - -* Supports the `for_each` [meta-argument](/terraform/language/meta-arguments/for_each) -* Defines aliases in the `provider` block header rather than as an argument -* Accepts arguments using a config block - -You must also define your providers at the top level of your Stack configuration in a `tfstack.hcl` file. You cannot define providers within the modules your component blocks source. - -### Complete configuration - -Provider configuration differs depending on which API you are interacting with. Below, you can configure the AWS provider and pass it to your S3 component. - -```hcl -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } -} - -# "main" is the alias for this provider -provider "aws" "main" { -# The config block accepts the configuration for a provider - config { - region = var.region - - assume_role_with_web_identity { - role_arn = var.role_arn - web_identity_token = var.identity_token - } - } -} -``` - -The `provider` block also supports the `for_each` meta-argument. For example, the following provider uses `for_each` to create multiple AWS configurations. - -```hcl -provider "aws" "configurations" { - for_each = var.regions - - config { - region = each.value - - assume_role_with_web_identity { - role_arn = var.role_arn - web_identity_token = var.identity_token - } - - default_tags { - tags = var.default_tags - } - } -} -``` - -For more information on declaring providers in Stacks, refer to [Declare providers](/terraform/language/stacks/create/declare-providers). - -## `locals` block configuration - -A local value assigns a name to an expression, so you can use the name multiple times within your Stack configuration instead of repeating the expression. The `locals` block works exactly as it does in traditional Terraform configurations. Learn more about [the `locals` block](/terraform/language/values/locals). - - -## `removed` block configuration - -Stacks take a systematic approach to removing components. To remove a component from a Stack, you must use the `removed` block to ensure HCP Terraform knows which components to remove and which providers it requires to remove that component. - -Do not remove providers from your stack configuration without first removing the components that require those providers. HCP Terraform requires a component's providers to ensure it can successfully remove that component. - - -### Complete configuration - -When every field is defined, a `removed` block has the following form: - -```hcl - -removed { - source = "" - - from = component.component_name - providers = { - aws = provider.aws.this - } -} -``` - - -### Specification - -This section provides details about the fields you can configure in the `removed` block. - -| Field | Description | Type | Required | -| :---- | :---- | :---- | :---- | -| `from` | The name of the resource you want to remove. | string | Required | -| `source` | The source module of the component you want to remove. | string | Required | -| `providers` | A mapping of provider names to the providers that the component you want to remove uses. HCP Terraform needs your component providers to remove that component properly. | map | Required | - -### Reference - -The `removed` block also supports the `for_each` meta-argument to support removing multiple `components`. For example, if you are trying to remove a dynamic component that HCP Terraform deploys in multiple AWS regions. - -```hcl -component "s3_buckets" { - source = "./s3" - - for_each = var.regions - - providers = { - aws = provider.aws.config[each.value] - } - - variables = { - region = each.value - } -} -``` - -You can use the `for_each` meta-argument to remove each component dynamically. - -```hcl -removed { - source = "./s3" - - for_each = var.regions - - from = component.s3_buckets[each.value] - providers = { - aws = provider.aws.config[each.value] - } -} -``` - -HCP Terraform iterates through the `var.regions` variable and removes each AWS region's corresponding component. Expanding on this example, you could add a new variable to keep track of the regions you want to remove. - -```hcl -variable "regions" { - type = set(string) -} - -# Adding a region to this variable instructs HCP Terraform to remove it. -variable "removed_regions" { - type = set(string) -} - -component "s3_buckets" { - source = "./s3" - - for_each = var.regions - - providers = { - aws = provider.aws.config[each.value] - } - - variables = { - region = each.value - } -} - -removed { - source = "./s3" - # Iterate and remove the regions in our new removed_regions variable. - for_each = var.removed_regions - - from = component.s3_buckets[each.value] - providers = { - aws = provider.aws.config[each.value] - } -} -``` - -When you move a region from `regions` to the `removed_regions` variable, HCP Terraform plans to remove that region's corresponding components. diff --git a/website/docs/language/stacks/reference/tfstacks-cli.mdx b/website/docs/language/stacks/reference/tfstacks-cli.mdx deleted file mode 100644 index b33aa96b8e..0000000000 --- a/website/docs/language/stacks/reference/tfstacks-cli.mdx +++ /dev/null @@ -1,171 +0,0 @@ ---- -page_title: Terraform Stack CLI reference -description: The terraform-stacks-cli is a command-line tool for validating, initializing, and managing Stack configurations. Learn about the terraform-stacks-cli commands and options. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Stack CLI reference - -The `terraform-stacks-cli` is a command-line tool for validating, initializing, and testing Stack configurations. - -## Requirements - -The `terraform-stacks-cli` requires an `alpha` version of Terraform, and you must use at least version `terraform_1.10.0-alpha20241009` or higher. You can download an `alpha` version of Terraform on the [releases page](https://releases.hashicorp.com/terraform/). We recommend downloading the latest alpha version of Terraform to use the most up-to-date functionality. - -## Installation - -To install the `terraform-stacks-cli`, you can download it directly [on the HashiCorp releases page](https://releases.hashicorp.com/tfstacks) or install it with one of the following package managers: Homebrew, Debian/Ubuntu, CentOS/RHEL, Fedora, or Amazon Linux. - -#### Homebrew - -Run the following commands to install the `terraform-stacks-cli` using Homebrew. - -```shell-session -$ brew tap hashicorp/tap -$ brew install hashicorp/tap/tfstacks -``` - -#### Linux Package Managers - -Run the following commands to install the `terraform-stacks-cli` with the following Linux package managers. - -##### Debian or Ubuntu - -Run the following commands to install the `terraform-stacks-cli` using Debian or Ubuntu. - -```shell-session -$ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg -$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list -$ sudo apt update && sudo apt install terraform-stacks-cli -``` - -##### CentOS or RHEL - -Run the following commands to install the terraform-stacks-cli using CentOS or RHEL. - -```shell-session -$ sudo yum install -y yum-utils -$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo -$ sudo yum -y install terraform-stacks-cli -``` - -##### Fedora - -Run the following commands to install the `terraform-stacks-cli` using Fedora. - -```shell-session -$ sudo dnf install -y dnf-plugins-core -$ sudo dnf config-manager addrepo --from-repofile=https://rpm.releases.hashicorp.com/fedora/hashicorp.repo -$ sudo dnf -y install terraform-stacks-cli -``` - -##### Amazon Linux - -Run the following commands to install the `terraform-stacks-cli` using Amazon Linux. - -```shell-session -$ sudo yum install -y yum-utils shadow-utils -$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo -$ sudo yum -y install terraform-stacks-cli -``` - -## Commands - -The `terraform-stacks-cli` supports the following four commands: - -* [`tfstacks init`](#tfstacks-init-command) -* [`tfstacks validate`](#tfstacks-validate-command) -* [`tfstacks providers lock [-platform=os_arch]`](#tfstacks-providers-lock-command) -* [`tfstacks plan -organization=org_name -stack=stack_id -deployment=deployment_name [-hostname=hostname]`](#tfstacks-plan-command) -* [`tfstacks fmt`](#tfstacks-fmt-command) - -Each Stack command supports [global options](#global-options). - -### `tfstacks init` command - -The `tfstacks init` command attempts to download any dependencies your Stack configuration requires. - -```shell-session -$ tfstacks init -``` - -If the `tfstacks init` command cannot find a dependency, it warns you of the reason why and installs a false dependency in the real one's place to unblock any future validation. Meaning, that it the `tfstacks init` command cannot download a dependency, you can still run `tfstacks validate`, but the missing dependencies are not validated. - -### `tfstacks validate` command - -The `tfstacks validate` command loads your Stack configuration and validates that your stack’s syntax and static types are correct. - -```shell-session -$ tfstacks validate -``` - -We recommend running this command whenever you change your Stack configuration. - -### `tfstacks providers lock` command - -The `tfstacks providers lock` command creates and updates your stack’s provider lock file. - -```shell-session -$ tfstacks providers lock [-platform=os_arch] -``` - -The `tfstacks providers lock` command references the `required_providers` block from your configuration to know which providers to download and compute the provider lock hashes for. The `tfstacks providers lock` command only checks the `required_providers` block, so you must list all of the providers you use in the `required_providers` block to ensure that the `tfstacks providers lock` command can find them. - -By default, the `tfstacks providers lock` installs hashes for providers built for `linux_amd64` machines, which HCP Terraform requires for execution. You can optionally use the `-platform=os_arch` argument to create hashes for other platforms. - -### `tfstacks plan` command - -The `tfstacks plan` runs a remote, speculative plan with local code in the current directory. If you are not currently logged in to HCP Terraform when you run this command, the output prompts you to log in. - -```shell-session -$ tfstacks plan -organization=REQUIRED_ORG_NAME -stack=REQUIRED_STACK_ID -deployment=REQUIRED_DEPLOYMENT [-hostname=hostname] -``` - -The `tfstacks plan` accepts the following arguments. - -| Field | Description | Required | -| :---- | :---- | :---- | -| `-organization` | Set the `organization` flag to the name of this stack’s organization.

Alternatively, you can set an environment variable named `TFSTACKS_ORGANIZATION` with the same value. | Required | -| `-stack=` | Set the `stack` flag to the ID of the Stack you want to perform this plan in. You can find a stack’s ID underneath its name when you view that Stack in HCP Terraform.

Alternatively, you can set an environment variable named `TFSTACKS_STACK_ID` with the same value. | Required | -| `-deployment=` | Set the `deployment` flag to the deployment name you want to perform this plan in. The deployment name must match one of the deployment names you specified in the `tfdeploy.hcl` file.

Alternatively, you can set an environment variable named `TFSTACKS_DEPLOYMENT` with the same value. | Required | -| `-hostname=` | You can set the `hostname` flag to the hostname of the HCP Terraform instance you want to perform this plan in. The default value is `app.terraform.io`.

Alternatively, you can set an environment variable named `TFSTACKS_HOSTNAME` with the same value. | Optional | - -### `tfstacks fmt` command - --> The `tfstacks fmt` command requires v0.6.0 of the `terraform-stacks-cli` or higher. Refer to [installation](#installation) for instructions. - -The `tfstacks fmt` command scans your current directory for Stack configuration files, `.tfstack.hcl` and `.tfdeploy.hcl`, and formats those files to match Terraform's canonical format and style. - -```shell-session -$ tfstacks fmt [options] [target] -``` - -By default, the `tfstacks fmt` command scans your current directory for configuration files. You can also provide a `target` argument to tell `tfstacks fmt` to scan: -* A directory -* A specific file -* Standard input by supplying a single dash (`-`). - -The `tfstacks 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, only the specified directory is processed. | Optional | - -The `tfstacks fmt` command uses the same formatting rules as the Terraform CLI's `terraform fmt` command. Refer to [`terraform fmt`](/terraform/cli/commands/fmt) for more information on formatting rules. - -## Global options - -You can apply the following global options to any `tfstacks` command: - -* The `-terraform-binary` flag specifies a specific version of Terraform to use instead of the one in your PATH. -* The `-chdir` flag points to an alternate configuration directory. -* The `-no-color` flag disables color output in the CLI. diff --git a/website/docs/language/stacks/use-cases.mdx b/website/docs/language/stacks/use-cases.mdx deleted file mode 100644 index 84c37f5ff2..0000000000 --- a/website/docs/language/stacks/use-cases.mdx +++ /dev/null @@ -1,246 +0,0 @@ ---- -page_title: Use cases -description: Learn about example use cases to better understand how to use Stacks to manage your infrastructure lifecycle more effectively. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Cases - -Stacks provide a way to define, organize, and reuse components and then deploy the infrastructure those components describe consistently across different deployments. - -Stacks are ideal for the following situations: -* Managing infrastructure with a common lifecycle, such as a microservices architecture where HCP Terraform needs to deploy multiple services together. -* Repeating infrastructure across different environments, regions, or accounts that require consistent and synchronized deployments. -* Tightly orchestrating infrastructure changes across different environments. Stacks help you manage your dependencies and ensure Terraform creates resources in the correct order. - -Stacks can simplify the complexity of wrangling the infrastructure in these scenarios, ensuring that your configurations remain organized, maintainable, and scalable. - -## Manage deployment dependencies - -Stacks allow you to manage dependencies within complex infrastructure deployments automatically. If your infrastructure has interdependencies between components, HCP Terraform recognizes if a Stack component requires attributes that are not yet available and defers planning those changes until it can apply them. - --> **Hands-on**: Go through our tutorial on [Managing Kubernetes workloads using Stacks](/terraform/tutorials/cloud/stacks-eks-deferred) for examples of Stacks that manage deployment dependencies. - -For example, when managing Kubernetes workloads that use custom resources, you cannot provision a custom resource definition (CRD) API and the resources that use those APIs in a single step. In these scenarios, HCP Terraform first needs to deploy your CRD and then deploy the resources that require your CRD in a second plan and apply. When you deploy this setup with HCP Terraform workspaces, you manage multiple workspaces to accomplish this workflow, which can get complicated. - -When you use a Stack, HCP Terraform recognizes the dependency between components, automatically deferring the component's plan and apply steps until it can complete them successfully. Learn more about how Stacks plan [deferred changes](/terraform/cloud-docs/stacks/deploy/plans#deferred-changes). - -## Deploy to multiple environments - -Managing infrastructure across multiple environments can be challenging, especially when you want to ensure that each environment remains consistent. For example, if you manage infrastructure for multiple environments, such as development, staging, and production. Each environment needs to be isolated, but they all mirror each other’s configuration. - -Stacks allow you to define deployments for each environment within a single configuration, making it easier to maintain uniformity and make updates across all your environments. - -```hcl -# deployments.tfdeploy.hcl - -deployment "production" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws.jwt - } -} - -deployment "development" { - inputs = { - aws_region = "us-east-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws.jwt - } -} -``` - -Stacks also simplify adding and removing environments. You can add a `deployment` block to create a new environment using the same Stack configuration and infrastructure components. - -```hcl -# deployments.tfdeploy.hcl - -deployment "production" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws.jwt - } -} - -deployment "development" { - inputs = { - aws_region = "us-east-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws.jwt - } -} - -deployment "staging" { - inputs = { - aws_region = "us-east-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws.jwt - } -} -``` - -By default, HCP Terraform notices that you changed your configuration and will create a new plan for your new deployment. - -## Deploy across regions - -For global applications, deploying infrastructure across multiple cloud regions is often necessary to ensure low latency and high availability. Stacks enable you to manage cross-region deployments with a unified configuration, ensuring that HCP Terraform sets up each region consistently while allowing for region-specific customization. - -For example, if you want to deploy the same environment to two different regions, you could set up your deployments to be region-specific. - -```hcl -# deployments.tfdeploy.hcl - -identity_token "aws_west" { - audience = ["aws.workload.identity.west"] -} - -identity_token "aws_east" { - audience = ["aws.workload.identity.east"] -} - -deployment "us_dev_east" { - inputs = { - aws_region = "us-east-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws_east.jwt - } -} - -deployment "us_dev_west" { - inputs = { - aws_region = "us-west-1" - instance_count = 2 - role_arn = "" - identity_token = identity_token.aws_west.jwt - } -} -``` - -Stacks support using the [`for_each` meta argument](/terraform/language/meta-arguments/for_each) in both `provider` and `component` blocks. You can use this support to streamline infrastructure deployment in repeating regions. For example, you could set up a variable to expect a set of regions. - -```hcl -# variables.tfstack.hcl - -# The regions variable is where we specify each region we want to deploy this -# Stack's infrastructure within. -variable "regions" { - type = set(string) -} - -# The identity_token and role_arn are for configuring this Stack to -# authenticate with AWS using OIDC. -variable "identity_token" { - type = string - ephemeral = true -} - -variable "role_arn" { - type = string -} -``` - -Then, set up your provider configuration to iterate through the `var.regions` variable to configure a version of that provider for each region. - -```hcl -# providers.tfstack.hcl - -required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.7.0" - } - - random = { - source = "hashicorp/random" - version = "~> 3.5.1" - } -} - - -provider "aws" "configurations" { -# This provider configuration iterates through and creates a configuration -# for each region. - for_each = var.regions - - config { - region = each.value - - assume_role_with_web_identity { - role_arn = var.role_arn - web_identity_token = var.identity_token - } - } -} -``` - -Each of your Stack’s deployments uses a separate AWS provider configuration for each region you defined in the `regions` variable. This means that in your configuration, you refer to the AWS provider for the `us-east-1` region as `provider.aws.configurations["us-east-1"]`. - -You can keep Stack components dynamic by using the `for_each` meta-argument to deploy a `component`’s Terraform module in each region. - -```hcl -# components.tfstack.hcl - -component "s3" { - for_each = var.regions - - source = "./s3" - - inputs = { - region = each.value - } - - providers = { - aws = provider.aws.configurations[each.value] - random = provider.random.this - } -} -``` - -The components in this example use the `for_each` meta-argument to deploy their Terraform module in the region for the current deployment. Notice how the component configures the AWS provider to use the correct provider for the given region with `provider.aws.configurations[each.value]`. - -## Deploy across accounts - -Stacks can also be helpful when managing infrastructure across different cloud provider accounts, ensuring that each account's infrastructure is consistent but isolated. - -```hcl -# deployments.tfdeploy.hcl - -identity_token "aws_prod" { - audience = ["aws.prod.workload.identity"] -} - -identity_token "aws_dev" { - audience = ["aws.dev.workload.identity"] -} - -deployment "development" { - inputs = { - aws_region = "us-east-1" - role_arn = "" - identity_token = identity_token.aws_dev.jwt - } -} - -deployment "production" { - inputs = { - regions = ["us-east-1", "us-west-1"] - role_arn = "" - identity_token = identity_token.aws_prod.jwt - } -} -``` - -Stacks enable you to define and deploy shared infrastructure components across different accounts, maintaining consistency while adhering to security and organizational boundaries. diff --git a/website/docs/language/state/backends.mdx b/website/docs/language/state/backends.mdx deleted file mode 100644 index acd4e11136..0000000000 --- a/website/docs/language/state/backends.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -page_title: 'Backends: State Storage and Locking' -description: >- - Backends are configured directly in Terraform files in the `terraform` - section. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# State Storage and Locking - -Backends are responsible for storing state and providing an API for -[state locking](/terraform/language/state/locking). State locking is optional. - -Despite the state being stored remotely, all Terraform commands such -as `terraform console`, the `terraform state` operations, `terraform taint`, -and more will continue to work as if the state was local. - -## State Storage - -Backends determine where state is stored. For example, the local (default) -backend stores state in a local JSON file on disk. The Consul backend stores -the state within Consul. Both of these backends happen to provide locking: -local via system APIs and Consul via locking APIs. - -When using a non-local backend, Terraform will not persist the state anywhere -on disk except in the case of a non-recoverable error where writing the state -to the backend failed. This behavior is a major benefit for backends: if -sensitive values are in your state, using a remote backend allows you to use -Terraform without that state ever being persisted to disk. - -In the case of an error persisting the state to the backend, Terraform will -write the state locally. This is to prevent data loss. If this happens, the -end user must manually push the state to the remote backend once the error -is resolved. - -## Manual State Pull/Push - -You can still manually retrieve the state from the remote state using -the `terraform state pull` command. This will load your remote state and -output it to stdout. You can choose to save that to a file or perform any -other operations. - -You can also manually write state with `terraform state push`. **This -is extremely dangerous and should be avoided if possible.** This will -overwrite the remote state. This can be used to do manual fixups if necessary. - -When manually pushing state, Terraform will attempt to protect you from -some potentially dangerous situations: - -- **Differing lineage**: The "lineage" is a unique ID assigned to a state - when it is created. If a lineage is different, then it means the states - were created at different times and its very likely you're modifying a - different state. Terraform will not allow this. - -- **Higher serial**: Every state has a monotonically increasing "serial" - number. If the destination state has a higher serial, Terraform will - not allow you to write it since it means that changes have occurred since - the state you're attempting to write. - -Both of these protections can be bypassed with the `-force` flag if you're -confident you're making the right decision. Even if using the `-force` flag, -we recommend making a backup of the state with `terraform state pull` -prior to forcing the overwrite. - -## State Locking - -Backends are responsible for supporting [state locking](/terraform/language/state/locking) -if possible. - -Not all backends support locking. The [documentation for each backend](/terraform/language/backend#available-backends) includes details about whether it supports locking or not. - -For more information on state locking, view the -[page dedicated to state locking](/terraform/language/state/locking). diff --git a/website/docs/language/state/import.mdx b/website/docs/language/state/import.mdx deleted file mode 100644 index 23fbcec6c2..0000000000 --- a/website/docs/language/state/import.mdx +++ /dev/null @@ -1,19 +0,0 @@ ---- -page_title: 'State: Import Existing Resources' -description: >- - Terraform stores state which caches the known state of the world the last time - Terraform ran. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 - -Terraform is able to import existing infrastructure. This allows you to take -resources you have created by some other means and bring them under Terraform management. - -To learn more, see [Import](/terraform/language/import). diff --git a/website/docs/language/state/index.mdx b/website/docs/language/state/index.mdx deleted file mode 100644 index ce44e3b373..0000000000 --- a/website/docs/language/state/index.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -page_title: State -description: >- - An introduction to state, information that Terraform uses to map resources to - a configuration, track metadata, and improve performance. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# State - -Terraform must store state about your managed infrastructure and -configuration. This state is used by Terraform to map real world -resources to your configuration, keep track of metadata, and to improve -performance for large infrastructures. - -This state is stored by default in a local file named "terraform.tfstate", -but we recommend [storing it in HCP Terraform](/terraform/cloud-docs/migrate) -to version, encrypt, and securely share it with your team. - -Terraform uses state to determine which changes to make to your -infrastructure. Prior to any operation, Terraform does a -[refresh](/terraform/cli/commands/refresh) to update the state with the -real infrastructure. - -The primary purpose of Terraform state is to store bindings between objects in -a remote system and resource instances declared in your configuration. -When Terraform creates a remote object in response to a change of configuration, -it will record the identity of that remote object against a particular -resource instance, and then potentially update or delete that object in -response to future configuration changes. - -For more information on why Terraform requires state and why Terraform cannot -function without state, please see the page [state purpose](/terraform/language/state/purpose). - -## Inspection and Modification - -While the format of the state files are just JSON, direct file editing -of the state is discouraged. Terraform provides the -[terraform state](/terraform/cli/commands/state) command to perform -basic modifications of the state using the CLI. - -The CLI usage and output of the state commands is structured to be -friendly for Unix tools such as grep, awk, etc. Additionally, the CLI -insulates users from any format changes within the state itself. The Terraform -project will keep the CLI working while the state format underneath it may -shift. - -Terraform expects a one-to-one mapping between configured resource instances -and remote objects. Normally that is guaranteed by Terraform being the one -to create each object and record its identity in the state, or to destroy -an object and then remove the binding for it. - -If you add or remove bindings in the state by other means, such as by importing -externally-created objects with `terraform import`, or by asking Terraform to -"forget" an existing object with `terraform state rm`, you'll then need to -ensure for yourself that this one-to-one rule is followed, such as by manually -deleting an object that you asked Terraform to "forget", or by re-importing it -to bind it to some other resource instance. - -## Format - -State snapshots are stored in JSON format and new Terraform versions are -generally backward compatible with state snapshots produced by earlier versions. -However, the state format is subject to change in new Terraform versions, so -if you build software that parses or modifies it directly you should expect -to perform ongoing maintenance of that software as the state format evolves -in new versions. - -Alternatively, there are several integration points which produce JSON output -that is specifically intended for consumption by external software: - -* [The `terraform output` command](/terraform/cli/commands/output) - has a `-json` option, for obtaining either the full set of root module output - values or a specific named output value from the latest state snapshot. -* [The `terraform show` command](/terraform/cli/commands/show) has a `-json` - option for inspecting the latest state snapshot in full, and also for - inspecting saved plan files which include a copy of the prior state at the - time the plan was made. - -A typical way to use these in situations where Terraform is running in -automation is to run them immediately after a successful `terraform apply` -to obtain a representation of the latest state snapshot, and then store that -result as an artifact associated with the automated run so that other software -can potentially consume it without needing to run Terraform itself. diff --git a/website/docs/language/state/locking.mdx b/website/docs/language/state/locking.mdx deleted file mode 100644 index 38b92563e9..0000000000 --- a/website/docs/language/state/locking.mdx +++ /dev/null @@ -1,46 +0,0 @@ ---- -page_title: 'State: Locking' -description: >- - Terraform stores state which caches the known state of the world the last time - Terraform ran. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# State Locking - -If supported by your [backend](/terraform/language/backend), Terraform will lock your -state for all operations that could write state. This prevents -others from acquiring the lock and potentially corrupting your state. - -State locking happens automatically on all operations that could write -state. You do not see any message that it happens. If state locking fails, -Terraform does not continue. You can disable state locking for most commands -with the `-lock=false` flag, but we do not recommend it. - -If acquiring the lock takes longer than expected, Terraform outputs -a status message. If Terraform does not output a message, state locking is -still occurring if your backend supports it. - -Not all backends support locking. The -[documentation for each backend](/terraform/language/backend) -includes details on whether it supports locking or not. - -## Force Unlock - -Terraform has a [force-unlock command](/terraform/cli/commands/force-unlock) -to manually unlock the state if unlocking failed. - -**Be very careful with this command.** If you unlock the state when someone -else is holding the lock it could cause multiple writers. Force unlock should -only be used to unlock your own lock in the situation where automatic -unlocking failed. - -To protect you, the `force-unlock` command requires a unique lock ID. Terraform -will output this lock ID if unlocking fails. This lock ID acts as a -[nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce), ensuring -that locks and unlocks target the correct lock. diff --git a/website/docs/language/state/purpose.mdx b/website/docs/language/state/purpose.mdx deleted file mode 100644 index 09a374ea7f..0000000000 --- a/website/docs/language/state/purpose.mdx +++ /dev/null @@ -1,115 +0,0 @@ ---- -page_title: State -description: >- - Terraform must store state about your managed infrastructure and - configuration. This state is used by Terraform to map real world resources to - your configuration, keep track of metadata, and to improve performance for - large infrastructures. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Purpose of Terraform State - -State is a necessary requirement for Terraform to function. It is often -asked if it is possible for Terraform to work without state, or for Terraform -to not use state and just inspect real world resources on every run. This page -will help explain why Terraform state is required. - -As you'll see from the reasons below, state is required. And in the scenarios -where Terraform may be able to get away without state, doing so would require -shifting massive amounts of complexity from one place (state) to another place -(the replacement concept). - -## Mapping to the Real World - -Terraform requires some sort of database to map Terraform config to the real -world. For example, when you have a resource `resource "aws_instance" "foo"` in your -configuration, Terraform uses this mapping to know that the resource `resource "aws_instance" "foo"` -represents a real world object with the instance ID `i-abcd1234` on a remote system. - -For some providers like AWS, Terraform could theoretically use something like -AWS tags. Early prototypes of Terraform actually had no state files and used -this method. However, we quickly ran into problems. The first major issue was -a simple one: not all resources support tags, and not all cloud providers -support tags. - -Therefore, for mapping configuration to resources in the real world, -Terraform uses its own state structure. - -Terraform expects that each remote object is bound to only one resource instance in the configuration. -If a remote object is bound to multiple resource instances, the mapping from configuration to the remote -object in the state becomes ambiguous, and Terraform may behave unexpectedly. Terraform can guarantee -a one-to-one mapping when it creates objects and records their identities in the state. -When importing objects created outside of Terraform, you must make sure that each distinct object -is imported to only one resource instance. - -## Metadata - -Alongside the mappings between resources and remote objects, Terraform must -also track metadata such as resource dependencies. - -Terraform typically uses the configuration to determine dependency order. -However, when you delete a resource from a Terraform configuration, Terraform -must know how to delete that resource from the remote system. Terraform can see that a mapping exists -in the state file for a resource not in your configuration and plan to destroy. However, since -the configuration no longer exists, the order cannot be determined from the -configuration alone. - -To ensure correct operation, Terraform retains a copy of the most recent set -of dependencies within the state. Now Terraform can still determine the correct -order for destruction from the state when you delete one or more items from -the configuration. - -Terraform could take another approach to dependency order by using an underlying hierarchy of order -between resource types. For example, Terraform could know that servers must be -deleted before the subnets they are a part of. The complexity for this approach -quickly explodes, however: in addition to Terraform having to understand the -ordering semantics of every resource for every _provider_, Terraform must also -understand the ordering _across providers_. - -Terraform also stores other metadata for similar reasons, such as a pointer -to the provider configuration that was most recently used with the resource -in situations where multiple aliased providers are present. - -## Performance - -In addition to basic mapping, Terraform stores a cache of the attribute -values for all resources in the state. This is the most optional feature of -Terraform state and is done only as a performance improvement. - -When running a `terraform plan`, Terraform must know the current state of -resources in order to effectively determine the changes that it needs to make -to reach your desired configuration. - -For small infrastructures, Terraform can query your providers and sync the -latest attributes from all your resources. This is the default behavior -of Terraform: for every plan and apply, Terraform will sync all resources in -your state. - -For larger infrastructures, querying every resource is too slow. Many cloud -providers do not provide APIs to query multiple resources at once, and the -round trip time for each resource is hundreds of milliseconds. On top of this, -cloud providers almost always have API rate limiting so Terraform can only -request a certain number of resources in a period of time. Larger users -of Terraform make heavy use of the `-refresh=false` flag as well as the -`-target` flag in order to work around this. In these scenarios, the cached -state is treated as the record of truth. - -## Syncing - -In the default configuration, Terraform stores the state in a file in the -current working directory where Terraform was run. This is okay for getting -started, but when using Terraform in a team it is important for everyone -to be working with the same state so that operations will be applied to the -same remote objects. - -[Remote state](/terraform/language/state/remote) is the recommended solution -to this problem. With a fully-featured state backend, Terraform can use -remote locking as a measure to avoid two or more different users accidentally -running Terraform at the same time, and thus ensure that each Terraform run -begins with the most recent updated state. diff --git a/website/docs/language/state/refactor.mdx b/website/docs/language/state/refactor.mdx deleted file mode 100644 index 6e669ea919..0000000000 --- a/website/docs/language/state/refactor.mdx +++ /dev/null @@ -1,275 +0,0 @@ ---- -page_title: Refactor Terraform state -description: >- - Learn how to move resources between state files and identify dependencies between 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Refactor Terraform state - -As your Terraform configuration grows in complexity, you might want to reorganize your resources to improve maintainability and performance. Terraform operations complete faster when you split configuration with large state files. - -This topic reviews the steps you must take to split your Terraform state across multiple configurations. First, you must plan how you will group your resources and identify inter-resource dependencies. Then you must choose the best approach to migrate resources from one state file to another. Finally, you must decide which approach to take to move resources between state files. - -Even small refactors require that you keep these principles in mind. Keep in mind that refactoring your configuration requires updating both the configuration and the corresponding state files. - -## Identify opportunities to refactor - -When refactoring your Terraform configuration, identify groups of resources that may benefit from a separate cadence of lifecycle management, or logically-related collections of resources that you can capture in a module instead. Refactoring your Terraform configuration should make it easier to maintain. - -The following are some common opportunities for refactoring: - -- **Long Terraform applies.** Your configuration has grown over time and become cumbersome to manage. Large, monolithic configuration can cause Terraform plan and apply operations to take a long time to complete and cause unintended changes. -- **Changes to management lifecycles.** Managing frequently updated resources separately from infrequently updated resources can help simplify your operations and reduce the blast radius of unintended changes. -- **Changes to resource ownership.** In some organizations, teams may split the responsibility of maintaining different parts of the architecture. In these cases, it is common for teams to refactor the configuration and state to match their area of ownership and scope. -- **Reusable module opportunity.** You have identified a subsection of your configuration that would make for a good module. If you create the same set of resources in multiple configurations, we recommend grouping those resources into a module and reusing it across your organization. - -## Plan your refactored state - -You must plan how you will group resources before starting refactoring your configuration. -Consider the following resource properties when deciding how to group resources together: - -- **Volatility and rate of change:** By exposing your long-living infrastructure to unnecessary volatility, you introduce more opportunities for accidental changes. For example, you may scale the number of compute resources your configuration deploys several times a day, but your networking configuration may stay static for months. By managing your network resources separately, you reduce the risk of making unintended changes to it. -- **Stateful versus stateless:** By managing stateful resources independently of stateless ones, such as separating databases from compute instances, you limit the blast radius of operations that re-provision resources and help protect against accidental data loss. -- **Access and team responsibility:** By splitting your workspaces by team, you limit the responsibility per workspace and allow teams to maintain distinct areas of ownership. This helps ensure that only users familiar with specific parts of your infrastructure make changes to the related configuration. - -To learn about different strategies for grouping resources, refer to the [Workspace best practices](/terraform/cloud-docs/workspaces/best-practices) documentation. - -## Identify dependencies - -As you migrate resources from one state file to another, you must identify dependencies between resources. For example, you may have compute resources that depend on your network resources. If you migrate those network resources to a new state file, your compute resources no longer be able to reference the network. - -We recommend using dynamic references rather than hardcoding information about resources in another configuration. Hardcoding information requires you to manually update the configuration whenever the data changes, which can lead to errors in your configuration or your deployed resources. - -You can use the following dynamic approaches to reference resources in another state file: - -- If your provider supports it, you can use a resource-specific data source to query your cloud provider. For example, you can use the [`aws_vpc`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) data source to look up information about a VPC created in another configuration. -- If you use HCP Terraform or Terraform Enterprise, you can use the [`tfe_outputs`](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) data source to reference outputs from another workspace. -- If you are using another remote backend, or the local backend, you can use the [`terraform_remote_state`](/terraform/language/state/remote-state-data) data source. To access state in an HCP Terraform workspace, you must explicitly specify which other workspaces have access. Refer to [remote state sharing](/terraform/cloud-docs/workspaces/settings#remote-state-sharing) for more information. - - -You can use the [`terraform graph`](/terraform/cli/commands/graph) command to help visualize the relationships between the resources in your configuration and identify any dependencies. - -## Migrate resources - -When you refactor your Terraform configuration, we recommend that you recreate stateless resources in a new Terraform configuration if you can do so without incurring downtime or extra cost. - -Stateful resources, such as databases and object stores, are more complicated to migrate. Often, you cannot delete and recreate them, or it may be complex and expensive to backup and restore the data. In this case, you can migrate your resources by moving them between state files. - -There are two common approaches to migrating resources between two Terraform state files: - -- [Remove and import](#remove-and-import): Explicitly remove resources from one Terraform state file, then add it to another. We recommend this approach since the `removed` and `import` blocks help keep a record of the configuration history. -- [Move resources directly to a new state file](#move-resources-directly-to-a-new-state-file): Use the `terraform state mv` command to move resources into a different state file. This is a legacy command, but is still supported in all versions of Terraform version 1.0 and newer. - -### Requirements - -[Removing and importing resources](#remove-and-import) requires Terraform version 1.7 or newer. - -[Moving resources directly to a new state file](#move-resources-directly-to-a-new-state-file) using the Terraform CLI requires Terraform version 1.0 or newer. - -### Remove and import - -You can use Terraform's configuration-driven `removed` and `import` blocks to move resources between state files without destroying them. - -The following example is an initial resource configuration that you will move to a new state file. - - - -```hcl -resource "aws_instance" "example" { - instance_type = "t3.micro" - ami = data.aws_ami.example.id -} -``` - - - -In your source configuration, complete the following steps to remove the resources: - -1. Retrieve your latest Terraform state and save the output to a file as a backup. - - ```shell-session - $ terraform state pull > terraform.tfstate.backup - ``` - -1. Review your provider's configuration to check which attribute you must use to import your resource type before you remove it. For example, the import [`aws_instance`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#import) resource uses the `id` attribute to import an EC2 instance into your Terraform state. - - ```shell-session - $ terrafrom state show aws_instance.example - ##... - id = "i-07b510cff5f79af00" - ##... - ``` - -1. For each resource you want to migrate, replace the `resource` block with a `removed` block to remove the resource from your state without destroying it. These `removed` blocks can exist anywhere in your configuration, but we recommend your organization standardizes where to declare these blocks to help with future maintenance. One common approach is defining the `removed` block in the file that previously contained the corresponding `resource` block. - - - - ```diff - - resource "aws_instance" "example" { - - instance_type = "t3.micro" - - ami = data.aws_ami.example.id - - } - - + removed { - + from = aws_instance.example - + lifecycle { - + destroy = false - + } - + } - ``` - - - -1. Run `terraform plan` to ensure that Terraform will not destroy the resources. - - - - ```bash - # aws_instance.example will no longer be managed by Terraform, but will not be destroyed - # (destroy = false is set in the configuration) - . resource "aws_instance" "example" { - id = "i-07b510cff5f79af00" - ##... - ``` - - - -1. Run `terraform apply` to remove the resource from state. - -Then, in your destination configuration, complete the following steps to import the resources: - -1. Add the resources to the configuration you are migrating the resources to. -1. For each added resource, add an `import` block to add the resource to your state without recreating it. These `import` blocks can exist anywhere in your configuration, but we recommend you standardize on location in your organization to help with future maintenance. One common practice is to define the `import` block in the same file you add the `resource` block to. - - ```hcl - resource "aws_instance" "example" { - instance_type = "t3.micro" - ami = data.aws_ami.example.id - } - - import { - id = "i-07b510cff5f79af00" - to = aws_instance.example - } - ``` - -1. Run `terraform plan` to ensure that Terraform will properly import the resources. - - - - ```bash - # aws_instance.example will be imported - resource "aws_instance" "example" { - ``` - - - -1. Run `terraform apply` to complete the import. - - ```shell-session - $ terraform apply - - ##... - - Plan: 1 to import, 0 to add, 0 to change, 0 to destroy. - - 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 - - aws_instance.example: Importing... [id=i-12345678901234567] - aws_instance.example: Import complete [id=i-12345678901234567] - - Apply complete! Resources: 1 imported, 0 added, 0 changed, 0 destroyed. - ``` - -After you complete the migration you can optionally remove the `removed` and `import` blocks, or choose to keep them as a record of the resource's lifecycle. - -Refer to the following documentation to learn more about the `removed` and `import` blocks: - -- [Removing resources](/terraform/language/resources/syntax#removing-resources) -- [Import block reference documentation](/terraform/language/import) - -### Move resources directly to a new state file - -You can also use the `terraform state mv` command to move resources directly between state files. - - - -The `-state` and `-state-out` flags are legacy options that Terraform maintains for backwards compatibility. - -This approach also uses the `terraform state pull` and `terraform state push` commands. While Terraform performs safety checks when you manually update remote state, this method does have some risk of corrupting your remote state. - -We recommend that you use the `removed` and `import` blocks documented above for any new migrations. - - - -#### Prepare the state files - -If you are using the local state backend, you can move resources directly between two state files. If you are using a remote state backend, such as HCP Terraform or AWS S3, you must first download the state files for the source and destination workspaces. - -To download the state files, complete the following steps: - -1. In the directory with your source configuration, use the `terraform state pull` command to save the state file locally. - - ```shell-session - $ terraform state pull > source.tfstate - ``` - -1. In the directory with your destination configuration, use the `terraform state pull` command to save the state file locally. - - ```shell-session - $ terraform state pull > destination.tfstate - ``` - -#### Move the resources - -Next, use the `terraform state mv` command to move the resource from the source state to the destination state. - -```shell-session -$ terraform state mv -state source/source.tfstate -state-out destination/destination.tfstate aws_instance.example aws_instance.example - -Move "aws_instance.example" to "aws_instance.example" -Successfully moved 1 object(s). -``` - -The `terraform state mv` command uses the `-state` flag to point to the source state file, and the `-state-out` flag to point to the destination state file. The final two arguments tell Terraform which resource to move out from the source state, and the resource to move it to in the destination state. - -Repeat this step for every resource you want to migrate. - -#### Push the state files - -If you are using a remote backend, you must push the state files to the backend with the `terraform state push` command. - -1. In the directory with your source configuration, use the `terraform state push` command to update the remote state. - - ```shell-session - $ terraform state push source.tfstate - ``` - -1. In the directory with your destination configuration, use the `terraform state push` command to update the remote state. - - ```shell-session - $ terraform state push destination.tfstate - ``` - -#### Update your configuration and verify the migration - -Next, update your configuration to match your state, and then verify that your changes are correct. - -1. Remove the resources that you migrated from your source configuration. -1. Run `terraform plan` on your source configuration and ensure that Terraform will not make any changes to your infrastructure. -1. Add the resources that you migrated to your destination configuration. -1. Run `terraform plan` on your destination configuration and ensure that Terraform will not make any changes to your infrastructure. -1. Create pull requests for the repositories that store your source and destination configurations. If your code review process creates a speculative plan for changes to your Terraform configuration, review the results and ensure that Terraform will not make any changes to your infrastructure. -1. Merge the pull requests. - -Refer to the [`terraform state mv` command reference documentation](/terraform/cli/commands/state/mv) to learn more. diff --git a/website/docs/language/state/remote-state-data.mdx b/website/docs/language/state/remote-state-data.mdx deleted file mode 100644 index 25b44b6ae3..0000000000 --- a/website/docs/language/state/remote-state-data.mdx +++ /dev/null @@ -1,214 +0,0 @@ ---- -page_title: The terraform_remote_state Data Source -description: >- - Retrieves the root module output values from a Terraform state snapshot stored - in a remote backend. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# The `terraform_remote_state` Data Source - -[backends]: /terraform/language/backend - -The `terraform_remote_state` data source uses the latest state snapshot from a specified state backend to retrieve the root module output values -from some other Terraform configuration. - -You can use the `terraform_remote_state` data source without requiring or configuring a provider. It is always available through a built-in provider with the [source address](/terraform/language/providers/requirements#source-addresses) `terraform.io/builtin/terraform`. That provider does not include any other resources or data sources. - -~> **Important:** We recommend using the [`tfe_outputs` data source](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) in the [HCP Terraform/Enterprise Provider](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs) to access remote state outputs in HCP Terraform or Terraform Enterprise. The `tfe_outputs` data source is more secure because it does not require full access to workspace state to fetch outputs. - -## Alternative Ways to Share Data Between Configurations - -Sharing data with root module outputs is convenient, but it has drawbacks. -Although `terraform_remote_state` only exposes output values, its user must have -access to the entire state snapshot, which often includes some sensitive -information. - -When possible, we recommend explicitly publishing data for external consumption -to a separate location instead of accessing it via remote state. This lets you -apply different access controls for shared information and state snapshots. - -To share data explicitly between configurations, you can use pairs of managed -resource types and data sources in various providers, including (but not -limited to) the following: - -| System | Publish with... | Read with... | -| ---------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Alibaba Cloud DNS
(for IP addresses and hostnames) | [`alicloud_alidns_record` resource type](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/alidns_record) | Normal DNS lookups, or [the `dns` provider](https://registry.terraform.io/providers/hashicorp/dns/latest/docs) | -| Amazon Route53
(for IP addresses and hostnames) | [`aws_route53_record` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route53_record) | Normal DNS lookups, or [the `dns` provider](https://registry.terraform.io/providers/hashicorp/dns/latest/docs) | -| Amazon S3 | [`aws_s3_object` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | [`aws_s3_object` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/s3_object) | -| Amazon SSM Parameter Store | [`aws_ssm_parameter` resource type](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ssm_parameter) | [`aws_ssm_parameter` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | -| Azure Automation | [`azurerm_automation_variable_string` resource type](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/automation_variable_string) | [`azurerm_automation_variable_string` data source](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/automation_variable_string) | -| Azure DNS
(for IP addresses and hostnames) | [`azurerm_dns_a_record` resource type](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/dns_a_record), etc | Normal DNS lookups, or [the `dns` provider](https://registry.terraform.io/providers/hashicorp/dns/latest/docs) | -| Google Cloud DNS
(for IP addresses and hostnames) | [`google_dns_record_set` resource type](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | Normal DNS lookups, or [the `dns` provider](https://registry.terraform.io/providers/hashicorp/dns/latest/docs) | -| Google Cloud Storage | [`google_storage_bucket_object` resource type](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket_object) | [`google_storage_bucket_object` data source](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/storage_bucket_object) and [`http` data source](https://registry.terraform.io/providers/hashicorp/http/latest/docs/data-sources/http) | -| HashiCorp Consul | [`consul_key_prefix` resource type](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/resources/key_prefix) | [`consul_key_prefix` data source](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/data-sources/key_prefix) | -| HashiCorp HCP Terraform | Normal `outputs` terraform block | [`tfe_outputs` data source](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) | -| Kubernetes | [`kubernetes_config_map` resource type](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/config_map) | [`kubernetes_config_map` data source](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/data-sources/config_map) | -| OCI Object Storage | [`oci_objectstorage_bucket` resource type](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/resources/objectstorage_object) | [`oci_objectstorage_bucket` data source](https://registry.terraform.io/providers/hashicorp/oci/latest/docs/data-sources/objectstorage_object) | - --> These are some common options from the Official Terraform providers, but -there are too many configuration storage options for us to list them all -here, including some in partner and community providers. -Any pair of managed resource type and corresponding data source can potentially -be used to share data between Terraform configurations. See individual provider -documentation to find other possibilities. - -A key advantage of using a separate explicit configuration store instead of -`terraform_remote_state` is that the data can potentially also be read by -systems other than Terraform, such as configuration management or scheduler -systems within your compute instances. For that reason, we recommend selecting -a configuration store that your other infrastructure could potentially make -use of. For example: - -* If you wish to share IP addresses and hostnames, you could publish them as - normal DNS `A`, `AAAA`, `CNAME`, and `SRV` records in a private DNS zone and - then configure your other infrastructure to refer to that zone so you can - find infrastructure objects via your system's built-in DNS resolver. -* If you use HashiCorp Consul then publishing data to the Consul key/value - store or Consul service catalog can make that data also accessible via - [Consul Template](https://github.com/hashicorp/consul-template) - or the - [HashiCorp Nomad](/nomad/docs/job-specification/template) - `template` stanza. -* If you use Kubernetes then you can - [make Config Maps available to your Pods](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/). - -Some of the data stores listed above are specifically designed for storing -small configuration values, while others are generic blob storage systems. For -those generic systems, you can use -[the `jsonencode` function](/terraform/language/functions/jsonencode) -and -[the `jsondecode` function](/terraform/language/functions/jsondecode) respectively -to store and retrieve structured data. - -You can encapsulate the implementation details of retrieving your published -configuration data by writing a -[data-only module](/terraform/language/modules/develop/composition#data-only-modules) -containing the necessary data source configuration and any necessary -post-processing such as JSON decoding. You can then change that module later -if you switch to a different strategy for sharing data between multiple -Terraform configurations. - -## Example Usage (`remote` Backend) - -```hcl -data "terraform_remote_state" "vpc" { - backend = "remote" - - config = { - organization = "hashicorp" - workspaces = { - name = "vpc-prod" - } - } -} - -# Terraform >= 0.12 -resource "aws_instance" "foo" { - # ... - subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id -} - -# Terraform <= 0.11 -resource "aws_instance" "foo" { - # ... - subnet_id = "${data.terraform_remote_state.vpc.subnet_id}" -} -``` - -## Example Usage (`local` Backend) - -```hcl -data "terraform_remote_state" "vpc" { - backend = "local" - - config = { - path = "..." - } -} - -# Terraform >= 0.12 -resource "aws_instance" "foo" { - # ... - subnet_id = data.terraform_remote_state.vpc.outputs.subnet_id -} - -# Terraform <= 0.11 -resource "aws_instance" "foo" { - # ... - subnet_id = "${data.terraform_remote_state.vpc.subnet_id}" -} -``` - -## Argument Reference - -The following arguments are supported: - -* `backend` - (Required) The remote backend to use. -* `workspace` - (Optional) The Terraform workspace to use, if the backend - supports workspaces. -* `config` - (Optional; object) The configuration of the remote backend. - Although this argument is listed as optional, most backends require - some configuration. - - The `config` object can use any arguments that would be valid in the - equivalent `terraform { backend "" { ... } }` block. See - [the documentation of your chosen backend](/terraform/language/backend) - for details. - - -> **Note:** If the backend configuration requires a nested block, specify - it here as a normal attribute with an object value. (For example, - `workspaces = { ... }` instead of `workspaces { ... }`.) -* `defaults` - (Optional; object) Default values for outputs, in case the state - file is empty or lacks a required output. - -## Attributes Reference - -In addition to the above, the following attributes are exported: - -* (v0.12+) `outputs` - An object containing every root-level - [output](/terraform/language/values/outputs) in the remote state. -* (<= v0.11) `` - Each root-level [output](/terraform/language/values/outputs) - in the remote state appears as a top level attribute on the data source. - -## Root Outputs Only - -Only the root-level output values from the remote state snapshot are exposed -for use elsewhere in your module. Resource data and output values from nested -modules are not accessible. - -If you wish to make a nested module output value accessible as a root module -output value, you must explicitly configure a passthrough in the root module. -For example: - -For example: - -```hcl -module "app" { - source = "..." -} - -output "app_value" { - # This syntax is for Terraform 0.12 or later. - value = module.app.example -} -``` - -In this example, the output value named `example` from the "app" module is -available as the `app_value` root module output value. If this configuration -didn't include the `output "app_value"` block then the data would not be -accessible via `terraform_remote_state`. - -~> **Warning:** Although `terraform_remote_state` doesn't expose any other -state snapshot information for use in configuration, the state snapshot data -is a single object and so any user or server which has enough access to read -the root module output values will also always have access to the full state -snapshot data by direct network requests. Don't use `terraform_remote_state` -if any of the resources in your configuration work with data that you consider -sensitive. diff --git a/website/docs/language/state/remote.mdx b/website/docs/language/state/remote.mdx deleted file mode 100644 index 0d050131bd..0000000000 --- a/website/docs/language/state/remote.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -page_title: 'State: Remote Storage' -description: >- - Terraform can store the state remotely, making it easier to version and work - with in a 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Remote State - -By default, Terraform stores state locally in a file named `terraform.tfstate`. -When working with Terraform in a team, use of a local file makes Terraform -usage complicated because each user must make sure they always have the latest -state data before running Terraform and make sure that nobody else runs -Terraform at the same time. - -With _remote_ state, Terraform writes the state data to a remote data store, -which can then be shared between all members of a team. Terraform supports -storing state in [HCP Terraform](https://www.hashicorp.com/products/terraform/), -[HashiCorp Consul](https://www.consul.io/), Amazon S3, Azure Blob Storage, Google Cloud Storage, Alibaba Cloud OSS, and more. - -Remote state is implemented by a [backend](/terraform/language/backend) or by -HCP Terraform, both of which you can configure in your configuration's root module. - -## Delegation and Teamwork - -Remote state allows you to share -[output values](/terraform/language/values/outputs) with other configurations. -This allows your infrastructure to be decomposed into smaller components. - -Put another way, remote state also allows teams to share infrastructure -resources in a read-only way without relying on any additional configuration -store. - -For example, a core infrastructure team can handle building the core -machines, networking, etc. and can expose some information to other -teams to run their own infrastructure. As a more specific example with AWS: -you can expose things such as VPC IDs, subnets, NAT instance IDs, etc. through -remote state and have other Terraform states consume that. - -For example usage, see -[the `terraform_remote_state` data source](/terraform/language/state/remote-state-data). - -While remote state can be a convenient, built-in mechanism for sharing data -between configurations, you may prefer to use more general stores to -pass settings both to other configurations and to other consumers. For example, -if your environment has [HashiCorp Consul](https://www.consul.io/) then you -can have one Terraform configuration that writes to Consul using -[`consul_key_prefix`](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/resources/key_prefix) and then -another that consumes those values using -[the `consul_keys` data source](https://registry.terraform.io/providers/hashicorp/consul/latest/docs/data-sources/keys). - -## Locking and Teamwork - -For fully-featured remote backends, Terraform can also use -[state locking](/terraform/language/state/locking) to prevent concurrent runs of -Terraform against the same state. - -[HCP Terraform by HashiCorp](https://www.hashicorp.com/products/terraform/) -is a commercial offering that supports an even stronger locking concept that -can also detect attempts to create a new plan when an existing plan is already -awaiting approval, by queuing Terraform operations in a central location. -This allows teams to more easily coordinate and communicate about changes to -infrastructure. diff --git a/website/docs/language/state/sensitive-data.mdx b/website/docs/language/state/sensitive-data.mdx deleted file mode 100644 index 268ba57aa7..0000000000 --- a/website/docs/language/state/sensitive-data.mdx +++ /dev/null @@ -1,48 +0,0 @@ ---- -page_title: 'State: Sensitive Data' -description: Sensitive data in 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Sensitive Data in State - -Terraform state can contain sensitive data, depending on the resources in use -and your definition of "sensitive." Unless your variables or resources are `ephemeral`, the state contains resource IDs and all resource attributes. For resources such as databases, this can contain initial -passwords. - -When using local state, state is stored in plain-text JSON files. - -When using [remote state](/terraform/language/state/remote), state is only ever held in memory when used by Terraform. It may be encrypted at rest, but this depends on the specific remote state backend. - -## Ephemeral data - --> **Note**: Ephemeral variables, outputs, and resources are available in Terraform v1.10 and later. - -Terraform allows you to mark variables and outputs as ephemeral. Providers can also support specific `ephemeral` resources. Ephemerality in Terraform means that the data of a block is available during runtime, but Terraform does not write that data to state or plan files. The `ephemeral` property is helpful when managing credentials, tokens, or other temporary resources you do not want to store in Terraform state files. - -Learn more about defining ephemeral [input variables](/terraform/language/values/variables#exclude-values-from-state), [outputs](/terraform/language/values/outputs#ephemeral-avoid-storing-values-in-state-or-plan-files), and [resources](/terraform/language/resources/ephemeral). - -## Recommendations - -Treat the state as sensitive data if you manage secret credentials like database passwords, user passwords, or private keys with Terraform. You can also mark your sensitive data in variables as `ephemeral` to prevent Terraform from writing those variables to your state and plan files. - -Storing state remotely can provide better security. As of Terraform 0.9, -Terraform does not persist state to the local disk when remote state is in use, -and some backends can be configured to encrypt the state data at rest. - -For example: - -- [HCP Terraform](https://cloud.hashicorp.com/products/terraform) always encrypts state at rest and - protects it with TLS in transit. HCP Terraform also knows the identity of - the user requesting state and maintains a history of state changes. This can - be used to control access and track activity. [Terraform Enterprise](/terraform/enterprise) - also supports detailed audit logging. -- The S3 backend supports encryption at rest when the `encrypt` option is - enabled. IAM policies and logging can be used to identify any invalid access. - Requests for the state go over a TLS connection. -- The GCS (Google Cloud Storage) backend supports using [customer-supplied](/terraform/language/backend/gcs#customer-supplied-encryption-keys) or [customer-managed (Cloud KMS)](/terraform/language/backend/gcs#customer-managed-encryption-keys-cloud-kms) encryption keys. diff --git a/website/docs/language/state/workspaces.mdx b/website/docs/language/state/workspaces.mdx deleted file mode 100644 index a94874259a..0000000000 --- a/website/docs/language/state/workspaces.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -page_title: 'State: Workspaces' -description: >- - Workspaces allow the use of multiple states with a single configuration - 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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Workspaces - -Each Terraform configuration has an associated [backend](/terraform/language/backend) that defines how Terraform executes operations and where Terraform stores persistent data, like [state](/terraform/language/state/purpose). - -The persistent data stored in the backend belongs to a workspace. The backend initially has only one workspace containing one Terraform state associated with that configuration. Some backends support multiple named workspaces, allowing multiple states to be associated with a single configuration. The configuration still has only one backend, but you can deploy multiple distinct instances of that configuration without configuring a new backend or changing authentication -credentials. - --> **Note**: The Terraform CLI workspaces are different from [workspaces in HCP Terraform](/terraform/cloud-docs/workspaces). Refer to [Connect to HCP Terraform](/terraform/cli/cloud/settings) for details about migrating a configuration with multiple workspaces to HCP Terraform. - -## Backends Supporting Multiple Workspaces - -You can use multiple workspaces with the following backends: - -- [AzureRM](/terraform/language/backend/azurerm) -- [Consul](/terraform/language/backend/consul) -- [COS](/terraform/language/backend/cos) -- [GCS](/terraform/language/backend/gcs) -- [Kubernetes](/terraform/language/backend/kubernetes) -- [Local](/terraform/language/backend/local) -- [OSS](/terraform/language/backend/oss) -- [Postgres](/terraform/language/backend/pg) -- [Remote](/terraform/language/backend/remote) -- [S3](/terraform/language/backend/s3) - - -## Using Workspaces - -~> **Important:** Workspaces are not appropriate for system decomposition or deployments requiring separate credentials and access controls. Refer to [Use Cases](/terraform/cli/workspaces#use-cases) in the Terraform CLI documentation for details and recommended alternatives. - -Terraform starts with a single, default workspace named `default` that you cannot delete. If you have not created a new workspace, you are using the default workspace in your Terraform working directory. - -When you run `terraform plan` in a new workspace, Terraform does not access existing resources in other workspaces. These resources still physically exist, but you must switch workspaces to manage them. - -Refer to the [Terraform CLI workspaces](/terraform/cli/workspaces) documentation for full details about how to create and use workspaces. - - -## Current Workspace Interpolation - -Within your Terraform configuration, you may include the name of the current -workspace using the `${terraform.workspace}` interpolation sequence. This can -be used anywhere interpolations are allowed. - -Referencing the current workspace is useful for changing behavior based -on the workspace. For example, for non-default workspaces, it may be useful -to spin up smaller cluster sizes. For example: - -```hcl -resource "aws_instance" "example" { - count = terraform.workspace == "default" ? 5 : 1 - - # ... other arguments -} -``` - -Another popular use case is using the workspace name as part of naming or -tagging behavior: - -```hcl -resource "aws_instance" "example" { - tags = { - Name = "web - ${terraform.workspace}" - } - - # ... other arguments -} -``` diff --git a/website/docs/language/style.mdx b/website/docs/language/style.mdx deleted file mode 100644 index 96f7d8f928..0000000000 --- a/website/docs/language/style.mdx +++ /dev/null @@ -1,687 +0,0 @@ ---- -page_title: Style Guide - Configuration Language -description: >- - Learn recommended style conventions for Terraform configuration and - workflows. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Style Guide - -The flexibility of Terraform's configuration language gives you many options to choose from as you write your code, structure your directories, and test your configuration. While some design decisions depend on your organization's needs or preferences, there are some common patterns that we suggest you adopt. Adopting and adhering to a style guide keeps your Terraform code legible, scalable, and maintainable. - -This article discusses best practices and some considerations to keep in mind as you develop your organization's style guide. The article is split into two sections. The first section covers code style recommendations, such as formatting and resource organization. The second section covers operations and workflow recommendations, such as lifecycle management through meta-arguments, versioning, and sensitive data management. - -## Code style - -Writing Terraform code in a consistent style makes it easier to read and maintain. The following sections discuss code style recommendations, including the following: - -- Run `terraform fmt` and `terraform validate` before committing your code to version control. -- Use a linter such as [TFLint](https://github.com/terraform-linters/tflint) to enforce your organization's own coding best practices. -- Use `#` for single and multi-line comments. -- Use nouns for resource names and do not include the resource type in the name. -- Use underscores to separate multiple words in names. Wrap the resource type and name in double quotes in your resource definition. -- Let your code build on itself: define dependent resources after the resources they reference. -- Include a type and description for every variable. -- Include a description for every output. -- Avoid overuse of variables and local values. -- Always include a default provider configuration. -- Use `count` and `for_each` sparingly. - -## Code formatting - -The Terraform parser allows you some flexibility in how you lay out the elements in your configuration files, but the Terraform language also has some idiomatic style conventions which we recommend users always follow for consistency between files and modules written by different teams. - -- Indent two spaces for each nesting level -- When multiple arguments with single-line values appear on consecutive lines at the same nesting level, align their equals signs: - - - - ```hcl - ami = "abc123" - instance_type = "t2.micro" - ``` - - - -- When both arguments and blocks appear together inside a block body, place all of the arguments together at the top and then place nested blocks below them. Use one blank line to separate the arguments from the blocks. -- Use empty lines to separate logical groups of arguments within a block. -- For blocks that contain both arguments and "meta-arguments" (as defined by the Terraform language semantics), list meta-arguments first and separate them from other arguments with one blank line. Place meta-argument blocks last and separate them from other blocks with one blank line. Refer to [dynamic resource count](#dynamic-resource-count) for more information on meta-arguments. - - - - ```hcl - resource "aws_instance" "example" { - # meta-argument first - count = 2 - - ami = "abc123" - instance_type = "t2.micro" - - network_interface { - # ... - } - - # meta-argument block last - lifecycle { - create_before_destroy = true - } - } - ``` - - - -- Top-level blocks should always be separated from one another by one blank line. Nested blocks should also be separated by blank lines, except when grouping together related blocks of the same type (like multiple `provisioner` blocks in a resource). -- Avoid grouping multiple blocks of the same type with other blocks of a different type, unless the block types are defined by semantics to form a family. (For example: `root_block_device`, `ebs_block_device` and `ephemeral_block_device` on `aws_instance` form a family of block types describing AWS block devices, and can therefore be grouped together and mixed.) - -The `terraform fmt` command formats your Terraform configuration to a subset of the above recommendations. By default, the `terraform fmt` command will only modify your Terraform code in the directory that you execute it in, but you can include the `-recursive` flag to modify code in all subdirectories as well. - -We recommend that you run `terraform fmt` before each commit to version control. You can use mechanisms such as [Git pre-commit hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) to automatically run this command each time you commit your code. - -If you use Microsoft VS Code, use the [Terraform VS Code extension](https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform) to enable features such as syntax highlighting and validation, automatic code formatting, and integration with HCP Terraform. If your development environment or text editor supports the [Language Server Protocol](https://microsoft.github.io/language-server-protocol/), you can use the [Terraform Language Server](https://github.com/hashicorp/terraform-ls) to access most of the VS Code extension features. - -## Code validation - -The `terraform validate` command checks that your configuration is syntactically valid and internally consistent. The `validate` command does not check if argument values are valid for a specific provider, but it will verify that they are the correct type. It does not evaluate any existing state. - -The `terraform validate` command is safe to run automatically and frequently. You can configure your text editor to run this command as a post-save check, define it as a pre-commit hook in a Git repository, or run it as a step in a CI/CD pipeline. - -For more information, refer to the [Terraform `validate` documentation](/terraform/cli/commands/validate). - -## File names - -We recommend the following file naming conventions: - -- A `backend.tf` file that contains your [backend configuration](/terraform/language/backend). You can define multiple `terraform` blocks in your configuration to separate your backend configuration from your Terraform and provider versioning configuration. -- A `main.tf` file that contains all resource and data source blocks. -- A `outputs.tf` file that contains all output blocks in alphabetical order. -- A `providers.tf` file that contains all `provider` blocks and configuration. -- A `terraform.tf` file that contains a single `terraform` block which defines your `required_version` and `required_providers`. -- A `variables.tf` file that contains all variable blocks in alphabetical order. -- A `locals.tf` file that contains local values. Refer to [local values](#local-values) for more information. -- A `override.tf` file that contains override definitions for your configuration. Terraform loads this and all files ending with `_override.tf` last. Use them sparingly and add comments to the original resource definitions, as these overrides make your code harder to reason about. Refer to the [override files](/terraform/language/files/override) documentation for more information. - -As your codebase grows, limiting it to just these files can become difficult to maintain. If your code becomes hard to navigate due to its size, we recommend that you organize resources and data sources in separate files by logical groups. For example, if your web application requires networking, storage, and compute resources, you might create the following files: - -- A `network.tf` file that contains your VPC, subnets, load balancers, and all other networking resources. -- A `storage.tf` file that contains your object storage and related permissions configuration. -- A `compute.tf` file that contains your compute instances. - - -No matter how you decide to split your code, it should be immediately clear where a maintainer can find a specific resource or data source definition. - -As your configuration grows, you may need to separate it into multiple state files. The HashiCorp Well-Architected Framework provides more guidance about [configuration structure and scope](/well-architected-framework/operational-excellence/operational-excellence-workspaces-projects#workspace-structure). - -## Linting and static code analysis - -Terraform does not have a built-in linter, but many organizations rely on a third-party linting tool such as [TFLint](https://github.com/terraform-linters/tflint) to enforce code standards. A linter uses static code analysis to compare your Terraform code against a set of rules. Most linters ship with a default set of rules, but also let you write your own. - -## Comments - -Write your code so it is easy to understand. Only when necessary, use comments to clarify complexity for other maintainers. - -Use `#` for both single- and multi-line comments. The `//` and `/* */` comment syntaxes are not considered idiomatic, but Terraform supports them to remain backward-compatible with earlier versions of HCL. - - - -```hcl -# Each tunnel is responsible for encrypting and decrypting traffic exiting -# and leaving its associated gateway. -resource "google_compute_vpn_tunnel" "tunnel1" { - ## ... -``` - - - -## Resource naming - -Every resource within a configuration must have a unique name. For consistency and readability, use a descriptive noun and separate words with underscores. Do not include the resource type in the resource identifier since the resource address already includes it. Wrap the resource type and name in double quotes. - -❌ Bad: - - - -```hcl -resource aws_instance webAPI-aws-instance {...} -``` - - - -✅ Good: - - - -```hcl -resource "aws_instance" "web_api" {...} -``` - - - -## Resource order - -The order of the resources and data sources in your code does not affect how Terraform builds them, so organize your resources for readability. Terraform determines the creation order based on cross-resource dependencies. - -How you order your resources largely depends on the size and complexity of your code, but we recommend defining data sources alongside the resources that reference them. For readability, your Terraform code should “build on itself” — you should define a data source before the resource that references it. - -The following example defines an `aws_instance` that relies on two data sources, `aws_ami` and `aws_availability_zone`. For readability and continuity, it defines the data sources before the `aws_instance` resource. - - - -```hcl -data "aws_ami" "web" { - ##... -} - -data "aws_availability_zones" "available" { - ##... -} - -resource "aws_instance" "web" { - ami = data.aws_ami.web.id - availability_zone = data.aws_availability_zones.available.names[0] - ##... -} -``` - - - -We recommend following a consistent order for resource parameters: - -1. If present, The `count` or `for_each` meta-argument. -1. Resource-specific non-block parameters. -1. Resource-specific block parameters. -1. If required, a `lifecycle` block. -1. If required, the `depends_on` parameter. - -## Variables - -While variables make your modules more flexible, overusing variables can make code difficult to understand. When deciding whether to expose a variable for a resource setting, consider whether that parameter will change between deployments. - -- Define a `type` and a `description` for every variable. -- If the variable is optional, define a reasonable `default`. -- For sensitive variables, such as passwords and private keys, set the `sensitive` parameter to `true`. Remember that Terraform will still store this value in plain text in its state, but it will not display it when you run `terraform plan` or `terraform apply`. Refer to [secrets management](#secrets-management) for more information on how to securely handle sensitive values. -- Use [input variable validation](/terraform/language/values/variables#custom-validation-rules) to create additional rules for your variable values in addition to Terraform's type validation. Only use variable validation when your variable values have uniquely restrictive requirements. For example, if your Terraform configuration requires two web instances, add a `validation` block to enforce it: - - - - ```hcl - variable "web_instance_count" { - type = number - description = "Number of web instances to deploy. This application requires at least two instances." - - validation { - condition = var.web_instance_count > 1 - error_message = "This application requires at least two web instances." - } - } - ``` - - - -We recommend following a consistent order for variable parameters: - -1. Type -1. Description -1. Default (optional) -1. Sensitive (optional) -1. [Validation blocks](/terraform/language/values/variables#custom-validation-rules) - -## Outputs - -Output values let you expose data about your infrastructure on the command line and make it easy to reference in other Terraform configurations. Like you would for variables, provide a `description` for each output. - -We recommend that you use the following order for your output parameters: - -1. Description -1. Value -1. Sensitive (optional) - -Every variable and output requires a unique name. For consistency and readability, we recommend that you use a descriptive noun and separate words with underscores. - - - - ```hcl -variable "db_disk_size" { - type = number - description = "Disk size for the API database" - default = 100 -} - -variable "db_password" { - type = string - description = "Database password" - sensitive = true -} - -output "web_public_ip" { - description = "Public IP of the web instance" - value = aws_instance.web.public_ip -} -``` - - - -## Local values - -Local values let you reference an [expression](/terraform/language/expressions) or value multiple times. Use local values sparingly, as overuse can make your code harder to understand. - -For example, you can use a local value to create a suffix for the region and environment (for example, `development` or `test`), and append it to multiple resources. - - - -```hcl -locals { - name_suffix = "${var.region}-${var.environment}" -} - -resource "aws_instance" "web" { - ami = data.aws_ami.ubuntu.id - instance_type = "t3.micro" - - tags = { - Name = "web-${local.name_suffix}" - } -} -``` - - - -Define local values in one of two places: - -- If you reference the local value in multiple files, define it in a file named `locals.tf`. -- If the local value is specific to a file, define it at the top of that file. - -As for other Terraform objects, use descriptive nouns for local value names and underscores to separate multiple words. - -For more information, refer to the [local values documentation](/terraform/language/values/locals) and the [Simplify Terraform configuration with locals](/terraform/tutorials/configuration-language/locals) tutorial. - -## Provider aliasing - -Provider aliasing lets you define multiple `provider` blocks for the same Terraform provider. Potential use cases for aliases include provisioning resources in multiple regions within a single configuration. The `provider` meta-argument for resources and the `providers` meta-argument for modules specifies which provider to use. - - - -```hcl -provider "aws" { - region = "us-east-1" -} - -provider "aws" { - alias = "west" - region = "us-west-2" -} -``` - - - - - -```hcl -resource "aws_instance" "example" { - provider = aws.west - # ... -} - -module "aws_vpc" { - source = "./aws_vpc" - providers = { - aws = aws.west - } -} -``` - - - -- Any provider block that does not define the `alias` parameter is the default provider configuration. -- Always include a default provider configuration and define all of your providers in the same file. -- If you define multiple instances of a provider, define the default first. -- For non-default providers, define the `alias` as the first parameter of the `provider` block. - -## Dynamic resource count - -The `for_each` and `count` meta-arguments let you create multiple resources from a single `resource` block depending on run-time conditions. You can use these meta-arguments to make your code flexible and reduce duplicate resource blocks. If the resources are almost identical, use `count`. If some of the arguments need distinct values that you cannot derive from an integer, use `for_each`. - -The `for_each` meta-argument accepts a `map` or `set` value, and Terraform will create an instance of that resource for each element in the value you provide. In the following example, Terraform creates an `aws_instance` for each of the strings defined in the `web_instances` variable: "ui", "api", "db" and "metrics". The example uses `each.key` to give each instance a unique name. The `web_private_ips` output uses a [for expression](https://developer.hashicorp.com/terraform/language/expressions/for) to create a map of instance names and their private IP addresses, while the `web_ui_public_ip` output addresses the instance with the key "ui" directly. - - - -```hcl -variable "web_instances" { - type = list(string) - description = "A list of instances for the web application" - default = [ - "ui", - "api", - "db", - "metrics" - ] -} -resource "aws_instance" "web" { - for_each = toset(var.web_instances) - ami = data.aws_ami.webapp.id - instance_type = "t3.micro" - tags = { - Name = "web_${each.key}" - } -} -output "web_private_ips" { - description = "Private IPs of the web instances" - value = { - for k, v in aws_instance.web : k => v.private_ip - } -} -output "web_ui_public_ip" { - description = "Public IP of the web UI instance" - value = aws_instance.web["ui"].public_ip -} -``` - - - -The above example will create the following output: - - - -```hcl -web_private_ips = { - "api" = "172.31.25.29" - "db" = "172.31.18.33" - "metrics" = "172.31.26.112" - "ui" = "172.31.20.142" -} -web_ui_public_ip = "18.216.208.182" -``` - - - -Refer to the [for_each meta-argument documentation](/terraform/language/meta-arguments/for_each) for more examples. - -The `count` meta-argument lets you create multiple instances of a resource from a single resource block. Refer to the [count meta-argument documentation](/terraform/language/meta-arguments/count) for examples. - -A common practice to conditionally create resources is to use the `count` meta-argument with a [conditional expression](/terraform/language/expressions/conditionals). In the following example, Terraform will only create the `aws_instance` if `var.enable_metrics` is `true`. - - - -```hcl -variable "enable_metrics" { - description = "True if the metrics server should be deployed" - type = bool - default = true -} - -resource "aws_instance" "web" { - count = var.enable_metrics ? 1 : 0 - - ami = data.aws_ami.webapp.id - instance_type = "t3.micro" - ##... -} -``` - - - -Meta-arguments simplify your code but add complexity, so use them in moderation. If the effect of the meta-argument is not immediately obvious, use a comment for clarification. - -To learn more about these meta-arguments, refer to the [`for_each`](/terraform/language/meta-arguments/for_each) and [`count`](/terraform/language/meta-arguments/count) documentation. - -## .gitignore - -Define a `.gitignore` file for your repository to exclude files that you should not publish to version control, such as your state file. - -Do not commit: - -- Your `terraform.tfstate` state file, including `terraform.tfstate.*` backup state files. -- Your `.terraform.tfstate.lock.info` file. Terraform creates and deletes this file automatically when you run a `terraform apply` command and contains info about your [state lock](/terraform/language/state/locking) -- Your `.terraform` directory, where Terraform downloads providers and child modules. -[Saved plan files](/terraform/cli/commands/plan#out-filename) that you create when you include the `-out` flag when you run `terraform plan`. -- Any `.tfvars` files that contain sensitive information. - -Always commit: - -- All Terraform code files -- Your `.terraform.lock.hcl` [dependency lock file](/terraform/language/files/dependency-lock) -- A `.gitignore` file that excludes the files listed below -- A `README.md` to describe the code, input variables, and outputs - -For an example, refer to [GitHub's Terraform .gitignore file](https://github.com/github/gitignore/blob/main/Terraform.gitignore). - -## Workflow style - -This section reviews standards that enable predictable and secure Terraform workflows, such as: - -- Pin your Terraform, provider, and module versions. -- Name your module repositories using this three-part name `terraform--` when using the HCP Terraform registry. -- Store local modules at `./modules/`. -- Use the [`tfe_outputs`](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) data source or provider-specific data sources to share state between two state files. -- Protect credentials by using [dynamic provider credentials](/terraform/tutorials/cloud/dynamic-credentials) or a secrets manager such as HashiCorp Vault. -- Write [tests](/terraform/language/tests) for your modules. -- Use [policy enforcement](/terraform/cloud-docs/policy-enforcement) on HCP Terraform to set guardrails for infrastructure operations. - -## Version pinning - -To prevent provider and module upgrades from introducing unintentional changes to your infrastructure, use version pinning. - -Specify provider versions using the [required_providers block](/terraform/language/providers/requirements#requiring-providers). Terraform [version constraints](/terraform/language/providers/requirements#version-constraints) support a range of accepted versions. - -Pin modules to a specific major and minor version as shown in the example below to ensure stability. You can use looser restrictions if you are certain that the module does not introduce breaking changes outside of major version updates. - -We also recommend that you set a minimum required version of the Terraform binary using the `required_version` in your `terraform` block. This requires all operators to use a Terraform version that has all of your configuration's required features. - - - -```hcl -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "5.34.0" - } - } - - required_version = ">= 1.7" -} -``` - - - -The above example pins the version of the `hashicorp/aws` provider to version `5.34.0`, and requires that operators use Terraform `1.7` or newer. - -For modules sourced from a registry, use the `version` parameter in the `module` block to pin the version. For local modules, Terraform ignores the `version` parameter. - - - -```hcl -module "vault_starter" { - source = "hashicorp/vault-starter/aws" - version = "1.0.0" - ##... -} -``` - - - -## Module repository names - -The Terraform registry requires that repositories match a naming convention for all modules that you publish to the registry. Module repositories must use this three-part name `terraform--`, where `` reflects the type of infrastructure the module manages and `` is the main provider the module uses. The `` segment can contain additional hyphens, for example, `terraform-google-vault` or `terraform-aws-ec2-instance`. - -## Module structure - -Terraform modules define self-contained, reusable pieces of infrastructure-as-code. - -Use modules to group together logically related resources that you need to provision together. For example: - -- A networking module that defines a VPC, along with its subnets, gateway, and security groups. -- An application module defining all resources required for each deployment. This stack could include web servers, databases, storage, and supported networking. - -Review the [module creation recommended pattern documentation](/terraform/tutorials/modules/pattern-module-creation) and [standard module structure](/terraform/language/modules/develop/structure) for guidance on how to structure your modules. - -## Local modules - -Local modules are sourced from local disk rather than a remote module registry. We recommend publishing your modules to a module registry, such as the [HCP Terraform private registry](/terraform/cloud-docs/registry), to easily version, share, and reuse modules across your organization. If you cannot use a module registry, using local modules can simplify maintaining and updating your code. - -We recommend that you define child modules in the `./modules/` directory. - -## Repository structure - -How you structure your modules and Terraform configuration in version control significantly impacts versioning and operations. We recommend that you store your actual infrastructure configuration separately from your module code. - -Store each module in an individual repository. This lets you independently version each module and makes it easier to publish your modules in the private Terraform registry. - -Organize your infrastructure configuration in repositories that group together logically-related resources. For example, a single repository for a web application that requires compute, networking, and database resources . By separating your resources into groups, you limit the number of resources that may be impacted by failures for any operation. - -Another approach is to group all modules and infrastructure configuration into a single monolithic repository, or monorepo. For example, a monorepo may define a collection of local modules for each component of the infrastructure stack, and deploy them in the root module. - - - -``` -. -├── modules -│ ├── function -│ │ ├── main.tf # contains aws_iam_role, aws_lambda_function -│ │ ├── outputs.tf -│ │ └── variables.tf -│ ├── queue -│ │ ├── main.tf # contains aws_sqs_queue -│ │ ├── outputs.tf -│ │ └── variables.tf -│ └── vpc -│ ├── main.tf # contains aws_vpc, aws_subnet -│ ├── outputs.tf -│ └── variables.tf -├── main.tf -├── outputs.tf -└── variables.tf -``` - - - -The advantage of monolithic repositories is having a single source of truth that tracks every infrastructure change. However, monolithic repositories can complicate your CI/CD automation: since any code change triggers a deployment that operates on your entire repository, your workflow must target only the modified directories. You also lose the granular access control, since anyone with repository access can modify any file in it. - -If your organization requires a monolithic approach, HCP Terraform and Terraform Enterprise let you scope a workspace to a specific directory in a repository, simplifying your workflows. - -## Branching strategy - -To collaborate on your Terraform code, we recommend using the [GitHub flow](https://docs.github.com/en/get-started/quickstart/github-flow). This approach uses short-lived branches to help your team quickly review, test, and merge changes to your code. To make changes to your code, you would: - -1. Create a new branch from your main branch -1. Write, commit, and push your changes to the new branch -1. Create a pull request -1. Review the changes with your team -1. Merge the pull request -1. Delete the branch - -HCP Terraform and Terraform Enterprise can run [speculative plans for pull requests](/terraform/cloud-docs/run/ui#speculative-plans-on-pull-requests). These speculative plans run automatically when you create or update a pull request, and you can use them to see the effect that your changes will have on your infrastructure before you merge them to your main branch. When you merge your pull request, HCP Terraform will start a new run to apply these changes. - -## Multiple environments - -We recommend that your repository's `main` branch be the source of truth for all environments. For HCP Terraform and Terraform Enterprise users, we recommend that you use separate workspaces for each environment. For larger codebases, we recommend that you split your resources across multiple workspaces to prevent large state files and limit unintended consequences from changes. For example, you could structure your code as follows: - - - -``` -. -├── compute -│ ├── main.tf -│ ├── outputs.tf -│ └── variables.tf -├── database -│ ├── main.tf -│ ├── outputs.tf -│ └── variables.tf -└── networking - ├── main.tf - ├── outputs.tf - └── variables.tf -``` - - - -In this scenario, you would create three workspaces per environment. For example, your production environment would have a `prod-compute`, `prod-database`, and `prod-networking` workspace. Read more about [Terraform workspace and project best practices](/well-architected-framework/operational-excellence/operational-excellence-workspaces-projects). - -If you do not use HCP Terraform or Terraform Enterprise, we recommend that you use modules to encapsulate your configuration, and use a directory for each environment so that each one has a separate state file. The configuration in each of these directories would call the local modules, each with parameters specific to their environment. This also lets you maintain separate variable and backend configurations for each environment. - - - -``` -├── modules -│ ├── compute -│ │ └── main.tf -│ ├── database -│ │ └── main.tf -│ └── network -│ └── main.tf -├── dev -│ ├── backend.tf -│ ├── main.tf -│ └── variables.tf -├── prod -│ ├── backend.tf -│ ├── main.tf -│ └── variables.tf -└── staging - ├── backend.tf - ├── main.tf - └── variables.tf -``` - - - -## State sharing - -Since your state contains sensitive information, avoid sharing full state files when possible. - -If you use HCP Terraform or Terraform Enterprise and need to reference resources across workspaces, use the [`tfe_outputs`](https://registry.terraform.io/providers/hashicorp/tfe/latest/docs/data-sources/outputs) data source. - -If you do not use HCP Terraform or Terraform Enterprise but still need to reference data about other infrastructure resources, use data sources to query the provider. For example, you can use the [`aws_instance` data source](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/instance) to look up an AWS EC2 instance by its ID or tags. - - -## Secrets management - -If you do not configure remote state storage, the Terraform CLI stores the entire state in plaintext on the local disk. State can include sensitive data, such as passwords and private keys. HCP Terraform and Terraform Enterprise provide state encryption through HashiCorp Vault. - -If you use HCP Terraform or Terraform Enterprise, we recommend the following: - -- When using Terraform Enterprise, define and enforce a Sentinel policy to prevent use of the `local_exec` provisioner or external data sources. -- When using HCP Terraform or Terraform Enterprise, use [dynamic provider credentials](/terraform/tutorials/cloud/dynamic-credentials) to avoid using long-lived static credentials. - - -If you use Terraform Community Edition, we recommend the following: - -- Configure provider credentials using provider-specific environment variables. -- Access secrets from a secrets management system such as HashiCorp Vault with the [Terraform Vault provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs). Be aware that Terraform will still write these values in plaintext to your state file. - -If you use a custom CI/CD pipeline, review your CI/CD tool's best practices for managing sensitive values. Most tools let you access sensitive values as environment variables. For more information, refer to your CI/CD documentation. - -- [Using secrets in GitHub Actions](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions) -- [Gitlab pipeline security](https://docs.gitlab.com/ee/ci/pipelines/pipeline_security.html) -- [Integrate Vault into your CI/CD pipeline](/well-architected-framework/security/security-cicd-vault) - -## Integration and unit testing - -Terraform tests let you validate your modules and catch breaking changes. We recommend that you write tests for your Terraform modules and run them just as you run your tests for your application code, such as pre-merge check in your pull requests or as a prerequisite step in your automated CI/CD pipeline. - -Tests differ from validation methods such as variable validation, preconditions, postconditions, and check blocks. These features focus on verifying the infrastructure deployed by your code, while tests validate the behavior and logic of your code itself. For more information, refer to the [Terraform test documentation](/terraform/language/tests) and the [Write Terraform tests tutorial](/terraform/tutorials/configuration-language/test). - -## Policy - -Policies are rules that HCP Terraform enforces on Terraform runs. You can use policies to validate that the Terraform plan complies with your organization's best practices. For example, you can write policies that: - -- Limit the size of a web instance -- Check for required resource tags -- Block deployments on Fridays -- Enforce security configuration and cost management - -We recommend that you store policies in a separate VCS repository from your Terraform code. - -For more information, refer to the [policy enforcement documentation](/terraform/cloud-docs/policy-enforcement), as well as the [enforce policy with Sentinel](/terraform/tutorials/policy) and [detect infrastructure drift and enforce OPA policies](/terraform/tutorials/cloud/drift-and-opa) tutorials. - -## Next steps - -This article introduces some considerations to keep in mind as you standardize your organization's Terraform style guidelines. Enforcing a standard way of writing and organizing your Terraform code across your organization ensures that it is readable, maintainable, and shareable. - -To learn more Terraform adoption best practices, refer to [Phases of Terraform adoption](/terraform/intro/phases). diff --git a/website/docs/language/syntax/configuration.mdx b/website/docs/language/syntax/configuration.mdx deleted file mode 100644 index c9064ed77e..0000000000 --- a/website/docs/language/syntax/configuration.mdx +++ /dev/null @@ -1,135 +0,0 @@ ---- -page_title: Syntax - Configuration Language -description: >- - Key constructs of the native Terraform language syntax, including identifiers, - arguments, blocks, and comments. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Configuration Syntax - -Other pages in this section have described various configuration constructs -that can appear in the Terraform language. This page describes the lower-level -syntax of the language in more detail, revealing the building blocks that -those constructs are built from. - -This page describes the _native syntax_ of the Terraform language, which is -a rich language designed to be relatively easy for humans to read and write. -The constructs in the Terraform language can also be expressed in -[JSON syntax](/terraform/language/syntax/json), which is harder for humans -to read and edit but easier to generate and parse programmatically. - -This low-level syntax of the Terraform language is defined in terms of a -syntax called _HCL_, which is also used by configuration languages in -other applications, and in particular other HashiCorp products. -It is not necessary to know all of the details of HCL syntax in -order to use Terraform, and so this page summarizes the most important -details. If you are interested, you can find a full definition of HCL -syntax in -[the HCL native syntax specification](https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md). - -## Arguments and Blocks - -The Terraform language syntax is built around two key syntax constructs: -arguments and blocks. - -### Arguments - -An _argument_ assigns a value to a particular name: - -```hcl -image_id = "abc123" -``` - -The identifier before the equals sign is the _argument name_, and the expression -after the equals sign is the argument's value. - -The context where the argument appears determines what value types are valid -(for example, each resource type has a schema that defines the types of its -arguments), but many arguments accept arbitrary -[expressions](/terraform/language/expressions), which allow the value to -either be specified literally or generated from other values programmatically. - --> **Note:** Terraform's configuration language is based on a more general -language called HCL, and HCL's documentation usually uses the word "attribute" -instead of "argument." These words are similar enough to be interchangeable in -this context, and experienced Terraform users might use either term in casual -conversation. But because Terraform also interacts with several _other_ things -called "attributes" (in particular, Terraform resources have attributes like -`id` that can be referenced from expressions but can't be assigned values in -configuration), we've chosen to use "argument" in the Terraform documentation -when referring to this syntax construct. - -### Blocks - -A _block_ is a container for other content: - -```hcl -resource "aws_instance" "example" { - ami = "abc123" - - network_interface { - # ... - } -} -``` - -A block has a _type_ (`resource` in this example). Each block type defines -how many _labels_ must follow the type keyword. The `resource` block type -expects two labels, which are `aws_instance` and `example` in the example above. -The `aws_instance` label is specific to the AWS provider. It specifies the `resource` type that Terraform provisions when you apply the configuration. The second label is an arbitrary name that you can add to the particular instance of the resource. You can create multiple instances of the same block type and differentiate them by giving each instance a unique name. In this example, the Terraform configuration author assigned the `example` label to this instance of the `aws_instance` resource. -A particular block type may have any number of required labels, or it may -require none as with the nested `network_interface` block type. - -After the block type keyword and any labels, the block _body_ is delimited -by the `{` and `}` characters. Within the block body, further arguments -and blocks may be nested, creating a hierarchy of blocks and their associated -arguments. - -The Terraform language uses a limited number of _top-level block types,_ which -are blocks that can appear outside of any other block in a configuration file. -Most of Terraform's features (including resources, input variables, output -values, data sources, etc.) are implemented as top-level blocks. - -## Identifiers - -Argument names, block type names, and the names of most Terraform-specific -constructs like resources, input variables, etc. are all _identifiers_. - -Identifiers can contain letters, digits, underscores (`_`), and hyphens (`-`). -The first character of an identifier must not be a digit, to avoid ambiguity -with literal numbers. - -For complete identifier rules, Terraform implements -[the Unicode identifier syntax](http://unicode.org/reports/tr31/), extended to -include the ASCII hyphen character `-`. - -## Comments - -The Terraform language supports three different syntaxes for comments: - -* `#` begins a single-line comment, ending at the end of the line. -* `//` also begins a single-line comment, as an alternative to `#`. -* `/*` and `*/` are start and end delimiters for a comment that might span - over multiple lines. - -The `#` single-line comment style is the default comment style and should be -used in most cases. Automatic configuration formatting tools may automatically -transform `//` comments into `#` comments, since the double-slash style is -not idiomatic. - -## Character Encoding and Line Endings - -Terraform configuration files must always be UTF-8 encoded. While the -delimiters of the language are all ASCII characters, Terraform accepts -non-ASCII characters in identifiers, comments, and string values. - -Terraform accepts configuration files with either Unix-style line endings -(LF only) or Windows-style line endings (CR then LF), but the idiomatic style -is to use the Unix convention, and so automatic configuration formatting tools -may automatically transform CRLF endings to LF. diff --git a/website/docs/language/syntax/index.mdx b/website/docs/language/syntax/index.mdx deleted file mode 100644 index 512006ab10..0000000000 --- a/website/docs/language/syntax/index.mdx +++ /dev/null @@ -1,29 +0,0 @@ ---- -page_title: Syntax Overview - Configuration Language -description: >- - Terraform language syntax for both the native and JSON variants. Also learn - formatting conventions that you can enforce with terraform fmt. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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. -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ - - -# Syntax - -The majority of the Terraform language documentation focuses on the practical -uses of the language and the specific constructs it uses. The pages in this -section offer a more abstract view of the Terraform language. - -- [Configuration Syntax](/terraform/language/syntax/configuration) describes the native - grammar of the Terraform language. -- [JSON Configuration Syntax](/terraform/language/syntax/json) documents - how to represent Terraform language constructs in the pure JSON variant of the - Terraform language. Terraform's JSON syntax is unfriendly to humans, but can - be very useful when generating infrastructure as code with other systems that - don't have a readily available HCL library. -- [Style Conventions](/terraform/language/style#code-formatting) documents some commonly - accepted formatting guidelines for Terraform code. These conventions can be - enforced automatically with [`terraform fmt`](/terraform/cli/commands/fmt). diff --git a/website/docs/language/syntax/json.mdx b/website/docs/language/syntax/json.mdx deleted file mode 100644 index 9e0a3fbd22..0000000000 --- a/website/docs/language/syntax/json.mdx +++ /dev/null @@ -1,475 +0,0 @@ ---- -page_title: JSON Configuration Syntax - Configuration Language -description: >- - Learn about the JSON-compatible language syntax, including file structure, - expression mapping, block mapping, and block-type-specific exceptions. ---- - -⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️ -> [!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 Configuration Syntax - -Most Terraform configurations are written in -[the native Terraform language syntax](/terraform/language/syntax/configuration), which is designed to be -relatively easy for humans to read and update. - -Terraform also supports an alternative syntax that is JSON-compatible. This -syntax is useful when generating portions of a configuration programmatically, -since existing JSON libraries can be used to prepare the generated -configuration files. - -The JSON syntax is defined in terms of the native syntax. Everything that can -be expressed in native syntax can also be expressed in JSON syntax, but some -constructs are more complex to represent in JSON due to limitations of the -JSON grammar. - -Terraform expects native syntax for files named with a `.tf` suffix, and -JSON syntax for files named with a `.tf.json` suffix. - -The low-level JSON syntax, just as with the native syntax, is defined in terms -of a specification called _HCL_. It is not necessary to know all of the details -of HCL syntax or its JSON mapping in order to use Terraform, and so this page -summarizes the most important differences between native and JSON syntax. -If you are interested, you can find a full definition of HCL's JSON syntax -in [its specification](https://github.com/hashicorp/hcl/blob/main/json/spec.md). - -## JSON File Structure - -At the root of any JSON-based Terraform configuration is a JSON object. The -properties of this object correspond to the top-level block types of the -Terraform language. For example: - -```json -{ - "variable": { - "example": { - "default": "hello" - } - } -} -``` - -Each top-level object property must match the name of one of the expected -top-level block types. Block types that expect labels, such as `variable` -shown above, are represented by one nested object value for each level -of label. `resource` blocks expect two labels, so two levels of nesting -are required: - -```json -{ - "resource": { - "aws_instance": { - "example": { - "instance_type": "t2.micro", - "ami": "ami-abc123" - } - } - } -} -``` - -After any nested objects representing the labels, finally one more nested -object represents the body of the block itself. In the above examples, the -`default` argument for `variable "example"` and the `instance_type` and -`ami` arguments for `resource "aws_instance" "example"` are specified. - -Taken together, the above two configuration files are equivalent to the -following blocks in the native syntax: - -```hcl -variable "example" { - default = "hello" -} - -resource "aws_instance" "example" { - instance_type = "t2.micro" - ami = "ami-abc123" -} -``` - -Within each top-level block type the rules for mapping to JSON are slightly -different (see the [block-type-specific exceptions](#block-type-specific-exceptions) below), but the following general rules apply in most cases: - -* The JSON object representing the block body contains properties that - correspond either to argument names or to nested block type names. - -* Where a property corresponds to an argument that accepts - [arbitrary expressions](/terraform/language/expressions) in the native syntax, the - property value is mapped to an expression as described under - [_Expression Mapping_](#expression-mapping) below. For arguments that - do _not_ accept arbitrary expressions, the interpretation of the property - value depends on the argument, as described in the - [block-type-specific exceptions](#block-type-specific-exceptions) - given later in this page. - -* Where a property name corresponds to an expected nested block type name, - the value is interpreted as described under - [_Nested Block Mapping_](#nested-block-mapping) below, unless otherwise - stated in [the block-type-specific exceptions](#block-type-specific-exceptions) - given later in this page. - -## Expression Mapping - -Since JSON grammar is not able to represent all of the Terraform language -[expression syntax](/terraform/language/expressions), JSON values interpreted as expressions -are mapped as follows: - -| JSON | Terraform Language Interpretation | -| ------- | ------------------------------------------------------------------------------------------------------------- | -| Boolean | A literal `bool` value. | -| Number | A literal `number` value. | -| String | Parsed as a [string template][] and then evaluated as described below. | -| Object | Each property value is mapped per this table, producing an `object(...)` value with suitable attribute types. | -| Array | Each element is mapped per this table, producing a `tuple(...)` value with suitable element types. | -| Null | A literal `null`. | - -[string template]: /terraform/language/expressions/strings#string-templates - -When a JSON string is encountered in a location where arbitrary expressions are -expected, its value is first parsed as a [string template][] -and then it is evaluated to produce the final result. - -If the given template consists _only_ of a single interpolation sequence, -the result of its expression is taken directly, without first converting it -to a string. This allows non-string expressions to be used within the -JSON syntax: - -```json -{ - "output": { - "example": { - "value": "${aws_instance.example}" - } - } -} -``` - -The `output "example"` declared above has the object value representing the -given `aws_instance` resource block as its value, rather than a string value. -This special behavior does not apply if any literal or control sequences appear -in the template; in these other situations, a string value is always produced. - -## Nested Block Mapping - -When a JSON object property is named after a nested block type, the value -of this property represents one or more blocks of that type. The value of -the property must be either a JSON object or a JSON array. - -The simplest situation is representing only a single block of the given type -when that type expects no labels, as with the `lifecycle` nested block used -within `resource` blocks: - -```json -{ - "resource": { - "aws_instance": { - "example": { - "lifecycle": { - "create_before_destroy": true - } - } - } - } -} -``` - -The above is equivalent to the following native syntax configuration: - -```hcl -resource "aws_instance" "example" { - lifecycle { - create_before_destroy = true - } -} -``` - -When the nested block type requires one or more labels, or when multiple -blocks of the same type can be given, the mapping gets a little more -complicated. For example, the `provisioner` nested block type used -within `resource` blocks expects a label giving the provisioner to use, -and the ordering of provisioner blocks is significant to decide the order -of operations. - -The following native syntax example shows a `resource` block with a number -of provisioners of different types: - -```hcl -resource "aws_instance" "example" { - # (resource configuration omitted for brevity) - - provisioner "local-exec" { - command = "echo 'Hello World' >example.txt" - } - provisioner "file" { - source = "example.txt" - destination = "/tmp/example.txt" - } - provisioner "remote-exec" { - inline = [ - "sudo install-something -f /tmp/example.txt", - ] - } -} -``` - -In order to preserve the order of these blocks, you must use a JSON array -as the direct value of the property representing this block type, as in -this JSON equivalent of the above: - -```json -{ - "resource": { - "aws_instance": { - "example": { - "provisioner": [ - { - "local-exec": { - "command": "echo 'Hello World' >example.txt" - } - }, - { - "file": { - "source": "example.txt", - "destination": "/tmp/example.txt" - } - }, - { - "remote-exec": { - "inline": ["sudo install-something -f /tmp/example.txt"] - } - } - ] - } - } - } -} -``` - -Each element of the `provisioner` array is an object with a single property -whose name represents the label for each `provisioner` block. For block types -that expect multiple labels, this pattern of alternating array and object -nesting can be used for each additional level. - -If a nested block type requires labels but the order does _not_ matter, you -may omit the array and provide just a single object whose property names -correspond to unique block labels. This is allowed as a shorthand for the above -for simple cases, but the alternating array and object approach is the most -general. We recommend using the most general form if systematically converting -from native syntax to JSON, to ensure that the meaning of the configuration is -preserved exactly. - -### Comment Properties - -Although we do not recommend hand-editing of JSON syntax configuration files -\-- this format is primarily intended for programmatic generation and consumption -- -a limited form of _comments_ are allowed inside JSON objects that represent -block bodies using a special property name: - -```json -{ - "resource": { - "aws_instance": { - "example": { - "//": "This instance runs the scheduled tasks for backup", - - "instance_type": "t2.micro", - "ami": "ami-abc123" - } - } - } -} -``` - -In any object that represents a block body, properties named `"//"` are -ignored by Terraform entirely. This exception does _not_ apply to objects -that are being [interpreted as expressions](#expression-mapping), where this -would be interpreted as an object type attribute named `"//"`. - -This special property name can also be used at the root of a JSON-based -configuration file. This can be useful to note which program created the file. - -```json -{ - "//": "This file is generated by generate-outputs.py. DO NOT HAND-EDIT!", - - "output": { - "example": { - "value": "${aws_instance.example}" - } - } -} -``` - -## Block-type-specific Exceptions - -[inpage-block]: #block-type-specific-exceptions - -Certain arguments within specific block types are processed in a special way -by Terraform, and so their mapping to the JSON syntax does not follow the -general rules described above. The following sub-sections describe the special -mapping rules that apply to each top-level block type. - -### `resource` and `data` blocks - -Some meta-arguments for the `resource` and `data` block types take direct -references to objects, or literal keywords. When represented in JSON, the -reference or keyword is given as a JSON string with no additional surrounding -spaces or symbols. - -For example, the `provider` meta-argument takes a `.` reference -to a provider configuration, which appears unquoted in the native syntax but -must be presented as a string in the JSON syntax: - -```json -{ - "resource": { - "aws_instance": { - "example": { - "provider": "aws.foo" - } - } - } -} -``` - -This special processing applies to the following meta-arguments: - -* `provider`: a single string, as shown above -* `depends_on`: an array of strings containing references to named entities, - like `["aws_instance.example"]`. -* `ignore_changes` within the `lifecycle` block: if set to `all`, a single - string `"all"` must be given. Otherwise, an array of JSON strings containing - property references must be used, like `["ami"]`. - -Special processing also applies to the `type` argument of any `connection` -blocks, whether directly inside the `resource` block or nested inside -`provisioner` blocks: the given string is interpreted literally, and not -parsed and evaluated as a string template. - -### `variable` blocks - -All arguments inside `variable` blocks have non-standard mappings to JSON: - -* `type`: a string containing a type expression, like `"string"` or `"list(string)"`. -* `default`: a literal JSON value that can be converted to the given type. - Strings within this value are taken literally and _not_ interpreted as - string templates. -* `description`: a literal JSON string, _not_ interpreted as a template. - -```json -{ - "variable": { - "example": { - "type": "string", - "default": "hello" - } - } -} -``` - -### `output` blocks - -The `description` and `sensitive` arguments are interpreted as literal JSON -values. The `description` string is not interpreted as a string template. - -The `value` argument is [interpreted as an expression](#expression-mapping). - -```json -{ - "output": { - "example": { - "value": "${aws_instance.example}" - } - } -} -``` - -### `locals` blocks - -The value of the JSON object property representing the locals block type -must be a JSON object whose property names are the local value names to -declare: - -```json -{ - "locals": { - "greeting": "Hello, ${var.name}" - } -} -``` - -The value of each of these nested properties is -[interpreted as an expression](#expression-mapping). - -### `module` blocks - -The `source` and `version` meta-arguments must be given as literal strings. The -values are not interpreted as string templates. - -The `providers` meta-argument must be given as a JSON object whose properties -are the compact provider addresses to expose into the child module and whose -values are the provider addresses to use from the current module, both -given as literal strings: - -```json -{ - "module": { - "example": { - "source": "hashicorp/consul/azurerm", - "version": "= 1.0.0", - "providers": { - "aws": "aws.usw1" - } - } - } -} -``` - -### `provider` blocks - -The `alias` and `version` meta-arguments must be given as literal strings. The -values are not interpreted as string templates. - -```json -{ - "provider": { - "aws": [ - { - "region": "us-east-1" - }, - { - "alias": "usw1", - "region": "us-west-1" - } - ] - } -} -``` - -### `terraform` blocks - -Since no settings within `terraform` blocks accept named object references or -function calls, all setting values are taken literally. String values are not -interpreted as string templates. - -Since only one `backend` block is allowed per `terraform` block, the compact -block mapping can be used to represent it, with a nested object containing -a single property whose name represents the backend type. - -```json -{ - "terraform": { - "required_version": ">= 0.12.0", - "backend": { - "s3": { - "region": "us-west-2", - "bucket": "acme-terraform-states" - } - } - } -} -``` diff --git a/website/docs/language/terraform.mdx b/website/docs/language/terraform.mdx deleted file mode 100644 index 902bbf62d9..0000000000 --- a/website/docs/language/terraform.mdx +++ /dev/null @@ -1,436 +0,0 @@ ---- -page_title: Terraform block configuration reference -description: >- - The `terraform` block allows you to configure Terraform behavior, including the Terraform version, backend, integration with HCP Terraform, and 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` block reference - -This topic provides reference information about the `terraform` block. The `terraform` block allows you to configure Terraform behavior, including the Terraform version, backend, integration with HCP Terraform, and required providers. - -## Configuration model - -The `terraform` block supports the following arguments: - -- [`terraform`](#terraform) - - [`required_version`](#required_version):   string - - [`required_providers`](#required_providers):   block - - [``](#provider):   block - - [`version`](#provider):   string - - [`source`](#provider):   string - - [`provider_meta "