2014-07-24 23:53:55 +02:00
---
2021-11-23 00:57:25 +01:00
layout: "docs"
page_title: "Command: plan"
sidebar_current: "docs-commands-plan"
description: "The terraform plan command creates an execution plan with a preview of the changes that Terraform will make to your infrastructure."
2014-07-24 23:53:55 +02:00
---
# Command: plan
2021-06-08 15:58:55 +02:00
The `terraform plan` command creates an execution plan, which lets you preview
the changes that Terraform plans to make to your infrastructure. By default,
when Terraform creates a plan it:
2021-04-07 21:25:59 +02:00
2021-06-08 15:58:55 +02:00
* Reads the current state of any already-existing remote objects to make sure
2021-04-07 21:25:59 +02:00
that the Terraform state is up-to-date.
2021-06-08 15:58:55 +02:00
* Compares the current configuration to the prior state and noting any
2021-04-07 21:25:59 +02:00
differences.
2021-06-08 15:58:55 +02:00
* Proposes a set of change actions that should, if applied, make the remote
2021-04-07 21:25:59 +02:00
objects match the configuration.
2021-06-08 15:58:55 +02:00
> **Hands-on:** Try the [Terraform: Get Started](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) collection on HashiCorp Learn.
2021-04-07 21:25:59 +02:00
The plan command alone will not actually carry out the proposed changes, and
so 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
2021-11-23 00:57:25 +01:00
[`terraform apply` ](./apply.html ) directly. By default, the "apply" command
2021-04-07 21:25:59 +02:00
automatically generates a new plan and prompts for 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
2021-11-23 00:57:25 +01:00
[`terraform apply` ](./apply.html ) as an extra argument. This two-step workflow
2021-04-07 21:25:59 +02:00
is primarily intended for when
2020-10-02 20:02:59 +02:00
[running Terraform in automation ](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 ).
2014-07-24 23:53:55 +02:00
2021-04-07 21:25:59 +02:00
If you run `terraform plan` without the `-out=FILE` option then it will create
2021-05-18 17:05:42 +02:00
a _speculative plan_ , which is a description of the effect of the plan but
2021-04-07 21:25:59 +02:00
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.
2020-05-27 01:59:06 +02:00
2014-07-24 23:53:55 +02:00
## Usage
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
Usage: `terraform plan [options]`
2014-07-24 23:53:55 +02:00
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
The `plan` subcommand looks in the current working directory for the root module
configuration.
2014-07-24 23:53:55 +02:00
2021-04-07 21:25:59 +02:00
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.
2021-11-23 00:57:25 +01:00
* **[Resource Targeting](#resource-targeting)** is one particular
special planning option that has some important caveats associated
with it.
2021-04-07 21:25:59 +02:00
* **[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 section above described Terraform's default planning behavior, which is
intended for changing the remote system to match with changes you've made to
your configuration.
2021-05-07 00:22:48 +02:00
Terraform has two alternative planning modes, each of which creates a plan with
2021-04-07 21:25:59 +02:00
a different intended outcome:
* **Destroy mode:** creates a plan whose goal is to destroy all remote objects
that currently exist, leaving an empty Terraform state. This can be useful
for situations like transient development environments, where the managed
objects cease to be useful once the development task is complete.
2021-11-23 00:57:25 +01:00
Activate destroy mode using the `-destroy` command line option.
2021-04-07 21:25:59 +02:00
2021-05-07 00:22:48 +02:00
* **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.
2021-11-23 00:57:25 +01:00
Activate refresh-only mode using the `-refresh-only` command line option.
2021-05-07 00:22:48 +02:00
2021-04-07 21:25:59 +02:00
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
2021-11-23 00:57:25 +01:00
earlier versions you must run [`terraform destroy` ](./destroy.html ).
2021-04-07 21:25:59 +02:00
2021-05-26 18:09:39 +02:00
-> **Note:** The `-refresh-only` option is available only in Terraform v0.15.4
and later.
2021-07-06 21:52:16 +02:00
> **Hands-on:** Try the [Use Refresh-Only Mode to Sync Terraform State](https://learn.hashicorp.com/tutorials/terraform/refresh) tutorial on HashiCorp Learn.
2021-04-07 21:25:59 +02:00
## Planning Options
In addition to the planning _modes_ described above, there are also several
additional options that can modify details of the behavior of the planning
step.
When you use `terraform apply` without passing it a saved plan file, it
incorporates the `terraform plan` command functionality and so the planning
options in this section, along with the planning mode selection options in
the previous section, are also available with the same meanings on
`terraform apply` .
* `-refresh=false` - Disables the default behavior of synchronizing the
Terraform state with remote objects before checking for configuration changes.
2021-11-23 00:57:25 +01:00
This option can potentially make the planning operation faster by reducing
the number of remote API requests, but it comes at the expense of having
Terraform not take into account any changes that might've happened outside
of Terraform, and thus the resulting plan may not be complete or correct.
2021-04-07 21:25:59 +02:00
2021-11-23 00:57:25 +01:00
This option is not available in the "refresh only" planning mode, because
it would effectively disable the entirety of the planning operation in that
case.
2021-04-07 21:25:59 +02:00
2021-04-30 23:46:22 +02:00
* `-replace=ADDRESS` - Instructs Terraform to plan to replace the single
resource instance with the given address. If the given instance would
normally have caused only an "update" action, or no action at all, then
Terraform will choose a "replace" action instead.
2021-11-23 00:57:25 +01:00
You can use this option if you have learned that a particular remote object
has become degraded in some way. If you are using immutable infrastructure
patterns then you may wish to respond to that by replacing the
malfunctioning object with a new object that has the same configuration.
2021-04-30 23:46:22 +02:00
2021-11-23 00:57:25 +01:00
This option is allowed only in the normal planning mode, so this option
is incompatible with the `-destroy` option.
2021-04-30 23:46:22 +02:00
2021-11-23 00:57:25 +01:00
The `-replace=...` option is available only from Terraform v0.15.2 onwards.
For earlier versions, you can achieve a similar effect (with some caveats)
using [`terraform taint` ](./taint.html ).
2021-04-30 23:46:22 +02:00
2021-04-07 21:25:59 +02:00
* `-target=ADDRESS` - Instructs Terraform to focus its planning efforts only
on resource instances which match the given address and on any objects that
those instances depend on.
2021-11-23 00:57:25 +01:00
This command is for exceptional use only. See
[Resource Targeting ](#resource-targeting )
below for more information.
2021-04-07 21:25:59 +02:00
2021-06-22 16:20:31 +02:00
* `-var 'NAME=VALUE'` - Sets a value for a single
2021-11-23 00:57:25 +01:00
[input variable ](/docs/language/values/variables.html ) declared in the
2021-04-07 21:25:59 +02:00
root module of the configuration. Use this option multiple times to set
2021-06-22 01:26:21 +02:00
more than one variable. For more information see
[Input Variables on the Command Line ](#input-variables-on-the-command-line ),
below.
2021-04-07 21:25:59 +02:00
* `-var-file=FILENAME` - Sets values for potentially many
2021-11-23 00:57:25 +01:00
[input variables ](/docs/language/values/variables.html ) declared in the
2021-04-07 21:25:59 +02:00
root module of the configuration, using definitions from a
2021-11-23 00:57:25 +01:00
["tfvars" file ](/docs/language/values/variables.html#variable-definitions-tfvars-files ).
2021-04-07 21:25:59 +02:00
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. For more information,
see
2021-11-23 00:57:25 +01:00
[Assigning Values to Root Module Variables ](/docs/language/values/variables.html#assigning-values-to-root-module-variables ).
2021-04-07 21:25:59 +02:00
2021-06-22 01:26:21 +02:00
### Input Variables on the Command Line
You can use the `-var` command line option to specify values for
2021-11-23 00:57:25 +01:00
[input variables ](/docs/language/values/variables.html ) declared in your
2021-06-22 01:26:21 +02:00
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 write your actual values
in a separate file so that Terraform can parse them directly, rather than
interpreting the result of your shell's parsing.
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
2021-11-23 00:57:25 +01:00
on the variable's [type constraint ](/docs/language/expressions/type-constraints.html ).
2021-06-22 01:26:21 +02:00
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
2021-11-23 00:57:25 +01:00
[Assigning Values to Root Module Variables ](/docs/language/values/variables.html#assigning-values-to-root-module-variables ).
2021-06-22 01:26:21 +02:00
2021-04-07 21:25:59 +02:00
### Resource Targeting
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
2021-03-22 17:55:41 +01:00
> **Hands-on:** Try the [Target resources](https://learn.hashicorp.com/tutorials/terraform/resource-targeting?in=terraform/state&utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS) tutorial on HashiCorp Learn.
2021-04-07 21:25:59 +02:00
You can use the `-target` option to focus Terraform's attention on only a
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
subset of resources.
2021-11-23 00:57:25 +01:00
You can use [resource address syntax ](/docs/cli/state/resource-addressing.html )
2021-04-07 21:25:59 +02:00
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]` .
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
2021-04-07 21:25:59 +02:00
* 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.
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
2021-04-07 21:25:59 +02:00
* 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.
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
This targeting capability is provided for exceptional circumstances, such
as recovering from mistakes or working around Terraform limitations. It
2021-11-23 00:57:25 +01:00
is *not recommended* to use `-target` for routine operations, since this can
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
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.
2021-11-23 00:57:25 +01:00
[Data sources ](/docs/language/data-sources/index.html ) can be used to access
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
information about resources created in other configurations, allowing
2019-03-21 20:20:29 +01:00
a complex system architecture to be broken down into more manageable parts
core: -target option to also select resources in descendant modules
Previously the behavior for -target when given a module address was to
target only resources directly within that module, ignoring any resources
defined in child modules.
This behavior turned out to be counter-intuitive, since users expected
the -target address to be interpreted hierarchically.
We'll now use the new "Contains" function for addresses, which provides
a hierarchical "containment" concept that is more consistent with user
expectations. In particular, it allows module.foo to match
module.foo.module.bar.aws_instance.baz, where before that would not have
been true.
Since Contains isn't commutative (unlike Equals) this requires some
special handling for targeting specific indices. When given an argument
like -target=aws_instance.foo[0], the initial graph construction (for
both plan and refresh) is for the resource nodes from configuration, which
have not yet been expanded to separate indexed instances. Thus we need
to do the first pass of TargetsTransformer in mode where indices are
ignored, with the work then completed by the DynamicExpand method which
re-applies the TargetsTransformer in index-sensitive mode.
This is a breaking change for anyone depending on the previous behavior
of -target, since it will now select more resources than before. There is
no way provided to obtain the previous behavior. Eventually we may support
negative targeting, which could then combine with positive targets to
regain the previous behavior as an explicit choice.
2017-06-16 03:15:41 +02:00
that can be updated independently.
2021-04-07 21:25:59 +02:00
## 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.
2014-07-26 06:42:06 +02:00
2021-04-07 21:25:59 +02:00
The available options are:
2014-07-26 06:42:06 +02:00
2021-04-07 21:25:59 +02:00
* `-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.
2014-07-26 06:42:06 +02:00
2021-04-07 21:25:59 +02:00
* `-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)
* `-input=false` - Disables Terraform's default behavior of prompting for
input for root module input variables that have not otherwise been assigned
2021-05-18 17:05:42 +02:00
a value. This option is particularly useful when running Terraform in
2021-04-07 21:25:59 +02:00
non-interactive automation systems.
2021-05-25 20:36:11 +02:00
* `-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.
2021-11-23 00:57:25 +01:00
[machine-readable-ui]: /docs/internals/machine-readable-ui.html
2021-05-25 20:36:11 +02:00
2021-05-12 18:05:03 +02:00
* `-lock=false` - Don't hold a state lock during the operation. This is
2021-11-23 00:57:25 +01:00
dangerous if others might concurrently run commands against the same
workspace.
2021-04-07 21:25:59 +02:00
* `-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.
2021-11-23 00:57:25 +01:00
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.
2021-04-07 21:25:59 +02:00
2021-11-23 00:57:25 +01:00
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.
2021-04-07 21:25:59 +02:00
2021-05-18 17:05:42 +02:00
* `-parallelism=n` - Limit the number of concurrent operations as Terraform
2021-11-23 00:57:25 +01:00
[walks the graph ](/docs/internals/graph.html#walking-the-graph ). Defaults
2021-04-07 21:25:59 +02:00
to 10.
For configurations using
2021-11-23 00:57:25 +01:00
[the `local` backend ](/docs/language/settings/backends/local.html ) only,
2021-04-07 21:25:59 +02:00
`terraform plan` accepts the legacy command line option
2021-11-23 00:57:25 +01:00
[`-state` ](/docs/language/settings/backends/local.html#command-line-arguments ).
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
2021-04-07 21:25:59 +02:00
### Passing a Different Configuration Directory
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
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.
2021-04-07 21:25:59 +02:00
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
2021-11-23 00:57:25 +01:00
[the `-chdir` global option ](./#switching-working-directory-with-chdir )
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
instead, which works across all commands and makes Terraform consistently look
2021-04-30 18:24:02 +02:00
in the given directory for all files it would normally read or write in the
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
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
2021-11-23 00:57:25 +01:00
[the `TF_DATA_DIR` environment variable ](/docs/cli/config/environment-variables.html#tf_data_dir )
main: new global option -chdir
This new option is intended to address the previous inconsistencies where
some older subcommands supported partially changing the target directory
(where Terraform would use the new directory inconsistently) where newer
commands did not support that override at all.
Instead, now Terraform will accept a -chdir command at the start of the
command line (before the subcommand) and will interpret it as a request
to direct all actions that would normally be taken in the current working
directory into the target directory instead. This is similar to options
offered by some other similar tools, such as the -C option in "make".
The new option is only accepted at the start of the command line (before
the subcommand) as a way to reflect that it is a global command (not
specific to a particular subcommand) and that it takes effect _before_
executing the subcommand. This also means it'll be forced to appear before
any other command-specific arguments that take file paths, which hopefully
communicates that those other arguments are interpreted relative to the
overridden path.
As a measure of pragmatism for existing uses, the path.cwd object in
the Terraform language will continue to return the _original_ working
directory (ignoring -chdir), in case that is important in some exceptional
workflows. The path.root object gives the root module directory, which
will always match the overriden working directory unless the user
simultaneously uses one of the legacy directory override arguments, which
is not a pattern we intend to support in the long run.
As a first step down the deprecation path, this commit adjusts the
documentation to de-emphasize the inconsistent old command line arguments,
including specific guidance on what to use instead for the main three
workflow commands, but all of those options remain supported in the same
way as they were before. In a later commit we'll make those arguments
produce a visible deprecation warning in Terraform's output, and then
in an even later commit we'll remove them entirely so that -chdir is the
single supported way to run Terraform from a directory other than the
one containing the root module configuration.
2020-09-02 00:45:12 +02:00
to direct Terraform to write the `.terraform` directory to a location other
than the current working directory.