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