hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io
Other
42.77k stars 9.56k forks source link

Help for `terraform destroy -help`? #29019

Open lorengordon opened 3 years ago

lorengordon commented 3 years ago

Terraform Version

$ terraform version
Terraform v1.0.0
on linux_amd64

Expected Behavior

terraform destroy -help should output the options for terraform destroy.

Actual Behavior

No useful help was output.

$ terraform destroy -help
Usage: terraform [global options] destroy [options]

  Destroy Terraform-managed infrastructure.

  This command is a convenience alias for:
      terraform apply -destroy

  This command also accepts many of the plan-customization options accepted by
  the terraform plan command. For more information on those options, run:
      terraform plan -help

Additional Context

I got here by running terraform destroy -force, which is deprecated, but it says to get help using terraform destroy -help, which doesn't really output anything that helps me figure out the replacement is terraform destroy -auto-approve

$ terraform destroy -force
╷
│ Error: Failed to parse command-line flags
│
│ flag provided but not defined: -force
╵

For more help on using this command, run:
  terraform destroy -help
apparentlymart commented 3 years ago

Hi @lorengordon!

Looks like you ran into one of the changes from the v0.15 release here. The upgrade guide does mention that, but I can certainly understand that it might not be obvious to look there given that Terraform simply reported that the option isn't valid at all, rather than giving any guidance about what it was replaced with. Ideally we would've made -destroy produce a specific error message saying that -auto-approve is the replacement.

The intent of this new help message is to draw attention to the fact that terraform destroy isn't really a separate subcommand at all, but is literally just the same as running terraform apply -destroy. Therefore terraform destroy -auto-approve is the same as terraform apply -destroy -auto-approve.

A particular quirk of this current message though is that it directs you to run terraform plan -help to see the options, but that doesn't include the additional options that are unique to terraform apply; you'd need to run terraform apply -help to see the -auto-approve option.

With that said, I can't help but feel that the most helpful way to respond to what you described here would be to make Terraform react to -force by explicitly saying to use -auto-approve instead, because that would avoid you needing to go reading through all of this help output in the first place.

lorengordon commented 3 years ago

Hi @apparentlymart! Yeah, I think you covered it all. It would be helpful if there were an explicit deprecation message for destroy -force that advises the user to use destroy -auto-approve instead.

It was especially confusing that no help arguments are displayed for destroy -help. Instead I have to run both plan -help and apply -help and guess which arguments are relevant to apply -destroy?

Oh, one more thing, apply -help doesn't even list -destroy as an option!

$ terraform apply -help
Usage: terraform [global options] apply [options] [PLAN]

  Creates or updates infrastructure according to Terraform configuration
  files in the current directory.

  By default, Terraform will generate a new plan and present it for your
  approval before taking any action. You can optionally provide a plan
  file created by a previous call to "terraform plan", in which case
  Terraform will take the actions described in that plan without any
  confirmation prompt.

Options:

  -auto-approve          Skip interactive approval of plan before applying.

  -backup=path           Path to backup the existing state file before
                         modifying. Defaults to the "-state-out" path with
                         ".backup" extension. Set to "-" to disable backup.

  -compact-warnings      If Terraform produces any warnings that are not
                         accompanied by errors, show them in a more compact
                         form that includes only the summary messages.

  -lock=false            Don't hold a state lock during the operation. This is
                         dangerous if others might concurrently run commands
                         against the same workspace.

  -lock-timeout=0s       Duration to retry a state lock.

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

  -no-color              If specified, output won't contain any color.

  -parallelism=n         Limit the number of parallel resource operations.
                         Defaults to 10.

  -state=path            Path to read and save state (unless state-out
                         is specified). Defaults to "terraform.tfstate".

  -state-out=path        Path to write state to that is different than
                         "-state". This can be used to preserve the old
                         state.

  If you don't provide a saved plan file then this command will also accept
  all of the plan-customization options accepted by the terraform plan command.
  For more information on those options, run:
      terraform plan -help
apparentlymart commented 3 years ago

Indeed, -destroy is covered indirectly as part of "this command will also accept all of the plan-customization options accepted by the terraform plan command".

Unfortunately Terraform is built around a CLI framework which assumes that all commands are entirely independent from one another and so sharing help output between all of them is non-trivial and hence we are currently doing it by reference. I would like to refactor this so that these are constructed mechanically and systematically rather than hand-written, but that's not a change we have the room to make right now. Adding a better error message specifically for the removal of -force seems more tractable because I expect it'll just be one extra check inside the implementation of the apply command (which destroy is, as the error message said, just an alias for.)

timblaktu commented 3 years ago

Similarly, I am trying to unconditionally force re-creation of all resources in a terraform project that is to be run on CI (Jenkins) that props up an ephemeral testing environment. At first I was using terraform destroy -auto-approve, but this did not result in destroying the resources, probably because I'm using local tf state which is cleaned up after every run.

I sought a TF CLI command that does an unconditional cleanup, regardless of state. The way to do this appears to be to use the -replace= option in the terraform plan creation:

https://www.terraform.io/docs/cli/commands/plan.html#replace-address

FWIW, applying a plan created with -replace doesn't either result in unconditionally deleting my resources as advertised. Note: this is not a situation where shared external state is useful, bc in my case the resources in question are solely owned and operated by the CI system, not humans, so there is no potential for concurrent TF runs conflicting.

Am I misinterpreting -replace here? Perhaps even -replace is ineffectual bc I'm not using a persistent state? Is there no way to tell terraform to unconditionally, blindly, delete resources?

UPDATE: I believe my problem here went away once I changed by Jenkins job config to NOT wipe the workspace directory between each build. This serves the purpose of persisting the local tf state file each run. We will eventually shift this to using remote state, but for now this is unnecessary since this infra is isolated in a test environment and understood in the org that it is not for human use other than intermittent ad-hoc testing in conjunction with CI.