diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index fdea4488e..6c9ed41ba 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -22,17 +22,18 @@ import ( // EvalApply is an EvalNode implementation that writes the diff to // the full diff. type EvalApply struct { - Addr addrs.ResourceInstance - Config *configs.Resource - State **states.ResourceInstanceObject - Change **plans.ResourceInstanceChange - ProviderAddr addrs.AbsProviderConfig - Provider *providers.Interface - ProviderMetas map[addrs.Provider]*configs.ProviderMeta - ProviderSchema **ProviderSchema - Output **states.ResourceInstanceObject - CreateNew *bool - Error *error + Addr addrs.ResourceInstance + Config *configs.Resource + State **states.ResourceInstanceObject + Change **plans.ResourceInstanceChange + ProviderAddr addrs.AbsProviderConfig + Provider *providers.Interface + ProviderMetas map[addrs.Provider]*configs.ProviderMeta + ProviderSchema **ProviderSchema + Output **states.ResourceInstanceObject + CreateNew *bool + Error *error + CreateBeforeDestroy bool } // TODO: test @@ -308,7 +309,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { Status: newStatus, Value: newVal, Private: resp.Private, - CreateBeforeDestroy: n.Config.Managed.CreateBeforeDestroy, + CreateBeforeDestroy: n.CreateBeforeDestroy, } } diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index 4162331df..d56291c19 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -119,6 +119,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { newState.Value = resp.NewState newState.Private = resp.Private newState.Dependencies = state.Dependencies + newState.CreateBeforeDestroy = state.CreateBeforeDestroy // Call post-refresh hook err = ctx.Hook(func(h Hook) (HookAction, error) { diff --git a/terraform/eval_state.go b/terraform/eval_state.go index cb0416c97..c19d37801 100644 --- a/terraform/eval_state.go +++ b/terraform/eval_state.go @@ -228,7 +228,6 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) { log.Printf("[TRACE] EvalWriteState: removing state object for %s", absAddr) return nil, nil } - fmt.Printf("OBJ: %#v\n", obj) // store the new deps in the state if n.Dependencies != nil { diff --git a/terraform/node_resource_apply_instance.go b/terraform/node_resource_apply_instance.go index 2a55f23a7..93aab7564 100644 --- a/terraform/node_resource_apply_instance.go +++ b/terraform/node_resource_apply_instance.go @@ -25,6 +25,10 @@ type NodeApplyableResourceInstance struct { destroyNode GraphNodeDestroyerCBD graphNodeDeposer // implementation of GraphNodeDeposerConfig + + // If this node is forced to be CreateBeforeDestroy, we need to record that + // in the state to. + ForceCreateBeforeDestroy bool } var ( @@ -42,20 +46,27 @@ func (n *NodeApplyableResourceInstance) AttachDestroyNode(d GraphNodeDestroyerCB n.destroyNode = d } -// createBeforeDestroy checks this nodes config status and the status af any +// CreateBeforeDestroy checks this nodes config status and the status af any // companion destroy node for CreateBeforeDestroy. -func (n *NodeApplyableResourceInstance) createBeforeDestroy() bool { - cbd := false +func (n *NodeApplyableResourceInstance) CreateBeforeDestroy() bool { + if n.ForceCreateBeforeDestroy { + return n.ForceCreateBeforeDestroy + } if n.Config != nil && n.Config.Managed != nil { - cbd = n.Config.Managed.CreateBeforeDestroy + return n.Config.Managed.CreateBeforeDestroy } if n.destroyNode != nil { - cbd = cbd || n.destroyNode.CreateBeforeDestroy() + return n.destroyNode.CreateBeforeDestroy() } - return cbd + return false +} + +func (n *NodeApplyableResourceInstance) ModifyCreateBeforeDestroy(v bool) error { + n.ForceCreateBeforeDestroy = v + return nil } // GraphNodeCreator @@ -78,7 +89,7 @@ func (n *NodeApplyableResourceInstance) References() []*addrs.Reference { // would create a dependency cycle. We make a compromise here of requiring // changes to be updated across two applies in this case, since the first // plan will use the old values. - if !n.createBeforeDestroy() { + if !n.CreateBeforeDestroy() { for _, ref := range ret { switch tr := ref.Subject.(type) { case addrs.ResourceInstance: @@ -254,7 +265,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe if diffApply != nil { destroy = (diffApply.Action == plans.Delete || diffApply.Action.IsReplace()) } - if destroy && n.createBeforeDestroy() { + if destroy && n.CreateBeforeDestroy() { createBeforeDestroyEnabled = true } return createBeforeDestroyEnabled, nil @@ -346,17 +357,18 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe Change: &diffApply, }, &EvalApply{ - Addr: addr.Resource, - Config: n.Config, - State: &state, - Change: &diffApply, - Provider: &provider, - ProviderAddr: n.ResolvedProvider, - ProviderMetas: n.ProviderMetas, - ProviderSchema: &providerSchema, - Output: &state, - Error: &err, - CreateNew: &createNew, + Addr: addr.Resource, + Config: n.Config, + State: &state, + Change: &diffApply, + Provider: &provider, + ProviderAddr: n.ResolvedProvider, + ProviderMetas: n.ProviderMetas, + ProviderSchema: &providerSchema, + Output: &state, + Error: &err, + CreateNew: &createNew, + CreateBeforeDestroy: n.CreateBeforeDestroy(), }, &EvalMaybeTainted{ Addr: addr.Resource, @@ -411,7 +423,7 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe if !diff.Action.IsReplace() { return true, nil } - if !n.createBeforeDestroy() { + if !n.CreateBeforeDestroy() { return true, nil } return false, nil