From 33d7c1e6d652d092318a3509972c121a1a7565f5 Mon Sep 17 00:00:00 2001 From: Chris Arcand Date: Fri, 19 Nov 2021 11:54:06 -0600 Subject: [PATCH 1/2] command/init: Add -cloud alias (of -backend) This fixes an issue where a user could not disable initialization of the 'cloud' configuration block (As is possible with -backend=false), as well as add some syntactic sugar around -backend by adding a mutually exclusive -cloud alias. --- internal/command/arguments/flags.go | 11 +++++++++++ internal/command/init.go | 27 +++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/internal/command/arguments/flags.go b/internal/command/arguments/flags.go index d36486d94..ae47bc6e0 100644 --- a/internal/command/arguments/flags.go +++ b/internal/command/arguments/flags.go @@ -84,3 +84,14 @@ type FlagNameValue struct { func (f FlagNameValue) String() string { return fmt.Sprintf("%s=%q", f.Name, f.Value) } + +// FlagIsSet returns whether a flag is explicitly set in a set of flags +func FlagIsSet(flags *flag.FlagSet, name string) bool { + isSet := false + flags.Visit(func(f *flag.Flag) { + if f.Name == name { + isSet = true + } + }) + return isSet +} diff --git a/internal/command/init.go b/internal/command/init.go index ac411e891..2ec671130 100644 --- a/internal/command/init.go +++ b/internal/command/init.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/terraform/internal/backend" backendInit "github.com/hashicorp/terraform/internal/backend/init" "github.com/hashicorp/terraform/internal/cloud" + "github.com/hashicorp/terraform/internal/command/arguments" "github.com/hashicorp/terraform/internal/configs" "github.com/hashicorp/terraform/internal/configs/configschema" "github.com/hashicorp/terraform/internal/getproviders" @@ -34,13 +35,14 @@ type InitCommand struct { func (c *InitCommand) Run(args []string) int { var flagFromModule, flagLockfile string - var flagBackend, flagGet, flagUpgrade bool + var flagBackend, flagCloud, flagGet, flagUpgrade bool var flagPluginPath FlagStringSlice flagConfigExtra := newRawFlags("-backend-config") args = c.Meta.process(args) cmdFlags := c.Meta.extendedFlagSet("init") cmdFlags.BoolVar(&flagBackend, "backend", true, "") + cmdFlags.BoolVar(&flagCloud, "cloud", true, "") cmdFlags.Var(flagConfigExtra, "backend-config", "") cmdFlags.StringVar(&flagFromModule, "from-module", "", "copy the source of the given module into the directory before init") cmdFlags.BoolVar(&flagGet, "get", true, "") @@ -58,6 +60,19 @@ func (c *InitCommand) Run(args []string) int { return 1 } + backendFlagSet := arguments.FlagIsSet(cmdFlags, "backend") + cloudFlagSet := arguments.FlagIsSet(cmdFlags, "cloud") + + switch { + case backendFlagSet && cloudFlagSet: + c.Ui.Error("The -backend and -cloud options are aliases of one another and mutually-exclusive in their use") + return 1 + case backendFlagSet: + flagCloud = flagBackend + case cloudFlagSet: + flagBackend = flagCloud + } + if c.migrateState && c.reconfigure { c.Ui.Error("The -migrate-state and -reconfigure options are mutually-exclusive") return 1 @@ -212,7 +227,7 @@ func (c *InitCommand) Run(args []string) int { var back backend.Backend switch { - case config.Module.CloudConfig != nil: + case flagCloud && config.Module.CloudConfig != nil: be, backendOutput, backendDiags := c.initCloud(config.Module, flagConfigExtra) diags = diags.Append(backendDiags) if backendDiags.HasErrors() { @@ -992,6 +1007,7 @@ func (c *InitCommand) AutocompleteArgs() complete.Predictor { func (c *InitCommand) AutocompleteFlags() complete.Flags { return complete.Flags{ "-backend": completePredictBoolean, + "-cloud": completePredictBoolean, "-backend-config": complete.PredictFiles("*.tfvars"), // can also be key=value, but we can't "predict" that "-force-copy": complete.PredictNothing, "-from-module": completePredictModuleSource, @@ -1026,8 +1042,11 @@ Usage: terraform [global options] init [options] Options: - -backend=false Disable backend initialization for this configuration - and use the previously initialized backend instead. + -backend=false Disable backend or Terraform Cloud initialization for + this configuration and use what what was previously + initialized instead. + + aliases: -cloud=false -backend-config=path This can be either a path to an HCL file with key/value assignments (same format as terraform.tfvars) or a From a0c7c1dc8d1773f55a70a2acbe2f966e1e1057bc Mon Sep 17 00:00:00 2001 From: Chris Arcand Date: Fri, 19 Nov 2021 13:53:09 -0600 Subject: [PATCH 2/2] command/init: Adjust init help output Some of the wording here needed adjusting with the change that backends largely reflect state snapshot storage (removing 'enhanced' designation), and that a 'backend' is not necessarily always present. --- internal/command/init.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/command/init.go b/internal/command/init.go index 2ec671130..f10779a68 100644 --- a/internal/command/init.go +++ b/internal/command/init.go @@ -1048,14 +1048,16 @@ Options: aliases: -cloud=false - -backend-config=path This can be either a path to an HCL file with key/value + -backend-config=path Configuration to be merged with what is in the + configuration file's 'backend' block. This can be + either a path to an HCL file with key/value assignments (same format as terraform.tfvars) or a - 'key=value' format. This is merged with what is in the - configuration file. This can be specified multiple + 'key=value' format, and can be specified multiple times. The backend type must be in the configuration itself. - -force-copy Suppress prompts about copying state data. This is + -force-copy Suppress prompts about copying state data when + initializating a new state backend. This is equivalent to providing a "yes" to all confirmation prompts. @@ -1064,9 +1066,9 @@ Options: -get=false Disable downloading modules for this configuration. - -input=false Disable prompting for missing backend configuration - values. This will result in an error if the backend - configuration is not fully specified. + -input=false Disable interactive prompts. Note that some actions may + require interactive prompts and will error if input is + disabled. -lock=false Don't hold a state lock during backend migration. This is dangerous if others might concurrently run @@ -1081,10 +1083,10 @@ Options: automatic installation of plugins. This flag can be used multiple times. - -reconfigure Reconfigure the backend, ignoring any saved + -reconfigure Reconfigure a backend, ignoring any saved configuration. - -migrate-state Reconfigure the backend, and attempt to migrate any + -migrate-state Reconfigure a backend, and attempt to migrate any existing state. -upgrade Install the latest module and provider versions @@ -1095,8 +1097,12 @@ Options: -lockfile=MODE Set a dependency lockfile mode. Currently only "readonly" is valid. - -ignore-remote-version A rare option used for the remote backend only. See - the remote backend documentation for more information. + -ignore-remote-version A rare option used for Terraform Cloud and the remote backend + only. Set this to ignore checking that the local and remote + Terraform versions use compatible state representations, making + an operation proceed even when there is a potential mismatch. + See the documentation on configuring Terraform with + Terraform Cloud for more information. ` return strings.TrimSpace(helpText)