@@ -139,6 +139,12 @@ type PlanOpts struct {
139139 // Query is a boolean that indicates whether the plan is being
140140 // generated for a query operation.
141141 Query bool
142+
143+ // OverridePreventDestroy will override any prevent_destroy attributes
144+ // allowing Terraform to destroy resources even if the prevent_destroy
145+ // attribute is set. This can only be set during a destroy plan, and should
146+ // only be set during the test command.
147+ OverridePreventDestroy bool
142148}
143149
144150// Plan generates an execution plan by comparing the given configuration
@@ -513,6 +519,7 @@ func (c *Context) destroyPlan(config *configs.Config, prevRunState *states.State
513519 refreshOpts := * opts
514520 refreshOpts .Mode = plans .NormalMode
515521 refreshOpts .PreDestroyRefresh = true
522+ refreshOpts .OverridePreventDestroy = false
516523
517524 // FIXME: A normal plan is required here to refresh the state, because
518525 // the state and configuration may not match during a destroy, and a
@@ -912,6 +919,10 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State,
912919 externalProviderConfigs = opts .ExternalProviders
913920 }
914921
922+ if opts != nil && opts .OverridePreventDestroy && opts .Mode != plans .DestroyMode {
923+ panic ("you can only set OverridePreventDestroy during destroy operations." )
924+ }
925+
915926 switch mode := opts .Mode ; mode {
916927 case plans .NormalMode :
917928 // In Normal mode we need to pay attention to import and removed blocks
@@ -969,6 +980,7 @@ func (c *Context) planGraph(config *configs.Config, prevRunState *states.State,
969980 Operation : walkPlanDestroy ,
970981 Overrides : opts .Overrides ,
971982 SkipGraphValidation : c .graphOpts .SkipGraphValidation ,
983+ overridePreventDestroy : opts .OverridePreventDestroy ,
972984 }).Build (addrs .RootModuleInstance )
973985 return graph , walkPlanDestroy , diags
974986 default :
0 commit comments