github.com/jaredpalmer/terraform@v1.1.0-alpha20210908.0.20210911170307-88705c943a03/website/docs/cli/commands/plan.html.md (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Command: plan"
     4  sidebar_current: "docs-commands-plan"
     5  description: "The terraform plan command creates an execution plan with a preview of the changes that Terraform will make to your infrastructure."
     6  ---
     7  
     8  # Command: plan
     9  
    10  The `terraform plan` command creates an execution plan, which lets you preview
    11  the changes that Terraform plans to make to your infrastructure. By default,
    12  when Terraform creates a plan it:
    13  
    14  * Reads the current state of any already-existing remote objects to make sure
    15    that the Terraform state is up-to-date.
    16  * Compares the current configuration to the prior state and noting any
    17    differences.
    18  * Proposes a set of change actions that should, if applied, make the remote
    19    objects match the configuration.
    20  
    21  > **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.
    22  
    23  The plan command alone will not actually carry out the proposed changes, and
    24  so you can use this command to check whether the proposed changes match what
    25  you expected before you apply the changes or share your changes with your
    26  team for broader review.
    27  
    28  If Terraform detects that no changes are needed to resource instances or to
    29  root module output values, `terraform plan` will report that no actions need
    30  to be taken.
    31  
    32  If you are using Terraform directly in an interactive terminal and you expect
    33  to apply the changes Terraform proposes, you can alternatively run
    34  [`terraform apply`](./apply.html) directly. By default, the "apply" command
    35  automatically generates a new plan and prompts for you to approve it.
    36  
    37  You can use the optional `-out=FILE` option to save the generated plan to a
    38  file on disk, which you can later execute by passing the file to
    39  [`terraform apply`](./apply.html) as an extra argument. This two-step workflow
    40  is primarily intended for when
    41  [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).
    42  
    43  If you run `terraform plan` without the `-out=FILE` option then it will create
    44  a _speculative plan_, which is a description of the effect of the plan but
    45  without any intent to actually apply it.
    46  
    47  In teams that use a version control and code review workflow for making changes
    48  to real infrastructure, developers can use speculative plans to verify the
    49  effect of their changes before submitting them for code review. However, it's
    50  important to consider that other changes made to the target system in the
    51  meantime might cause the final effect of a configuration change to be different
    52  than what an earlier speculative plan indicated, so you should always re-check
    53  the final non-speculative plan before applying to make sure that it still
    54  matches your intent.
    55  
    56  ## Usage
    57  
    58  Usage: `terraform plan [options]`
    59  
    60  The `plan` subcommand looks in the current working directory for the root module
    61  configuration.
    62  
    63  Because the plan command is one of the main commands of Terraform, it has
    64  a variety of different options, described in the following sections. However,
    65  most of the time you should not need to set any of these options, because
    66  a Terraform configuration should typically be designed to work with no special
    67  additional options for routine work.
    68  
    69  The remaining sections on this page describe the various options:
    70  
    71  * **[Planning Modes](#planning-modes)**: There are some special alternative
    72    planning modes that you can use for some special situations where your goal
    73    is not just to change the remote system to match your configuration.
    74  * **[Planning Options](#planning-options)**: Alongside the special planning
    75    modes, there are also some options you can set in order to customize the
    76    planning process for unusual needs.
    77      * **[Resource Targeting](#resource-targeting)** is one particular
    78        special planning option that has some important caveats associated
    79        with it.
    80  * **[Other Options](#other-options)**: These change the behavior of the planning
    81    command itself, rather than customizing the content of the generated plan.
    82  
    83  ## Planning Modes
    84  
    85  The section above described Terraform's default planning behavior, which is
    86  intended for changing the remote system to match with changes you've made to
    87  your configuration.
    88  
    89  Terraform has two alternative planning modes, each of which creates a plan with
    90  a different intended outcome:
    91  
    92  * **Destroy mode:** creates a plan whose goal is to destroy all remote objects
    93    that currently exist, leaving an empty Terraform state. This can be useful
    94    for situations like transient development environments, where the managed
    95    objects cease to be useful once the development task is complete.
    96  
    97      Activate destroy mode using the `-destroy` command line option.
    98  
    99  * **Refresh-only mode:** creates a plan whose goal is only to update the
   100    Terraform state and any root module output values to match changes made to
   101    remote objects outside of Terraform. This can be useful if you've
   102    intentionally changed one or more remote objects outside of the usual
   103    workflow (e.g. while responding to an incident) and you now need to reconcile
   104    Terraform's records with those changes.
   105  
   106      Activate refresh-only mode using the `-refresh-only` command line option.
   107  
   108  In situations where we need to discuss the default planning mode that Terraform
   109  uses when none of the alternative modes are selected, we refer to it as
   110  "Normal mode". Because these alternative modes are for specialized situations
   111  only, some other Terraform documentation only discusses the normal planning
   112  mode.
   113  
   114  The planning modes are all mutually-exclusive, so activating any non-default
   115  planning mode disables the "normal" planning mode, and you can't use more than
   116  one alternative mode at the same time.
   117  
   118  -> **Note:** In Terraform v0.15 and earlier, the `-destroy` option is
   119  supported only by the `terraform plan` command, and not by the
   120  `terraform apply` command. To create and apply a plan in destroy mode in
   121  earlier versions you must run [`terraform destroy`](./destroy.html).
   122  
   123  -> **Note:** The `-refresh-only` option is available only in Terraform v0.15.4
   124  and later.
   125  
   126  > **Hands-on:** Try the [Use Refresh-Only Mode to Sync Terraform State](https://learn.hashicorp.com/tutorials/terraform/refresh) tutorial on HashiCorp Learn.
   127  
   128  ## Planning Options
   129  
   130  In addition to the planning _modes_ described above, there are also several
   131  additional options that can modify details of the behavior of the planning
   132  step.
   133  
   134  When you use `terraform apply` without passing it a saved plan file, it
   135  incorporates the `terraform plan` command functionality and so the planning
   136  options in this section, along with the planning mode selection options in
   137  the previous section, are also available with the same meanings on
   138  `terraform apply`.
   139  
   140  * `-refresh=false` - Disables the default behavior of synchronizing the
   141    Terraform state with remote objects before checking for configuration changes.
   142  
   143      This option can potentially make the planning operation faster by reducing
   144      the number of remote API requests, but it comes at the expense of having
   145      Terraform not take into account any changes that might've happened outside
   146      of Terraform, and thus the resulting plan may not be complete or correct.
   147  
   148      This option is not available in the "refresh only" planning mode, because
   149      it would effectively disable the entirety of the planning operation in that
   150      case.
   151  
   152  * `-replace=ADDRESS` - Instructs Terraform to plan to replace the single
   153    resource instance with the given address. If the given instance would
   154    normally have caused only an "update" action, or no action at all, then
   155    Terraform will choose a "replace" action instead.
   156  
   157      You can use this option if you have learned that a particular remote object
   158      has become degraded in some way. If you are using immutable infrastructure
   159      patterns then you may wish to respond to that by replacing the
   160      malfunctioning object with a new object that has the same configuration.
   161  
   162      This option is allowed only in the normal planning mode, so this option
   163      is incompatible with the `-destroy` option.
   164  
   165      The `-replace=...` option is available only from Terraform v0.15.2 onwards.
   166      For earlier versions, you can achieve a similar effect (with some caveats)
   167      using [`terraform taint`](./taint.html).
   168  
   169  * `-target=ADDRESS` - Instructs Terraform to focus its planning efforts only
   170    on resource instances which match the given address and on any objects that
   171    those instances depend on.
   172  
   173      This command is for exceptional use only. See
   174      [Resource Targeting](#resource-targeting)
   175      below for more information.
   176  
   177  * `-var 'NAME=VALUE'` - Sets a value for a single
   178    [input variable](/docs/language/values/variables.html) declared in the
   179    root module of the configuration. Use this option multiple times to set
   180    more than one variable. For more information see
   181    [Input Variables on the Command Line](#input-variables-on-the-command-line),
   182    below.
   183  
   184  * `-var-file=FILENAME` - Sets values for potentially many
   185    [input variables](/docs/language/values/variables.html) declared in the
   186    root module of the configuration, using definitions from a
   187    ["tfvars" file](/docs/language/values/variables.html#variable-definitions-tfvars-files).
   188    Use this option multiple times to include values from more than one file.
   189  
   190  There are several other ways to set values for input variables in the root
   191  module, aside from the `-var` and `-var-file` options. For more information,
   192  see
   193  [Assigning Values to Root Module Variables](/docs/language/values/variables.html#assigning-values-to-root-module-variables).
   194  
   195  ### Input Variables on the Command Line
   196  
   197  You can use the `-var` command line option to specify values for
   198  [input variables](/docs/language/values/variables.html) declared in your
   199  root module.
   200  
   201  However, to do so will require writing a command line that is parsable both
   202  by your chosen command line shell _and_ Terraform, which can be complicated
   203  for expressions involving lots of quotes and escape sequences. In most cases
   204  we recommend using the `-var-file` option instead, and write your actual values
   205  in a separate file so that Terraform can parse them directly, rather than
   206  interpreting the result of your shell's parsing.
   207  
   208  To use `-var` on a Unix-style shell on a system like Linux or macOS we
   209  recommend writing the option argument in single quotes `'` to ensure the
   210  shell will interpret the value literally:
   211  
   212  ```
   213  terraform plan -var 'name=value'
   214  ```
   215  
   216  If your intended value also includes a single quote then you'll still need to
   217  escape that for correct interpretation by your shell, which also requires
   218  temporarily ending the quoted sequence so that the backslash escape character
   219  will be significant:
   220  
   221  ```
   222  terraform plan -var 'name=va'\''lue'
   223  ```
   224  
   225  When using Terraform on Windows, we recommend using the Windows Command Prompt
   226  (`cmd.exe`). When you pass a variable value to Terraform from the Windows
   227  Command Prompt, use double quotes `"` around the argument:
   228  
   229  ```
   230  terraform plan -var "name=value"
   231  ```
   232  
   233  If your intended value includes literal double quotes then you'll need to
   234  escape those with a backslash:
   235  
   236  ```
   237  terraform plan -var "name=va\"lue"
   238  ```
   239  
   240  PowerShell on Windows cannot correctly pass literal quotes to external programs,
   241  so we do not recommend using Terraform with PowerShell when you are on Windows.
   242  Use Windows Command Prompt instead.
   243  
   244  The appropriate syntax for writing the variable value is different depending
   245  on the variable's [type constraint](/docs/language/expressions/type-constraints.html).
   246  The primitive types `string`, `number`, and `bool` all expect a direct string
   247  value with no special punctuation except that required by your shell, as
   248  shown in the above examples. For all other type constraints, including list,
   249  map, and set types and the special `any` keyword, you must write a valid
   250  Terraform language expression representing the value, and write any necessary
   251  quoting or escape characters to ensure it will pass through your shell
   252  literally to Terraform. For example, for a `list(string)` type constraint:
   253  
   254  ```
   255  # Unix-style shell
   256  terraform plan -var 'name=["a", "b", "c"]'
   257  
   258  # Windows Command Prompt (do not use PowerShell on Windows)
   259  terraform plan -var "name=[\"a\", \"b\", \"c\"]"
   260  ```
   261  
   262  Similar constraints apply when setting input variables using environment
   263  variables. For more information on the various methods for setting root module
   264  input variables, see
   265  [Assigning Values to Root Module Variables](/docs/language/values/variables.html#assigning-values-to-root-module-variables).
   266  
   267  
   268  ### Resource Targeting
   269  
   270  > **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.
   271  
   272  You can use the `-target` option to focus Terraform's attention on only a
   273  subset of resources.
   274  You can use [resource address syntax](/docs/cli/state/resource-addressing.html)
   275  to specify the constraint. Terraform interprets the resource address as follows:
   276  
   277  * If the given address identifies one specific resource instance, Terraform
   278    will select that instance alone. For resources with either `count` or
   279    `for_each` set, a resource instance address must include the instance index
   280    part, like `aws_instance.example[0]`.
   281  
   282  * If the given address identifies a resource as a whole, Terraform will select
   283    all of the instances of that resource. For resources with either `count`
   284    or `for_each` set, this means selecting _all_ instance indexes currently
   285    associated with that resource. For single-instance resources (without
   286    either `count` or `for_each`), the resource address and the resource instance
   287    address are identical, so this possibility does not apply.
   288  
   289  * If the given address identifies an entire module instance, Terraform will
   290    select all instances of all resources that belong to that module instance
   291    and all of its child module instances.
   292  
   293  Once Terraform has selected one or more resource instances that you've directly
   294  targeted, it will also then extend the selection to include all other objects
   295  that those selections depend on either directly or indirectly.
   296  
   297  This targeting capability is provided for exceptional circumstances, such
   298  as recovering from mistakes or working around Terraform limitations. It
   299  is *not recommended* to use `-target` for routine operations, since this can
   300  lead to undetected configuration drift and confusion about how the true state
   301  of resources relates to configuration.
   302  
   303  Instead of using `-target` as a means to operate on isolated portions of very
   304  large configurations, prefer instead to break large configurations into
   305  several smaller configurations that can each be independently applied.
   306  [Data sources](/docs/language/data-sources/index.html) can be used to access
   307  information about resources created in other configurations, allowing
   308  a complex system architecture to be broken down into more manageable parts
   309  that can be updated independently.
   310  
   311  ## Other Options
   312  
   313  The `terraform plan` command also has some other options that are related to
   314  the input and output of the planning command, rather than customizing what
   315  sort of plan Terraform will create. These commands are not necessarily also
   316  available on `terraform apply`, unless otherwise stated in the documentation
   317  for that command.
   318  
   319  The available options are:
   320  
   321  * `-compact-warnings` - Shows any warning messages in a compact form which
   322    includes only the summary messages, unless the warnings are accompanied by
   323    at least one error and thus the warning text might be useful context for
   324    the errors.
   325  
   326  * `-detailed-exitcode` - Returns a detailed exit code when the command exits.
   327    When provided, this argument changes the exit codes and their meanings to
   328    provide more granular information about what the resulting plan contains:
   329    * 0 = Succeeded with empty diff (no changes)
   330    * 1 = Error
   331    * 2 = Succeeded with non-empty diff (changes present)
   332  
   333  * `-input=false` - Disables Terraform's default behavior of prompting for
   334    input for root module input variables that have not otherwise been assigned
   335    a value. This option is particularly useful when running Terraform in
   336    non-interactive automation systems.
   337  
   338  * `-json` - Enables the [machine readable JSON UI][machine-readable-ui] output.
   339    This implies `-input=false`, so the configuration must have no unassigned
   340    variable values to continue.
   341  
   342    [machine-readable-ui]: /docs/internals/machine-readable-ui.html
   343  
   344  * `-lock=false` - Don't hold a state lock during the operation. This is
   345     dangerous if others might concurrently run commands against the same
   346     workspace.
   347  
   348  * `-lock-timeout=DURATION` - Unless locking is disabled with `-lock=false`,
   349    instructs Terraform to retry acquiring a lock for a period of time before
   350    returning an error. The duration syntax is a number followed by a time
   351    unit letter, such as "3s" for three seconds.
   352  
   353  * `-no-color` - Disables terminal formatting sequences in the output. Use this
   354    if you are running Terraform in a context where its output will be
   355    rendered by a system that cannot interpret terminal formatting.
   356  
   357  * `-out=FILENAME` - Writes the generated plan to the given filename in an
   358    opaque file format that you can later pass to `terraform apply` to execute
   359    the planned changes, and to some other Terraform commands that can work with
   360    saved plan files.
   361  
   362      Terraform will allow any filename for the plan file, but a typical
   363      convention is to name it `tfplan`. **Do not** name the file with a suffix
   364      that Terraform recognizes as another file format; if you use a `.tf` suffix
   365      then Terraform will try to interpret the file as a configuration source
   366      file, which will then cause syntax errors for subsequent commands.
   367  
   368      The generated file is not in any standard format intended for consumption
   369      by other software, but the file _does_ contain your full configuration,
   370      all of the values associated with planned changes, and all of the plan
   371      options including the input variables. If your plan includes any sort of
   372      sensitive data, even if obscured in Terraform's terminal output, it will
   373      be saved in cleartext in the plan file. You should therefore treat any
   374      saved plan files as potentially-sensitive artifacts.
   375  
   376  * `-parallelism=n` - Limit the number of concurrent operations as Terraform
   377    [walks the graph](/docs/internals/graph.html#walking-the-graph). Defaults
   378    to 10.
   379  
   380  For configurations using
   381  [the `local` backend](/docs/language/settings/backends/local.html) only,
   382  `terraform plan` accepts the legacy command line option
   383  [`-state`](/docs/language/settings/backends/local.html#command-line-arguments).
   384  
   385  ### Passing a Different Configuration Directory
   386  
   387  Terraform v0.13 and earlier accepted an additional positional argument giving
   388  a directory path, in which case Terraform would use that directory as the root
   389  module instead of the current working directory.
   390  
   391  That usage was deprecated in Terraform v0.14 and removed in Terraform v0.15.
   392  If your workflow relies on overriding the root module directory, use
   393  [the `-chdir` global option](./#switching-working-directory-with-chdir)
   394  instead, which works across all commands and makes Terraform consistently look
   395  in the given directory for all files it would normally read or write in the
   396  current working directory.
   397  
   398  If your previous use of this legacy pattern was also relying on Terraform
   399  writing the `.terraform` subdirectory into the current working directory even
   400  though the root module directory was overridden, use
   401  [the `TF_DATA_DIR` environment variable](/docs/cli/config/environment-variables.html#tf_data_dir)
   402  to direct Terraform to write the `.terraform` directory to a location other
   403  than the current working directory.