diff --git a/terraform/context.go b/terraform/context.go index 6f62e01e75..2575155c01 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -712,6 +712,11 @@ func (c *Context) validateWalkFn(rws *[]string, res *[]error) depgraph.WalkFunc return nil } + // Don't validate orphans since they never have a config + if rn.Orphan { + return nil + } + log.Printf("[INFO] Validating resource: %s", rn.Resource.Id) ws, es := rn.Resource.Provider.ValidateResource( rn.Type, rn.Resource.Config) diff --git a/terraform/context_test.go b/terraform/context_test.go index 314bf340a1..c785ce39cc 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -8,9 +8,13 @@ import ( ) func TestContextValidate(t *testing.T) { + p := testProvider("aws") config := testConfig(t, "validate-good") c := testContext(t, &ContextOpts{ Config: config, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, }) w, e := c.Validate() @@ -23,9 +27,13 @@ func TestContextValidate(t *testing.T) { } func TestContextValidate_badVar(t *testing.T) { + p := testProvider("aws") config := testConfig(t, "validate-bad-var") c := testContext(t, &ContextOpts{ Config: config, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, }) w, e := c.Validate() @@ -37,6 +45,39 @@ func TestContextValidate_badVar(t *testing.T) { } } +func TestContextValidate_orphans(t *testing.T) { + p := testProvider("aws") + config := testConfig(t, "validate-good") + state := &State{ + Resources: map[string]*ResourceState{ + "aws_instance.web": &ResourceState{ + ID: "bar", + Type: "aws_instance", + }, + }, + } + c := testContext(t, &ContextOpts{ + Config: config, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + State: state, + }) + + p.ValidateResourceFn = func( + t string, c *ResourceConfig) ([]string, []error) { + return nil, c.CheckSet([]string{"foo"}) + } + + w, e := c.Validate() + if len(w) > 0 { + t.Fatalf("bad: %#v", w) + } + if len(e) > 0 { + t.Fatalf("bad: %#v", e) + } +} + func TestContextValidate_providerConfig_bad(t *testing.T) { config := testConfig(t, "validate-bad-pc") p := testProvider("aws") diff --git a/terraform/resource_provider_mock.go b/terraform/resource_provider_mock.go index caf50861e8..42faada7c2 100644 --- a/terraform/resource_provider_mock.go +++ b/terraform/resource_provider_mock.go @@ -38,6 +38,7 @@ type MockResourceProvider struct { ValidateConfig *ResourceConfig ValidateReturnWarns []string ValidateReturnErrors []error + ValidateResourceFn func(string, *ResourceConfig) ([]string, []error) ValidateResourceCalled bool ValidateResourceType string ValidateResourceConfig *ResourceConfig @@ -61,6 +62,11 @@ func (p *MockResourceProvider) ValidateResource(t string, c *ResourceConfig) ([] p.ValidateResourceCalled = true p.ValidateResourceType = t p.ValidateResourceConfig = c + + if p.ValidateResourceFn != nil { + return p.ValidateResourceFn(t, c) + } + return p.ValidateResourceReturnWarns, p.ValidateResourceReturnErrors } diff --git a/terraform/test-fixtures/validate-good/main.tf b/terraform/test-fixtures/validate-good/main.tf index ce56544419..f9aa393caf 100644 --- a/terraform/test-fixtures/validate-good/main.tf +++ b/terraform/test-fixtures/validate-good/main.tf @@ -1,5 +1,6 @@ resource "aws_instance" "foo" { num = "2" + foo = "bar" } resource "aws_instance" "bar" {