diff --git a/plans/changes_sync.go b/plans/changes_sync.go index 10d7225c1..258869986 100644 --- a/plans/changes_sync.go +++ b/plans/changes_sync.go @@ -61,3 +61,29 @@ func (cs *ChangesSync) GetResourceInstanceChange(addr addrs.AbsResourceInstance, } panic(fmt.Sprintf("unsupported generation value %#v", gen)) } + +// RemoveResourceInstanceChange searches the set of resource instance changes +// for one matching the given address and generation, and removes it from the +// set if it exists. +func (cs *ChangesSync) RemoveResourceInstanceChange(addr addrs.AbsResourceInstance, gen states.Generation) { + if cs == nil { + panic("RemoveResourceInstanceChange on nil ChangesSync") + } + cs.lock.Lock() + defer cs.lock.Unlock() + + dk := states.NotDeposed + if realDK, ok := gen.(states.DeposedKey); ok { + dk = realDK + } + + addrStr := addr.String() + for i, r := range cs.changes.Resources { + if r.Addr.String() != addrStr || r.DeposedKey != dk { + continue + } + copy(cs.changes.Resources[i:], cs.changes.Resources[i+1:]) + cs.changes.Resources = cs.changes.Resources[:len(cs.changes.Resources)-1] + return + } +} diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index c96f98787..0599d2940 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -195,7 +195,12 @@ func (n *EvalApplyPost) Eval(ctx EvalContext) (interface{}, error) { if resourceHasUserVisibleApply(n.Addr) { absAddr := n.Addr.Absolute(ctx.Path()) - newState := state.Value + var newState cty.Value + if state != nil { + newState = state.Value + } else { + newState = cty.NullVal(cty.DynamicPseudoType) + } var err error if n.Error != nil { err = *n.Error diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index 87d2d54be..cd8178950 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -754,9 +754,21 @@ type EvalWriteDiff struct { // TODO: test func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) { + changes := ctx.Changes() + addr := n.Addr.Absolute(ctx.Path()) + if n.Change == nil || *n.Change == nil { + // Caller sets nil to indicate that we need to remove a change from + // the set of changes. + gen := states.CurrentGen + if n.DeposedKey != states.NotDeposed { + gen = n.DeposedKey + } + changes.RemoveResourceInstanceChange(addr, gen) + return nil, nil + } + providerSchema := *n.ProviderSchema change := *n.Change - addr := n.Addr.Absolute(ctx.Path()) if change.Addr.String() != n.Addr.String() || change.DeposedKey != n.DeposedKey { // Should never happen, and indicates a bug in the caller. @@ -774,7 +786,6 @@ func (n *EvalWriteDiff) Eval(ctx EvalContext) (interface{}, error) { return nil, fmt.Errorf("failed to encode planned changes for %s: %s", addr, err) } - changes := ctx.Changes() changes.AppendResourceInstanceChange(csrc) if n.DeposedKey == states.NotDeposed { log.Printf("[TRACE] EvalWriteDiff: recorded %s change for %s", change.Action, addr)