Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

applying a plan should use the refreshed state #15423

Merged
merged 1 commit into from
Jun 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/local/backend_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, state.State,
}

// Load our state
// By the time we get here, the backend creation code in "command" took
// care of making s.State() return a state compatible with our plan,
// if any, so we can safely pass this value in both the plan context
// and new context cases below.
opts.State = s.State()

// Build the context
Expand Down
21 changes: 19 additions & 2 deletions terraform/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,30 @@ type Plan struct {
// Context returns a Context with the data encapsulated in this plan.
//
// The following fields in opts are overridden by the plan: Config,
// Diff, State, Variables.
// Diff, Variables.
//
// If State is not provided, it is set from the plan. If it _is_ provided,
// it must be Equal to the state stored in plan, but may have a newer
// serial.
func (p *Plan) Context(opts *ContextOpts) (*Context, error) {
opts.Diff = p.Diff
opts.Module = p.Module
opts.State = p.State
opts.Targets = p.Targets

// If we are given a state in "base" then we'll use it, and otherwise
// we'll fall back on the state stashed in the plan. We do this because
// sometimes the caller has already persisted the plan's state by the
// time we get here, and we don't want to regress to the plan-time state
// serial if so.
if opts.State == nil {
opts.State = p.State
} else if !opts.State.Equal(p.State) {
// Even if we're overriding the state, it should be logically equal
// to what's in plan. The only valid change to have made by the time
// we get here is to have incremented the serial.
return nil, errors.New("plan state and ContextOpts state are not equal")
}

opts.Variables = make(map[string]interface{})
for k, v := range p.Vars {
opts.Variables[k] = v
Expand Down