diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 5ea108380d21..af747c17c98f 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -3469,6 +3469,7 @@ func TestSchemaMap_Validate(t *testing.T) { }, Err: true, }, + "ValidateFunc gets decoded type": { Schema: map[string]*Schema{ "maybe": &Schema{ @@ -3486,6 +3487,27 @@ func TestSchemaMap_Validate(t *testing.T) { "maybe": "true", }, }, + + "ValidateFunc is not called with a computed value": { + Schema: map[string]*Schema{ + "validate_me": &Schema{ + Type: TypeString, + Required: true, + ValidateFunc: func(v interface{}) (ws []string, es []error) { + es = append(es, fmt.Errorf("something is not right here")) + return + }, + }, + }, + Config: map[string]interface{}{ + "validate_me": "${var.foo}", + }, + Vars: map[string]string{ + "var.foo": config.UnknownVariableValue, + }, + + Err: false, + }, } for tn, tc := range cases { diff --git a/terraform/context_test.go b/terraform/context_test.go index 6275fd8d703e..db16e4e0894d 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -2447,6 +2447,38 @@ func TestContext2Validate_badVar(t *testing.T) { } } +func TestContext2Validate_computedVar(t *testing.T) { + p := testProvider("aws") + m := testModule(t, "validate-computed-var") + c := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + "test": testProviderFuncFixed(testProvider("test")), + }, + }) + + p.ValidateFn = func(c *ResourceConfig) ([]string, []error) { + if !c.IsComputed("value") { + return nil, []error{fmt.Errorf("value isn't computed")} + } + + return nil, c.CheckSet([]string{"value"}) + } + + p.ConfigureFn = func(c *ResourceConfig) error { + return fmt.Errorf("Configure should not be called for provider") + } + + w, e := c.Validate() + if len(w) > 0 { + t.Fatalf("bad: %#v", w) + } + if len(e) > 0 { + t.Fatalf("bad: %#v", e) + } +} + func TestContext2Validate_countNegative(t *testing.T) { p := testProvider("aws") m := testModule(t, "validate-count-negative") @@ -4583,6 +4615,49 @@ func TestContext2Apply_outputOrphan(t *testing.T) { } } +func TestContext2Apply_providerComputedVar(t *testing.T) { + m := testModule(t, "apply-provider-computed") + p := testProvider("aws") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + + pTest := testProvider("test") + pTest.ApplyFn = testApplyFn + pTest.DiffFn = testDiffFn + + ctx := testContext2(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + "test": testProviderFuncFixed(pTest), + }, + }) + + p.ConfigureFn = func(c *ResourceConfig) error { + if c.IsComputed("value") { + return fmt.Errorf("value is computed") + } + + v, ok := c.Get("value") + if !ok { + return fmt.Errorf("value is not found") + } + if v != "yes" { + return fmt.Errorf("value is not 'yes': %v", v) + } + + return nil + } + + if _, err := ctx.Plan(); err != nil { + t.Fatalf("err: %s", err) + } + + if _, err := ctx.Apply(); err != nil { + t.Fatalf("err: %s", err) + } +} + func TestContext2Apply_Provisioner_compute(t *testing.T) { m := testModule(t, "apply-provisioner-compute") p := testProvider("aws") diff --git a/terraform/evaltree_provider.go b/terraform/evaltree_provider.go index 6b26d43e9597..1910bc0913b1 100644 --- a/terraform/evaltree_provider.go +++ b/terraform/evaltree_provider.go @@ -62,6 +62,20 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode { Provider: &provider, Config: &resourceConfig, }, + &EvalSetProviderConfig{ + Provider: n, + Config: &resourceConfig, + }, + }, + }, + }) + + // We configure on everything but validate, since validate may + // not have access to all the variables. + seq = append(seq, &EvalOpFilter{ + Ops: []walkOperation{walkRefresh, walkPlan, walkApply}, + Node: &EvalSequence{ + Nodes: []EvalNode{ &EvalConfigProvider{ Provider: n, Config: &resourceConfig, diff --git a/terraform/test-fixtures/apply-provider-computed/main.tf b/terraform/test-fixtures/apply-provider-computed/main.tf new file mode 100644 index 000000000000..4a39bb5461ae --- /dev/null +++ b/terraform/test-fixtures/apply-provider-computed/main.tf @@ -0,0 +1,9 @@ +provider "aws" { + value = "${test_instance.foo.value}" +} + +resource "aws_instance" "bar" {} + +resource "test_instance" "foo" { + value = "yes" +} diff --git a/terraform/test-fixtures/validate-computed-var/main.tf b/terraform/test-fixtures/validate-computed-var/main.tf new file mode 100644 index 000000000000..4a39bb5461ae --- /dev/null +++ b/terraform/test-fixtures/validate-computed-var/main.tf @@ -0,0 +1,9 @@ +provider "aws" { + value = "${test_instance.foo.value}" +} + +resource "aws_instance" "bar" {} + +resource "test_instance" "foo" { + value = "yes" +}