diff --git a/terraform/context.go b/terraform/context.go index d912aa9b3..dcf72bb2c 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -1,6 +1,7 @@ package terraform import ( + "fmt" "sync" "github.com/hashicorp/go-multierror" @@ -112,6 +113,7 @@ func (c *Context2) Apply() (*State, error) { // Clean out any unused things c.state.prune() + println(fmt.Sprintf("%#v", c.state)) return c.state, err } diff --git a/terraform/context_test.go b/terraform/context_test.go index ccd304eb9..66b588a7d 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -3473,8 +3473,7 @@ func TestContext2Apply_error_createBeforeDestroy(t *testing.T) { } } -/* -func TestContextApply_errorDestroy_createBeforeDestroy(t *testing.T) { +func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) { m := testModule(t, "apply-error-create-before") p := testProvider("aws") state := &State{ @@ -3495,7 +3494,7 @@ func TestContextApply_errorDestroy_createBeforeDestroy(t *testing.T) { }, }, } - ctx := testContext(t, &ContextOpts{ + ctx := testContext2(t, &ContextOpts{ Module: m, Providers: map[string]ResourceProviderFactory{ "aws": testProviderFuncFixed(p), @@ -3531,7 +3530,6 @@ func TestContextApply_errorDestroy_createBeforeDestroy(t *testing.T) { t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected) } } -*/ func TestContext2Apply_provisionerResourceRef(t *testing.T) { m := testModule(t, "apply-provisioner-resource-ref") diff --git a/terraform/eval_state.go b/terraform/eval_state.go index cf315dade..fa664e211 100644 --- a/terraform/eval_state.go +++ b/terraform/eval_state.go @@ -43,8 +43,16 @@ func (n *EvalReadState) Eval( // Return the primary result = rs.Primary } else { - // Return the proper tainted resource - result = rs.Tainted[n.TaintedIndex] + // Get the index. If it is negative, then we get the last one + idx := n.TaintedIndex + if idx < 0 { + idx = len(rs.Tainted) - 1 + } + + if idx < len(rs.Tainted) { + // Return the proper tainted resource + result = rs.Tainted[n.TaintedIndex] + } } // Write the result to the output pointer @@ -103,8 +111,6 @@ func (n *EvalWriteState) Eval( rs.Type = n.ResourceType rs.Dependencies = n.Dependencies - println(fmt.Sprintf("%#v", rs)) - println(fmt.Sprintf("%#v", *n.State)) if n.Tainted != nil && *n.Tainted { if n.TaintedIndex != -1 { rs.Tainted[n.TaintedIndex] = *n.State @@ -119,9 +125,8 @@ func (n *EvalWriteState) Eval( // Set the primary state rs.Primary = *n.State } + println(fmt.Sprintf("%#v", rs)) - // Prune because why not, we can clear out old useless entries now - rs.prune() return nil, nil } @@ -216,7 +221,6 @@ func (n *EvalUndeposeState) Eval( idx := len(rs.Tainted) - 1 rs.Primary = rs.Tainted[idx] rs.Tainted[idx] = nil - rs.Tainted = rs.Tainted[:idx] return nil, nil } diff --git a/terraform/state.go b/terraform/state.go index 2d1f95d84..22a0935b7 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -373,6 +373,7 @@ func (m *ModuleState) deepcopy() *ModuleState { func (m *ModuleState) prune() { for k, v := range m.Resources { v.prune() + if (v.Primary == nil || v.Primary.ID == "") && len(v.Tainted) == 0 { delete(m.Resources, k) } @@ -554,8 +555,10 @@ func (r *ResourceState) prune() { copy(r.Tainted[i:], r.Tainted[i+1:]) r.Tainted[n-1] = nil n-- + i-- } } + r.Tainted = r.Tainted[:n] } diff --git a/terraform/transform_resource.go b/terraform/transform_resource.go index dfa06b913..30143e961 100644 --- a/terraform/transform_resource.go +++ b/terraform/transform_resource.go @@ -315,8 +315,11 @@ func (n *graphNodeExpandedResource) EvalTree() EvalNode { }, &EvalIf{ If: func(ctx EvalContext) (bool, error) { + if n.Resource.Lifecycle.CreateBeforeDestroy { + tainted = err != nil + } + failure := tainted || err != nil - tainted = n.Resource.Lifecycle.CreateBeforeDestroy return n.Resource.Lifecycle.CreateBeforeDestroy && failure, nil }, Node: &EvalUndeposeState{