From c70954aeabfd5c084f9f15d017e141f9aa1498b7 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 23 Jan 2019 14:16:52 -0800 Subject: [PATCH] tools/terraform-bundle: refuse to bundle versions <0.12.0 Since terraform-bundle is just a different frontend to Terraform's module installer, it is subject to the same installation constraints as Terraform itself. Terraform 0.12 cannot install providers targeting Terraform 0.11 and earlier, and so therefore terraform-bundle built with Terraform 0.12 cannot either. A build of terraform-bundle from the v0.11 line must be used instead. Without this change, the latest revisions of terraform-bundle would install plugins for Terraform 0.12 to bundle along with Terraform 0.10 or 0.11, which will not work at runtime due to the plugin protocol mismatch. Until now, terraform-bundle was incorrectly labelled with its own version number even though in practice it has no version identity separate from Terraform itself. Part of this change, then, is to make the terraform-bundle version match the Terraform version it was built against, though any prior builds will of course continue to refer to themselves as 0.0.1. If asked to create a bundle for a version of Terraform v0.12 or greater, an error will be returned instructing the user to use a build from the v0.11 branch or one of the v0.11.x tags in order to bundle those versions. This also includes a small fix for a bug where the tool would not fail properly when the requested Terraform version is not available for installation, instead just producing a zip file with no "terraform" executable inside at all. Now it will fail, allowing automated build processes to detect it and not produce a broken archive for distribution. --- tools/terraform-bundle/README.md | 9 +++++++++ tools/terraform-bundle/config.go | 9 ++++++++- tools/terraform-bundle/main.go | 8 +++----- tools/terraform-bundle/package.go | 1 + 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tools/terraform-bundle/README.md b/tools/terraform-bundle/README.md index 5d6bf103b..a75fa7726 100644 --- a/tools/terraform-bundle/README.md +++ b/tools/terraform-bundle/README.md @@ -32,6 +32,15 @@ $ go install ./tools/terraform-bundle This will install `terraform-bundle` in `$GOPATH/bin`, which is assumed by the rest of this README to be in `PATH`. +`terraform-bundle` is a repackaging of the module installation functionality +from Terraform itself, so for best results you should build from the tag +relating to the version of Terraform you plan to use. There is some slack in +this requirement due to the fact that the module installation behavior changes +rarely, but please note that in particular bundles for versions of +Terraform before v0.12 must be built from a `terraform-bundle` built against +a Terraform v0.11 tag at the latest, since Terraform v0.12 installs plugins +in a different way that is not compatible. + ## Usage `terraform-bundle` uses a simple configuration file to define what should diff --git a/tools/terraform-bundle/config.go b/tools/terraform-bundle/config.go index 8f493e0c5..df67c5bcc 100644 --- a/tools/terraform-bundle/config.go +++ b/tools/terraform-bundle/config.go @@ -8,6 +8,8 @@ import ( "github.com/hashicorp/terraform/plugin/discovery" ) +var zeroTwelve = discovery.ConstraintStr(">= 0.12.0").MustParse() + type Config struct { Terraform TerraformConfig `hcl:"terraform"` Providers map[string][]discovery.ConstraintStr `hcl:"providers"` @@ -42,9 +44,14 @@ func (c *Config) validate() error { return fmt.Errorf("terraform.version is required") } - if _, err := c.Terraform.Version.Parse(); err != nil { + var v discovery.Version + var err error + if v, err = c.Terraform.Version.Parse(); err != nil { return fmt.Errorf("terraform.version: %s", err) } + if !zeroTwelve.Allows(v) { + return fmt.Errorf("this version of terraform-bundle can only build bundles for Terraform v0.12 and later; build terraform-bundle from the v0.11 branch or a v0.11.* tag to construct bundles for earlier versions") + } if c.Providers == nil { c.Providers = map[string][]discovery.ConstraintStr{} diff --git a/tools/terraform-bundle/main.go b/tools/terraform-bundle/main.go index 6556c5a75..1e1ba08f8 100644 --- a/tools/terraform-bundle/main.go +++ b/tools/terraform-bundle/main.go @@ -33,16 +33,14 @@ package main import ( + "io/ioutil" "log" "os" - "io/ioutil" - + tfversion "github.com/hashicorp/terraform/version" "github.com/mitchellh/cli" ) -const Version = "0.0.1" - func main() { ui := &cli.ColoredUi{ OutputColor: cli.UiColorNone, @@ -64,7 +62,7 @@ func main() { log.SetOutput(ioutil.Discard) } - c := cli.NewCLI("terraform-bundle", Version) + c := cli.NewCLI("terraform-bundle", tfversion.Version) c.Args = os.Args[1:] c.Commands = map[string]cli.CommandFactory{ "package": func() (cli.Command, error) { diff --git a/tools/terraform-bundle/package.go b/tools/terraform-bundle/package.go index 62ee497bd..62ebc8f7c 100644 --- a/tools/terraform-bundle/package.go +++ b/tools/terraform-bundle/package.go @@ -135,6 +135,7 @@ func (c *PackageCommand) Run(args []string) int { if err != nil { c.ui.Error(fmt.Sprintf("Failed to fetch core package from %s: %s", coreZipURL, err)) + return 1 } c.ui.Info(fmt.Sprintf("Fetching 3rd party plugins in directory: %s", pluginDir))