From f5da7e85c89f1b02aa06e4dd03172e63707f73a6 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 11 Nov 2016 11:02:49 -0800 Subject: [PATCH] terraform: detect compute counts and show a nicer error This will detect computed counts (which we don't currently support) and change the error to be more informative that we don't allow computed counts. Prior to this, the error would instead be something like `strconv.ParseInt: "${var.foo}" cannot be parsed as int`. --- terraform/context_plan_test.go | 20 +++++++++++++++ terraform/eval_count_computed.go | 25 +++++++++++++++++++ terraform/graph_config_node_resource.go | 1 + terraform/node_resource_plan.go | 1 + .../plan-count-computed-module/child/main.tf | 5 ++++ .../plan-count-computed-module/main.tf | 8 ++++++ 6 files changed, 60 insertions(+) create mode 100644 terraform/eval_count_computed.go create mode 100644 terraform/test-fixtures/plan-count-computed-module/child/main.tf create mode 100644 terraform/test-fixtures/plan-count-computed-module/main.tf diff --git a/terraform/context_plan_test.go b/terraform/context_plan_test.go index f2b473623..dc6af4acb 100644 --- a/terraform/context_plan_test.go +++ b/terraform/context_plan_test.go @@ -1309,6 +1309,26 @@ func TestContext2Plan_countComputed(t *testing.T) { } } +func TestContext2Plan_countComputedModule(t *testing.T) { + m := testModule(t, "plan-count-computed-module") + p := testProvider("aws") + p.DiffFn = testDiffFn + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + }) + + _, err := ctx.Plan() + + expectedErr := "aws_instance.bar: value of 'count'" + if !strings.Contains(fmt.Sprintf("%s", err), expectedErr) { + t.Fatalf("expected err would contain %q\nerr: %s\n", + expectedErr, err) + } +} + func TestContext2Plan_countIndex(t *testing.T) { m := testModule(t, "plan-count-index") p := testProvider("aws") diff --git a/terraform/eval_count_computed.go b/terraform/eval_count_computed.go new file mode 100644 index 000000000..54a8333e0 --- /dev/null +++ b/terraform/eval_count_computed.go @@ -0,0 +1,25 @@ +package terraform + +import ( + "fmt" + + "github.com/hashicorp/terraform/config" +) + +// EvalCountCheckComputed is an EvalNode that checks if a resource count +// is computed and errors if so. This can possibly happen across a +// module boundary and we don't yet support this. +type EvalCountCheckComputed struct { + Resource *config.Resource +} + +// TODO: test +func (n *EvalCountCheckComputed) Eval(ctx EvalContext) (interface{}, error) { + if n.Resource.RawCount.Value() == unknownValue() { + return nil, fmt.Errorf( + "%s: value of 'count' cannot be computed", + n.Resource.Id()) + } + + return nil, nil +} diff --git a/terraform/graph_config_node_resource.go b/terraform/graph_config_node_resource.go index db4e6626c..b160f6ddd 100644 --- a/terraform/graph_config_node_resource.go +++ b/terraform/graph_config_node_resource.go @@ -215,6 +215,7 @@ func (n *GraphNodeConfigResource) EvalTree() EvalNode { return &EvalSequence{ Nodes: []EvalNode{ &EvalInterpolate{Config: n.Resource.RawCount}, + &EvalCountCheckComputed{Resource: n.Resource}, &EvalOpFilter{ Ops: []walkOperation{walkValidate}, Node: &EvalValidateCount{Resource: n.Resource}, diff --git a/terraform/node_resource_plan.go b/terraform/node_resource_plan.go index c9e53e02c..dc5f653b8 100644 --- a/terraform/node_resource_plan.go +++ b/terraform/node_resource_plan.go @@ -31,6 +31,7 @@ func (n *NodePlannableResource) EvalTree() EvalNode { // into the proper number of instances. &EvalInterpolate{Config: n.Config.RawCount}, + &EvalCountCheckComputed{Resource: n.Config}, &EvalCountFixZeroOneBoundary{Resource: n.Config}, }, } diff --git a/terraform/test-fixtures/plan-count-computed-module/child/main.tf b/terraform/test-fixtures/plan-count-computed-module/child/main.tf new file mode 100644 index 000000000..f80d699d9 --- /dev/null +++ b/terraform/test-fixtures/plan-count-computed-module/child/main.tf @@ -0,0 +1,5 @@ +variable "value" {} + +resource "aws_instance" "bar" { + count = "${var.value}" +} diff --git a/terraform/test-fixtures/plan-count-computed-module/main.tf b/terraform/test-fixtures/plan-count-computed-module/main.tf new file mode 100644 index 000000000..c87beb5f8 --- /dev/null +++ b/terraform/test-fixtures/plan-count-computed-module/main.tf @@ -0,0 +1,8 @@ +resource "aws_instance" "foo" { + compute = "foo" +} + +module "child" { + source = "./child" + value = "${aws_instance.foo.foo}" +}