Skip to content

Commit

Permalink
core: add "apply -auto-approve=false" 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 -auto-approve=false`
flag provides an easier alternative to

    P=$(mktemp -t plan)
    terraform refresh
    terraform plan -refresh=false -out=$P
    terraform apply $P
    rm $P

The flag defaults to true for now, but in a future version of Terraform it will
default to false.
  • Loading branch information
glasser committed Jun 13, 2017
1 parent 00dcf9b commit 30572bf
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 5 deletions.
7 changes: 4 additions & 3 deletions backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,10 @@ type Operation struct {

// The options below are more self-explanatory and affect the runtime
// behavior of the operation.
Destroy bool
Targets []string
Variables map[string]interface{}
Destroy bool
Targets []string
Variables map[string]interface{}
AutoApprove bool

// Input/output/control options.
UIIn terraform.UIInput
Expand Down
38 changes: 37 additions & 1 deletion backend/local/backend_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/backend"
"github.com/hashicorp/terraform/command/clistate"
"github.com/hashicorp/terraform/command/format"
"github.com/hashicorp/terraform/config/module"
"github.com/hashicorp/terraform/state"
"github.com/hashicorp/terraform/terraform"
Expand Down Expand Up @@ -89,10 +90,37 @@ func (b *Local) opApply(

// Perform the plan
log.Printf("[INFO] backend/local: apply calling Plan")
if _, err := tfCtx.Plan(); err != nil {
plan, err := tfCtx.Plan()
if err != nil {
runningOp.Err = errwrap.Wrapf("Error running plan: {{err}}", err)
return
}

trivialPlan := plan.Diff == nil || plan.Diff.Empty()
hasUI := op.UIOut != nil && op.UIIn != nil
if hasUI && !op.AutoApprove && !trivialPlan {
op.UIOut.Output(strings.TrimSpace(approvePlanHeader) + "\n")
op.UIOut.Output(format.Plan(&format.PlanOpts{
Plan: plan,
Color: b.Colorize(),
ModuleDepth: -1,
}))
desc := "Terraform will apply the plan described above.\n" +
"Only 'yes' will be accepted to approve."
v, err := op.UIIn.Input(&terraform.InputOpts{
Id: "approve",
Query: "Do you want to apply the plan above?",
Description: desc,
})
if err != nil {
runningOp.Err = errwrap.Wrapf("Error asking for approval: {{err}}", err)
return
}
if v != "yes" {
runningOp.Err = errors.New("Apply cancelled.")
return
}
}
}

// Setup our hook for continuous state updates
Expand Down Expand Up @@ -288,3 +316,11 @@ Terraform encountered an error attempting to save the state before canceling
the current operation. Once the operation is complete another attempt will be
made to save the final state.
`

const approvePlanHeader = `
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.
`
15 changes: 14 additions & 1 deletion command/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type ApplyCommand struct {
}

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

cmdName := "apply"
Expand All @@ -42,6 +42,9 @@ func (c *ApplyCommand) Run(args []string) int {
cmdFlags.BoolVar(&destroyForce, "force", false, "force")
}
cmdFlags.BoolVar(&refresh, "refresh", true, "refresh")
if !c.Destroy {
cmdFlags.BoolVar(&autoApprove, "auto-approve", true, "skip interactive approval of plan before applying")
}
cmdFlags.IntVar(
&c.Meta.parallelism, "parallelism", DefaultParallelism, "parallelism")
cmdFlags.StringVar(&c.Meta.statePath, "state", "", "path")
Expand Down Expand Up @@ -106,6 +109,11 @@ func (c *ApplyCommand) Run(args []string) int {
if plan != nil {
// Reset the config path for backend loading
configPath = ""

if !autoApprove {
c.Ui.Error("Cannot combine -auto-approve=false with a plan file.")
return 1
}
}

// Load the module if we don't have one yet (not running from plan)
Expand Down Expand Up @@ -189,6 +197,7 @@ func (c *ApplyCommand) Run(args []string) int {
opReq.Plan = plan
opReq.PlanRefresh = refresh
opReq.Type = backend.OperationTypeApply
opReq.AutoApprove = autoApprove

// Perform the operation
ctx, ctxCancel := context.WithCancel(context.Background())
Expand Down Expand Up @@ -283,6 +292,10 @@ Options:
-lock-timeout=0s Duration to retry a state lock.
-auto-approve=true Skip interactive approval of plan before applying. In a
future version of Terraform, this flag's default value
will change to false.
-input=true Ask for input for variables if not directly set.
-no-color If specified, output won't contain any color.
Expand Down
1 change: 1 addition & 0 deletions command/meta_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ func (m *Meta) Operation() *backend.Operation {
PlanOutBackend: m.backendState,
Targets: m.targets,
UIIn: m.UIInput(),
UIOut: m.Ui,
Workspace: m.Workspace(),
LockState: m.stateLock,
StateLockTimeout: m.stateLockTimeout,
Expand Down
3 changes: 3 additions & 0 deletions website/source/docs/commands/apply.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ The command-line flags are all optional. The list of available flags are:

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

* `-auto-approve=true` - Skip interactive approval of plan before applying. In a
future version of Terraform, this flag's default value will change to false.

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

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

0 comments on commit 30572bf

Please sign in to comment.