terraform plan command
Theterraform plan command creates an execution plan, which lets you previewthe changes that Terraform plans to make to your infrastructure.
Introduction
By default, Terraform performs the following operations when it creates a plan:
- Reads the current state of any already-existing remote objects to make surethat the Terraform state is up-to-date.
- Compares the current configuration to the prior state and noting anydifferences.
- Proposes a set of change actions that should, if applied, make the remoteobjects match the configuration.
Hands-on: Try theTerraform: Get Started tutorials. For more in-depth details on the
plancommand, check out theCreate a Terraform Plan tutorial.
Theplan command alone does not actually carry out the proposed changes You can use this command to check whether the proposed changes match whatyou expected before you apply the changes or share your changes with yourteam for broader review.
If Terraform detects that no changes are needed to resource instances or toroot module output values,terraform plan will report that no actions needto be taken.
If you are using Terraform directly in an interactive terminal and you expectto apply the changes Terraform proposes, you can alternatively runterraform apply directly. By default, the "apply" commandautomatically generates a new plan and prompts for you to approve it.
You can use the optional-out=FILE option to save the generated plan to afile on disk, which you can later execute by passing the file toterraform apply as an extra argument. This two-step workflowis primarily intended for whenrunning Terraform in automation.
If you runterraform plan without the-out=FILE option then it will createaspeculative plan, which is a description of the effect of the plan butwithout any intent to actually apply it.
In teams that use a version control and code review workflow for making changesto real infrastructure, developers can use speculative plans to verify theeffect of their changes before submitting them for code review. However, it'simportant to consider that other changes made to the target system in themeantime might cause the final effect of a configuration change to be differentthan what an earlier speculative plan indicated, so you should always re-checkthe final non-speculative plan before applying to make sure that it stillmatches your intent.
Usage
Usage:terraform plan [options]
Theplan subcommand looks in the current working directory for the root moduleconfiguration.
Because the plan command is one of the main commands of Terraform, it hasa variety of different options, described in the following sections. However,most of the time you should not need to set any of these options, becausea Terraform configuration should typically be designed to work with no specialadditional options for routine work.
The remaining sections on this page describe the various options:
- Planning Modes: There are some special alternativeplanning modes that you can use for some special situations where your goalis not just to change the remote system to match your configuration.
- Planning Options: Alongside the special planningmodes, there are also some options you can set in order to customize theplanning process for unusual needs.
- Resource Targeting is one particularspecial planning option that has some important caveats associatedwith it.
- Other Options: These change the behavior of the planningcommand itself, rather than customizing the content of the generated plan.
Planning Modes
The previous section describes Terraform's default planning behavior, whichchanges the remote system to match the changes you make toyour configuration. Terraform has two alternative planning modes, each of which creates a plan with a different intended outcome. These options are available for bothterraform plan andterraform apply.
Destroy mode: creates a plan whose goal is to destroy all remote objectsthat currently exist, leaving an empty Terraform state. It is the same as running
terraform 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.Activate destroy mode using the
-destroycommand line option.Refresh-only mode: creates a plan whose goal is only to update theTerraform state and any root module output values to match changes made toremote objects outside of Terraform. This can be useful if you'veintentionally changed one or more remote objects outside of the usualworkflow (e.g. while responding to an incident) and you now need to reconcileTerraform's records with those changes.
Activate refresh-only mode using the
-refresh-onlycommand line option.
In situations where we need to discuss the default planning mode that Terraformuses when none of the alternative modes are selected, we refer to it as"Normal mode". Because these alternative modes are for specialized situationsonly, some other Terraform documentation only discusses the normal planningmode.
The planning modes are all mutually-exclusive, so activating any non-defaultplanning mode disables the "normal" planning mode, and you can't use more thanone alternative mode at the same time.
Note: In Terraform v0.15 and earlier, the-destroy option issupported only by theterraform plan command, and not by theterraform apply command. To create and apply a plan in destroy mode inearlier versions you must runterraform destroy.
Note: The-refresh-only option is available only in Terraform v0.15.4and later.
Hands-on: Try theUse Refresh-Only Mode to Sync Terraform State tutorial.
Planning Options
In addition to alternateplanning modes, there are several options that can modify planning behavior. These options are available for bothterraform plan andterraform apply.
-refresh=false- Disables the default behavior of synchronizing theTerraform 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, settingrefresh=falsecauses Terraform to ignore external changes, which could result in an incomplete or incorrect plan. You cannot userefresh=falsein refresh-only planning mode because it would effectively disable the entirety of the planning operation.-replace=ADDRESS- Instructs Terraform to plan to replace theresource 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 configuration 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-replacewith the-destroyoption, and it is only available from Terraform v0.15.2 onwards. For earlier versions, useterraform taintto achieve a similar result.-target=ADDRESS- Instructs Terraform to focus its planning efforts onlyon resource instances which match the given address and on any objects thatthose instances depend on.Note: Use
-target=ADDRESSin exceptional circumstances only, such as recovering from mistakes or working around Terraform limitations. Refer toResource Targeting for more details.-var 'NAME=VALUE'- Sets a value for a singleinput variable declared in theroot module of the configuration. Use this option multiple times to setmore than one variable. Refer toInput Variables on the Command Line for more information.-var-file=FILENAME- Sets values for potentially manyinput variables declared in theroot module of the configuration, using definitions from a.tfvarsfile.Use this option multiple times to include values from more than one file.There are several other ways to set values for input variables in the rootmodule, aside from the-varand-var-fileoptions. Refer toAssign values to input variables for more information.
Input Variables on the Command Line
You can use the-var command line option to specify values forinput variables declared in yourroot module.
However, to do so will require writing a command line that is parsable bothby your chosen command line shelland Terraform, which can be complicatedfor expressions involving lots of quotes and escape sequences. In most caseswe recommend using the-var-file option instead, and write your actual valuesin a separate file so that Terraform can parse them directly, rather thaninterpreting the result of your shell's parsing.
Warning: Terraform will error if you include a space before or after the equals sign (e.g.,-var "length = 2").
To use-var on a Unix-style shell on a system like Linux or macOS werecommend writing the option argument in single quotes' to ensure theshell will interpret the value literally:
terraform plan -var 'name=value'If your intended value also includes a single quote then you'll still need toescape that for correct interpretation by your shell, which also requirestemporarily ending the quoted sequence so that the backslash escape characterwill be significant:
terraform plan -var 'name=va'\''lue'When using Terraform on Windows, we recommend using the Windows Command Prompt(cmd.exe). When you pass a variable value to Terraform from the WindowsCommand Prompt, use double quotes" around the argument:
terraform plan -var "name=value"If your intended value includes literal double quotes then you'll need toescape those with a backslash:
terraform plan -var "name=va\"lue"PowerShell on Windows cannot correctly pass literal quotes to external programs,so we do not recommend using Terraform with PowerShell when you are on Windows.Use Windows Command Prompt instead.
The appropriate syntax for writing the variable value is different dependingon the variable'stype constraint.The primitive typesstring,number, andbool all expect a direct stringvalue with no special punctuation except that required by your shell, asshown in the above examples. For all other type constraints, including list,map, and set types and the specialany keyword, you must write a validTerraform language expression representing the value, and write any necessaryquoting or escape characters to ensure it will pass through your shellliterally to Terraform. For example, for alist(string) type constraint:
# Unix-style shellterraform plan -var 'name=["a", "b", "c"]' # Windows Command Prompt (do not use PowerShell on Windows)terraform plan -var "name=[\"a\", \"b\", \"c\"]"Similar constraints apply when setting input variables using environmentvariables. For more information on the various methods for setting root moduleinput variables, seeAssign values to input variables.
Resource Targeting
Hands-on: Try theTarget resources tutorial.
You can use the-target option to focus Terraform's attention on only asubset of resources.You can useresource address syntaxto specify the constraint. Terraform interprets the resource address as follows:
If the given address identifies one specific resource instance, Terraformwill select that instance alone. For resources with either
countorfor_eachset, a resource instance address must include the instance indexpart, likeaws_instance.example[0].If the given address identifies a resource as a whole, Terraform will selectall of the instances of that resource. For resources with either
countorfor_eachset, this means selectingall instance indexes currentlyassociated with that resource. For single-instance resources (withouteithercountorfor_each), the resource address and the resource instanceaddress are identical, so this possibility does not apply.If the given address identifies an entire module instance, Terraform willselect all instances of all resources that belong to that module instanceand all of its child module instances.
Once Terraform has selected one or more resource instances that you've directlytargeted, it will also then extend the selection to include all other objectsthat those selections depend on either directly or indirectly.
This targeting capability is provided for exceptional circumstances, suchas recovering from mistakes or working around Terraform limitations. Itisnot recommended to use-target for routine operations, since this canlead to undetected configuration drift and confusion about how the true stateof resources relates to configuration.
Instead of using-target as a means to operate on isolated portions of verylarge configurations, prefer instead to break large configurations intoseveral smaller configurations that can each be independently applied.Data sources can be used to accessinformation about resources created in other configurations, allowinga complex system architecture to be broken down into more manageable partsthat can be updated independently.
Other Options
Theterraform plan command also has some other options that are related tothe input and output of the planning command, rather than customizing whatsort of plan Terraform will create. These commands are not necessarily alsoavailable onterraform apply, unless otherwise stated in the documentationfor that command.
The available options are:
-compact-warnings- Shows any warning messages in a compact form whichincludes only the summary messages, unless the warnings are accompanied byat least one error and thus the warning text might be useful context forthe errors.-detailed-exitcode- Returns a detailed exit code when the command exits.When provided, this argument changes the exit codes and their meanings toprovide 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)
-generate-config-out=PATH- (Experimental) Ifimportblocks are present in configuration, instructs Terraform to generate HCL for any imported resources not already present. The configuration is written to a new file at PATH, which must not already exist, or Terraform will error. If the plan fails for another reason, Terraform may still attempt to write configuration.
-input=false- Disables Terraform's default behavior of prompting forinput for root module input variables that have not otherwise been assigneda value. This option is particularly useful when running Terraform innon-interactive automation systems.-json- Enables themachine readable JSON UI output.This implies-input=false, so the configuration must have no unassignedvariable values to continue.-lock=false- Don't hold a state lock during the operation. This isdangerous if others might concurrently run commands against the sameworkspace.-lock-timeout=DURATION- Unless locking is disabled with-lock=false,instructs Terraform to retry acquiring a lock for a period of time beforereturning an error. The duration syntax is a number followed by a timeunit letter, such as "3s" for three seconds.-no-color- Disables terminal formatting sequences in the output. Use thisif you are running Terraform in a context where its output will berendered by a system that cannot interpret terminal formatting.-out=FILENAME- Writes the generated plan to the given filename in anopaque file format that you can later pass toterraform applyto executethe planned changes, and to some other Terraform commands that can work withsaved plan files.Terraform will allow any filename for the plan file, but a typicalconvention is to name it
tfplan.Do not name the file with a suffixthat Terraform recognizes as another file format; if you use a.tfsuffixthen Terraform will try to interpret the file as a configuration sourcefile, which will then cause syntax errors for subsequent commands.The generated file is not in any standard format intended for consumptionby other software, but the filedoes contain your full configuration,all of the values associated with planned changes, and all of the planoptions including the input variables. If your plan includes any sort ofsensitive data, even if obscured in Terraform's terminal output, it willbe saved in cleartext in the plan file. You should therefore treat anysaved plan files as potentially-sensitive artifacts.
-parallelism=n- Limit the number of concurrent operations as Terraformwalks the graph. Defaultsto 10.
For configurations usingthelocal backend only,terraform plan accepts the legacy command line option-state.
Passing a Different Configuration Directory
Terraform v0.13 and earlier accepted an additional positional argument givinga directory path, in which case Terraform would use that directory as the rootmodule instead of the current working directory.
That usage was deprecated in Terraform v0.14 and removed in Terraform v0.15.If your workflow relies on overriding the root module directory, usethe-chdir global optioninstead, which works across all commands and makes Terraform consistently lookin the given directory for all files it would normally read or write in thecurrent working directory.
If your previous use of this legacy pattern was also relying on Terraformwriting the.terraform subdirectory into the current working directory eventhough the root module directory was overridden, usetheTF_DATA_DIR environment variableto direct Terraform to write the.terraform directory to a location otherthan the current working directory.