From 808f09f01f28332e64949f407cf57cb12caf1d42 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 9 Dec 2016 15:58:24 -0500 Subject: [PATCH] terraform: user friendly error when using old map overrides Related to #8036 We have had this behavior for a _long_ time now (since 0.7.0) but it seems people are still periodically getting bit by it. This adds an explicit error message that explains that this kind of override isn't allowed anymore. --- terraform/context_validate_test.go | 22 +++++++++++++++++++ terraform/semantics.go | 16 ++++++++++++++ terraform/semantics_test.go | 2 +- .../validate-var-map-override-old/main.tf | 1 + 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 terraform/test-fixtures/validate-var-map-override-old/main.tf diff --git a/terraform/context_validate_test.go b/terraform/context_validate_test.go index 131955df3..9e434a7be 100644 --- a/terraform/context_validate_test.go +++ b/terraform/context_validate_test.go @@ -44,6 +44,28 @@ func TestContext2Validate_badVar(t *testing.T) { } } +func TestContext2Validate_varMapOverrideOld(t *testing.T) { + m := testModule(t, "validate-module-pc-vars") + p := testProvider("aws") + c := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + Variables: map[string]interface{}{ + "foo.foo": "bar", + }, + }) + + w, e := c.Validate() + if len(w) > 0 { + t.Fatalf("bad: %#v", w) + } + if len(e) == 0 { + t.Fatalf("bad: %s", e) + } +} + func TestContext2Validate_varNoDefaultExplicitType(t *testing.T) { m := testModule(t, "validate-var-no-default-explicit-type") c := testContext2(t, &ContextOpts{ diff --git a/terraform/semantics.go b/terraform/semantics.go index 80ca636a8..6d99875cd 100644 --- a/terraform/semantics.go +++ b/terraform/semantics.go @@ -2,6 +2,7 @@ package terraform import ( "fmt" + "strings" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform/config" @@ -96,6 +97,21 @@ func smcUserVariables(c *config.Config, vs map[string]interface{}) []error { // Check that types match up for name, proposedValue := range vs { + // Check for "map.key" fields. These stopped working with Terraform + // 0.7 but we do this to surface a better error message informing + // the user what happened. + if idx := strings.Index(name, "."); idx > 0 { + key := name[:idx] + if _, ok := cvs[key]; ok { + errs = append(errs, fmt.Errorf( + "%s: Overriding map keys with the format `name.key` is no "+ + "longer allowed. You may still override keys by setting "+ + "`name = { key = value }`. The maps will be merged. This "+ + "behavior appeared in 0.7.0.", name)) + continue + } + } + schema, ok := cvs[name] if !ok { continue diff --git a/terraform/semantics_test.go b/terraform/semantics_test.go index f40f2af69..9a37decd9 100644 --- a/terraform/semantics_test.go +++ b/terraform/semantics_test.go @@ -24,7 +24,7 @@ func TestSMCUserVariables(t *testing.T) { "foo": "bar", "map.foo": "baz", }) - if len(errs) != 0 { + if len(errs) == 0 { t.Fatalf("err: %#v", errs) } diff --git a/terraform/test-fixtures/validate-var-map-override-old/main.tf b/terraform/test-fixtures/validate-var-map-override-old/main.tf new file mode 100644 index 000000000..7fe646c8b --- /dev/null +++ b/terraform/test-fixtures/validate-var-map-override-old/main.tf @@ -0,0 +1 @@ +variable "foo" { default = { foo = "bar" } }