Refresh instances during plan

This change refreshes the instance state during plan, so a complete
Refresh no longer needs to happen before Plan.
This commit is contained in:
James Bardin 2020-07-27 16:35:55 -04:00
parent 02fb28eeae
commit be757bd416
3 changed files with 37 additions and 48 deletions

View File

@ -80,18 +80,6 @@ func (b *Local) opApply(
// If we weren't given a plan, then we refresh/plan // If we weren't given a plan, then we refresh/plan
if op.PlanFile == nil { if op.PlanFile == nil {
// If we're refreshing before apply, perform that
if op.PlanRefresh {
log.Printf("[INFO] backend/local: apply calling Refresh")
_, refreshDiags := tfCtx.Refresh()
diags = diags.Append(refreshDiags)
if diags.HasErrors() {
runningOp.Result = backend.OperationFailure
b.ShowDiagnostics(diags)
return
}
}
// Perform the plan // Perform the plan
log.Printf("[INFO] backend/local: apply calling Plan") log.Printf("[INFO] backend/local: apply calling Plan")
plan, planDiags := tfCtx.Plan() plan, planDiags := tfCtx.Plan()

View File

@ -97,27 +97,6 @@ func (b *Local) opPlan(
runningOp.State = tfCtx.State() runningOp.State = tfCtx.State()
// If we're refreshing before plan, perform that
baseState := runningOp.State
if op.PlanRefresh {
log.Printf("[INFO] backend/local: plan calling Refresh")
if b.CLI != nil {
b.CLI.Output(b.Colorize().Color(strings.TrimSpace(planRefreshing) + "\n"))
}
refreshedState, refreshDiags := tfCtx.Refresh()
diags = diags.Append(refreshDiags)
if diags.HasErrors() {
b.ReportResult(runningOp, diags)
return
}
baseState = refreshedState // plan will be relative to our refreshed state
if b.CLI != nil {
b.CLI.Output("\n------------------------------------------------------------------------")
}
}
// Perform the plan in a goroutine so we can be interrupted // Perform the plan in a goroutine so we can be interrupted
var plan *plans.Plan var plan *plans.Plan
var planDiags tfdiags.Diagnostics var planDiags tfdiags.Diagnostics
@ -142,6 +121,7 @@ func (b *Local) opPlan(
b.ReportResult(runningOp, diags) b.ReportResult(runningOp, diags)
return return
} }
// Record whether this plan includes any side-effects that could be applied. // Record whether this plan includes any side-effects that could be applied.
runningOp.PlanEmpty = !planHasSideEffects(priorState, plan.Changes) runningOp.PlanEmpty = !planHasSideEffects(priorState, plan.Changes)
@ -161,7 +141,7 @@ func (b *Local) opPlan(
// We may have updated the state in the refresh step above, but we // We may have updated the state in the refresh step above, but we
// will freeze that updated state in the plan file for now and // will freeze that updated state in the plan file for now and
// only write it if this plan is subsequently applied. // only write it if this plan is subsequently applied.
plannedStateFile := statemgr.PlannedStateUpdate(opState, baseState) plannedStateFile := statemgr.PlannedStateUpdate(opState, plan.State)
log.Printf("[INFO] backend/local: writing plan output to: %s", path) log.Printf("[INFO] backend/local: writing plan output to: %s", path)
err := planfile.Create(path, configSnap, plannedStateFile, plan) err := planfile.Create(path, configSnap, plannedStateFile, plan)
@ -187,7 +167,7 @@ func (b *Local) opPlan(
return return
} }
b.renderPlan(plan, baseState, priorState, schemas) b.renderPlan(plan, plan.State, priorState, schemas)
// If we've accumulated any warnings along the way then we'll show them // If we've accumulated any warnings along the way then we'll show them
// here just before we show the summary and next steps. If we encountered // here just before we show the summary and next steps. If we encountered

View File

@ -63,8 +63,7 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResou
Addr: addr.Resource, Addr: addr.Resource,
Provider: &provider, Provider: &provider,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
Output: &state,
Output: &state,
}, },
&EvalValidateSelfRef{ &EvalValidateSelfRef{
@ -108,7 +107,8 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
var provider providers.Interface var provider providers.Interface
var providerSchema *ProviderSchema var providerSchema *ProviderSchema
var change *plans.ResourceInstanceChange var change *plans.ResourceInstanceChange
var state *states.ResourceInstanceObject var refreshState *states.ResourceInstanceObject
var planState *states.ResourceInstanceObject
return &EvalSequence{ return &EvalSequence{
Nodes: []EvalNode{ Nodes: []EvalNode{
@ -118,19 +118,40 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
Schema: &providerSchema, Schema: &providerSchema,
}, },
&EvalReadState{
Addr: addr.Resource,
Provider: &provider,
ProviderSchema: &providerSchema,
Output: &state,
},
&EvalValidateSelfRef{ &EvalValidateSelfRef{
Addr: addr.Resource, Addr: addr.Resource,
Config: config.Config, Config: config.Config,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
}, },
// Refresh the instance
&EvalReadState{
Addr: addr.Resource,
Provider: &provider,
ProviderSchema: &providerSchema,
Output: &refreshState,
},
&EvalRefreshDependencies{
State: &refreshState,
Dependencies: &n.Dependencies,
},
&EvalRefresh{
Addr: addr.Resource,
ProviderAddr: n.ResolvedProvider,
Provider: &provider,
ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema,
State: &refreshState,
Output: &refreshState,
},
&EvalWriteState{
Addr: addr.Resource,
ProviderAddr: n.ResolvedProvider,
State: &refreshState,
ProviderSchema: &providerSchema,
},
// Plan the instance
&EvalDiff{ &EvalDiff{
Addr: addr.Resource, Addr: addr.Resource,
Config: n.Config, Config: n.Config,
@ -139,9 +160,9 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
ProviderMetas: n.ProviderMetas, ProviderMetas: n.ProviderMetas,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
State: &state, State: &refreshState,
OutputChange: &change, OutputChange: &change,
OutputState: &state, OutputState: &planState,
}, },
&EvalCheckPreventDestroy{ &EvalCheckPreventDestroy{
Addr: addr.Resource, Addr: addr.Resource,
@ -151,7 +172,7 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
&EvalWriteState{ &EvalWriteState{
Addr: addr.Resource, Addr: addr.Resource,
ProviderAddr: n.ResolvedProvider, ProviderAddr: n.ResolvedProvider,
State: &state, State: &planState,
ProviderSchema: &providerSchema, ProviderSchema: &providerSchema,
}, },
&EvalWriteDiff{ &EvalWriteDiff{