2014-07-24 23:53:55 +02:00
---
layout: "docs"
page_title: "Command: plan"
sidebar_current: "docs-commands-plan"
2014-10-22 05:21:56 +02:00
description: |-
The `terraform plan` command is used to create an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are necessary to achieve the desired state specified in the configuration files. The plan can be saved using `-out` , and then provided to `terraform apply` to ensure only the pre-planned actions are executed.
2014-07-24 23:53:55 +02:00
---
# Command: plan
The `terraform plan` command is used to create an execution plan. Terraform
performs a refresh, unless explicitly disabled, and then determines what
actions are necessary to achieve the desired state specified in the
2017-10-30 21:33:27 +01:00
configuration files.
This command is a convenient way to check whether the execution plan for a
set of changes matches your expectations without making any changes to
real resources or to the state. For example, `terraform plan` might be run
before committing a change to version control, to create confidence that it
will behave as expected.
The optional `-out` argument can be used to save the generated plan to a file
for later execution with `terraform apply` , which can be useful when
2018-11-14 02:13:47 +01:00
[running Terraform in automation ](https://learn.hashicorp.com/terraform/development/running-terraform-in-automation ).
2014-07-24 23:53:55 +02:00
2020-05-27 01:59:06 +02:00
If Terraform detects no changes to resource or to root module output values,
`terraform plan` will indicate that no changes are required.
2014-07-24 23:53:55 +02:00
## Usage
2019-03-01 21:30:51 +01:00
Usage: `terraform plan [options] [dir]`
2014-07-24 23:53:55 +02:00
By default, `plan` requires no flags and looks in the current directory
for the configuration and state file to refresh.
The command-line flags are all optional. The list of available flags are:
2019-12-10 20:06:06 +01:00
* `-compact-warnings` - If Terraform produces any warnings that are not
accompanied by errors, show them in a more compact form that includes only
the summary messages.
2014-07-24 23:53:55 +02:00
* `-destroy` - If set, generates a plan to destroy all the known resources.
2015-04-01 18:49:36 +02:00
* `-detailed-exitcode` - Return 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)
2014-12-06 00:29:00 +01:00
* `-input=true` - Ask for input for variables if not directly set.
2017-04-04 19:48:59 +02:00
* `-lock=true` - Lock the state file when locking is supported.
* `-lock-timeout=0s` - Duration to retry a state lock.
2014-07-24 23:53:55 +02:00
* `-no-color` - Disables output with coloring.
2014-07-26 06:42:06 +02:00
* `-out=path` - The path to save the generated execution plan. This plan
can then be used with `terraform apply` to be certain that only the
changes shown in this plan are applied. Read the warning on saved
plans below.
2014-07-24 23:53:55 +02:00
2015-10-06 00:18:03 +02:00
* `-parallelism=n` - Limit the number of concurrent operation as Terraform
2019-03-06 15:25:36 +01:00
[walks the graph ](/docs/internals/graph.html#walking-the-graph ). Defaults
to 10.
2015-10-06 00:18:03 +02:00
2014-07-24 23:53:55 +02:00
* `-refresh=true` - Update the state prior to checking for differences.
* `-state=path` - Path to the state file. Defaults to "terraform.tfstate".
2017-03-15 18:20:26 +01:00
Ignored when [remote state ](/docs/state/remote.html ) is used.
2014-07-24 23:53:55 +02:00
2015-04-01 01:48:54 +02:00
* `-target=resource` - A [Resource
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
Address](/docs/internals/resource-addressing.html) to target. This flag can
be used multiple times. See below for more information.
2015-03-27 23:24:15 +01:00
2016-07-12 00:37:51 +02:00
* `-var 'foo=bar'` - Set a variable in the Terraform configuration. This flag
can be set multiple times. Variable values are interpreted as
[HCL ](/docs/configuration/syntax.html#HCL ), so list and map values can be
specified via this flag.
2014-07-24 23:53:55 +02:00
* `-var-file=foo` - Set variables in the Terraform configuration from
2017-06-22 03:22:07 +02:00
a [variable file ](/docs/configuration/variables.html#variable-files ). If
a `terraform.tfvars` or any `.auto.tfvars` files are present in the current
directory, they will be automatically loaded. `terraform.tfvars` is loaded
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.
2014-07-24 23:53:55 +02:00
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
## Resource Targeting
The `-target` option can be used to focus Terraform's attention on only a
subset of resources.
[Resource Address ](/docs/internals/resource-addressing.html ) syntax is used
to specify the constraint. The resource address is interpreted as follows:
* If the given address has a _resource spec_ , only the specified resource
is targeted. If the named resource uses `count` and no explicit index
2018-06-05 07:13:57 +02:00
is specified in the address (i.e. aws_instance.example[3]), all of the instances sharing the given
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
resource name are targeted.
2018-06-11 21:34:25 +02:00
* If the given address _does not_ have a resource spec, and instead just
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
specifies a module path, the target applies to all resources in the
specified module _and_ all of the descendent modules of the specified
module.
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 ](/docs/configuration/data-sources.html ) can be used to access
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.
2014-07-26 06:42:06 +02:00
## Security Warning
Saved plan files (with the `-out` flag) encode the configuration,
state, diff, and _variables_ . Variables are often used to store secrets.
Therefore, the plan file can potentially store secrets.
Terraform itself does not encrypt the plan file. It is highly
recommended to encrypt the plan file if you intend to transfer it
2014-07-29 08:51:24 +02:00
or keep it at rest for an extended period of time.
2014-07-26 06:42:06 +02:00
Future versions of Terraform will make plan files more
secure.