github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/website/docs/cli/commands/plan.mdx (about)

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