Skip to content

Commit 435d8bd

Browse files
authored
Merge pull request #26343 from hashicorp/jbardin/update-cbd-state
Update create_before_destroy in state during refresh
2 parents 014bd30 + a0cee10 commit 435d8bd

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

terraform/context_refresh_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,3 +1689,56 @@ aws_instance.foo:
16891689

16901690
checkStateString(t, result, expect)
16911691
}
1692+
1693+
// verify that create_before_destroy is updated in the state during refresh
1694+
func TestRefresh_updateLifecycle(t *testing.T) {
1695+
state := states.NewState()
1696+
root := state.EnsureModule(addrs.RootModuleInstance)
1697+
root.SetResourceInstanceCurrent(
1698+
addrs.Resource{
1699+
Mode: addrs.ManagedResourceMode,
1700+
Type: "aws_instance",
1701+
Name: "bar",
1702+
}.Instance(addrs.NoKey),
1703+
&states.ResourceInstanceObjectSrc{
1704+
Status: states.ObjectReady,
1705+
AttrsJSON: []byte(`{"id":"bar"}`),
1706+
},
1707+
addrs.AbsProviderConfig{
1708+
Provider: addrs.NewDefaultProvider("aws"),
1709+
Module: addrs.RootModule,
1710+
},
1711+
)
1712+
1713+
m := testModuleInline(t, map[string]string{
1714+
"main.tf": `
1715+
resource "aws_instance" "bar" {
1716+
lifecycle {
1717+
create_before_destroy = true
1718+
}
1719+
}
1720+
`,
1721+
})
1722+
1723+
p := testProvider("aws")
1724+
p.ApplyFn = testApplyFn
1725+
p.DiffFn = testDiffFn
1726+
1727+
ctx := testContext2(t, &ContextOpts{
1728+
Config: m,
1729+
Providers: map[addrs.Provider]providers.Factory{
1730+
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
1731+
},
1732+
State: state,
1733+
})
1734+
1735+
state, diags := ctx.Refresh()
1736+
if diags.HasErrors() {
1737+
t.Fatalf("plan errors: %s", diags.Err())
1738+
}
1739+
1740+
r := state.ResourceInstance(mustResourceInstanceAddr("aws_instance.bar"))
1741+
if !r.Current.CreateBeforeDestroy {
1742+
t.Fatal("create_before_destroy not updated in instance state")
1743+
}
1744+
}

terraform/eval_state.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,36 @@ func (n *EvalWriteResourceState) Eval(ctx EvalContext) (interface{}, error) {
529529

530530
return nil, nil
531531
}
532+
533+
// EvalRefreshLifecycle is an EvalNode implementation that updates
534+
// the status of the lifecycle options stored in the state.
535+
// This currently only applies to create_before_destroy.
536+
type EvalRefreshLifecycle struct {
537+
Addr addrs.AbsResourceInstance
538+
539+
Config *configs.Resource
540+
// Prior State
541+
State **states.ResourceInstanceObject
542+
// ForceCreateBeforeDestroy indicates a create_before_destroy resource
543+
// depends on this resource.
544+
ForceCreateBeforeDestroy bool
545+
}
546+
547+
func (n *EvalRefreshLifecycle) Eval(ctx EvalContext) (interface{}, error) {
548+
state := *n.State
549+
if state == nil {
550+
// no existing state
551+
return nil, nil
552+
}
553+
554+
// In 0.13 we could be refreshing a resource with no config.
555+
// We should be operating on managed resource, but check here to be certain
556+
if n.Config == nil || n.Config.Managed == nil {
557+
log.Printf("[WARN] EvalRefreshLifecycle: no Managed config value found in instance state for %q", n.Addr)
558+
return nil, nil
559+
}
560+
561+
state.CreateBeforeDestroy = n.Config.Managed.CreateBeforeDestroy || n.ForceCreateBeforeDestroy
562+
563+
return nil, nil
564+
}

terraform/node_resource_plan_instance.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ func (n *NodePlannableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
148148
ProviderSchema: &providerSchema,
149149
Output: &instanceRefreshState,
150150
},
151+
&EvalRefreshLifecycle{
152+
Addr: addr,
153+
Config: n.Config,
154+
State: &instanceRefreshState,
155+
ForceCreateBeforeDestroy: n.ForceCreateBeforeDestroy,
156+
},
151157
&EvalRefresh{
152158
Addr: addr.Resource,
153159
ProviderAddr: n.ResolvedProvider,

0 commit comments

Comments
 (0)