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.