Skip to content

Commit

Permalink
core: add "apply -confirm" flag
Browse files Browse the repository at this point in the history
A common reason to want to use `terraform plan` is to have a chance to
review and confirm a plan before running it.  If in fact that is the
only reason you are running plan, this new `terraform apply -confirm`
flag provides an easier alternative to

    P=$(mktemp -t plan)
    terraform refresh
    terraform plan -refresh=false -out=$P
    terraform apply $P
    rm $P
  • Loading branch information
glasser committed Jun 21, 2016
1 parent 820c7ca commit 777a710
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
52 changes: 50 additions & 2 deletions command/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type ApplyCommand struct {
}

func (c *ApplyCommand) Run(args []string) int {
var destroyForce, refresh bool
var destroyForce, refresh, confirm bool
var moduleDepth int
args = c.Meta.process(args, true)

cmdName := "apply"
Expand All @@ -40,6 +41,10 @@ func (c *ApplyCommand) Run(args []string) int {
cmdFlags.BoolVar(&destroyForce, "force", false, "force")
}
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
if !c.Destroy {
cmdFlags.BoolVar(&confirm, "confirm", false, "confirm plan before applying")
c.addModuleDepthFlag(cmdFlags, &moduleDepth)
}
cmdFlags.IntVar(
&c.Meta.parallelism, "parallelism", DefaultParallelism, "parallelism")
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path")
Expand Down Expand Up @@ -111,6 +116,10 @@ func (c *ApplyCommand) Run(args []string) int {
"Destroy can't be called with a plan file."))
return 1
}
if confirm && planned {
c.Ui.Error("Cannot confirm with a plan file.")
return 1
}
if !destroyForce && c.Destroy {
// Default destroy message
desc := "Terraform will delete all your managed infrastructure.\n" +
Expand Down Expand Up @@ -162,11 +171,36 @@ func (c *ApplyCommand) Run(args []string) int {
}
}

if _, err := ctx.Plan(); err != nil {
plan, err := ctx.Plan()
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error creating plan: %s", err))
return 1
}

if confirm {
c.Ui.Output(strings.TrimSpace(confirmHeader) + "\n")
c.Ui.Output(FormatPlan(&FormatPlanOpts{
Plan: plan,
Color: c.Colorize(),
ModuleDepth: moduleDepth,
}))
desc := "Terraform will apply the plan described above.\n" +
"Only 'yes' will be accepted to confirm."
v, err := c.UIInput().Input(&terraform.InputOpts{
Id: "confirm",
Query: "Do you want to apply the plan above?",
Description: desc,
})
if err != nil {
c.Ui.Error(fmt.Sprintf("Error asking for confirmation: %s", err))
return 1
}
if v != "yes" {
c.Ui.Output("Apply cancelled.")
return 1
}
}
}

// Setup the state hook for continuous state updates
Expand Down Expand Up @@ -299,8 +333,14 @@ Options:
modifying. Defaults to the "-state-out" path with
".backup" extension. Set to "-" to disable backup.
-confirm Display the plan and ask for confirmation before applying.
-input=true Ask for input for variables if not directly set.
-module-depth=n Specifies the depth of modules to show when using -confirm.
This does not affect the plan itself, only the output
shown. By default, this is -1, which will expand all.
-no-color If specified, output won't contain any color.
-parallelism=n Limit the number of concurrent operations.
Expand Down Expand Up @@ -430,3 +470,11 @@ func outputsAsString(state *terraform.State, schema []*config.Output, includeHea

return strings.TrimSpace(outputBuf.String())
}

const confirmHeader = `
The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.
`
2 changes: 2 additions & 0 deletions website/source/docs/commands/apply.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The command-line flags are all optional. The list of available flags are:

* `-input=true` - Ask for input for variables if not directly set.

* `-confirm` - Display the plan and ask for confirmation before applying.

* `-no-color` - Disables output with coloring.

* `-parallelism=n` - Limit the number of concurrent operation as Terraform
Expand Down

0 comments on commit 777a710

Please sign in to comment.