diff --git a/internal/command/format/diff.go b/internal/command/format/diff.go index 0f812f5cb167..8c7d3ce84ba9 100644 --- a/internal/command/format/diff.go +++ b/internal/command/format/diff.go @@ -115,6 +115,8 @@ func ResourceChange( switch change.ActionReason { case plans.ResourceInstanceDeleteBecauseNoResourceConfig: buf.WriteString(fmt.Sprintf("\n # (because %s is not in configuration)", addr.Resource.Resource)) + case plans.ResourceInstanceDeleteBecauseNoMoveTarget: + buf.WriteString(fmt.Sprintf("\n # (because %s was moved to %s, which is not in configuration)", change.PrevRunAddr, addr.Resource.Resource)) case plans.ResourceInstanceDeleteBecauseNoModule: // FIXME: Ideally we'd truncate addr.Module to reflect the earliest // step that doesn't exist, so it's clearer which call this refers diff --git a/internal/command/jsonplan/plan.go b/internal/command/jsonplan/plan.go index 048d68ea7187..3edd3e857bed 100644 --- a/internal/command/jsonplan/plan.go +++ b/internal/command/jsonplan/plan.go @@ -413,6 +413,8 @@ func (p *plan) marshalResourceChanges(resources []*plans.ResourceInstanceChangeS r.ActionReason = "delete_because_each_key" case plans.ResourceInstanceDeleteBecauseNoModule: r.ActionReason = "delete_because_no_module" + case plans.ResourceInstanceDeleteBecauseNoMoveTarget: + r.ActionReason = "delete_because_no_move_target" case plans.ResourceInstanceReadBecauseConfigUnknown: r.ActionReason = "read_because_config_unknown" case plans.ResourceInstanceReadBecauseDependencyPending: diff --git a/internal/command/views/json/change.go b/internal/command/views/json/change.go index 21188bfaf5d3..60439e509017 100644 --- a/internal/command/views/json/change.go +++ b/internal/command/views/json/change.go @@ -80,6 +80,7 @@ const ( ReasonDeleteBecauseCountIndex ChangeReason = "delete_because_count_index" ReasonDeleteBecauseEachKey ChangeReason = "delete_because_each_key" ReasonDeleteBecauseNoModule ChangeReason = "delete_because_no_module" + ReasonDeleteBecauseNoMoveTarget ChangeReason = "delete_because_no_move_target" ReasonReadBecauseConfigUnknown ChangeReason = "read_because_config_unknown" ReasonReadBecauseDependencyPending ChangeReason = "read_because_dependency_pending" ) @@ -108,6 +109,8 @@ func changeReason(reason plans.ResourceInstanceChangeActionReason) ChangeReason return ReasonDeleteBecauseNoModule case plans.ResourceInstanceReadBecauseConfigUnknown: return ReasonReadBecauseConfigUnknown + case plans.ResourceInstanceDeleteBecauseNoMoveTarget: + return ReasonDeleteBecauseNoMoveTarget case plans.ResourceInstanceReadBecauseDependencyPending: return ReasonReadBecauseDependencyPending default: diff --git a/internal/plans/changes.go b/internal/plans/changes.go index 1a4331528cde..7c54928331e6 100644 --- a/internal/plans/changes.go +++ b/internal/plans/changes.go @@ -427,6 +427,12 @@ const ( // specific reasons for a particular instance to no longer be declared. ResourceInstanceDeleteBecauseNoModule ResourceInstanceChangeActionReason = 'M' + // ResourceInstanceDeleteBecauseNoMoveTarget indicates that the resource + // address appears as the target ("to") in a moved block, but no + // configuration exists for that resource. According to our move rules, + // this combination evaluates to a deletion of the "new" resource. + ResourceInstanceDeleteBecauseNoMoveTarget ResourceInstanceChangeActionReason = 'A' + // ResourceInstanceReadBecauseConfigUnknown indicates that the resource // must be read during apply (rather than during planning) because its // configuration contains unknown values. This reason applies only to diff --git a/internal/plans/internal/planproto/planfile.pb.go b/internal/plans/internal/planproto/planfile.pb.go index 8e09fee33c37..96f8828bccd5 100644 --- a/internal/plans/internal/planproto/planfile.pb.go +++ b/internal/plans/internal/planproto/planfile.pb.go @@ -152,6 +152,7 @@ const ( ResourceInstanceActionReason_REPLACE_BY_TRIGGERS ResourceInstanceActionReason = 9 ResourceInstanceActionReason_READ_BECAUSE_CONFIG_UNKNOWN ResourceInstanceActionReason = 10 ResourceInstanceActionReason_READ_BECAUSE_DEPENDENCY_PENDING ResourceInstanceActionReason = 11 + ResourceInstanceActionReason_DELETE_BECAUSE_NO_MOVE_TARGET ResourceInstanceActionReason = 12 ) // Enum value maps for ResourceInstanceActionReason. @@ -169,6 +170,7 @@ var ( 9: "REPLACE_BY_TRIGGERS", 10: "READ_BECAUSE_CONFIG_UNKNOWN", 11: "READ_BECAUSE_DEPENDENCY_PENDING", + 12: "DELETE_BECAUSE_NO_MOVE_TARGET", } ResourceInstanceActionReason_value = map[string]int32{ "NONE": 0, @@ -183,6 +185,7 @@ var ( "REPLACE_BY_TRIGGERS": 9, "READ_BECAUSE_CONFIG_UNKNOWN": 10, "READ_BECAUSE_DEPENDENCY_PENDING": 11, + "DELETE_BECAUSE_NO_MOVE_TARGET": 12, } ) @@ -1391,7 +1394,7 @@ var file_planfile_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x05, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x54, 0x48, 0x45, 0x4e, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x48, - 0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0x86, 0x03, 0x0a, 0x1c, + 0x45, 0x4e, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x07, 0x2a, 0xa9, 0x03, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, @@ -1416,11 +1419,14 @@ var file_planfile_proto_rawDesc = []byte{ 0x4f, 0x4e, 0x46, 0x49, 0x47, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x42, 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x44, 0x45, 0x50, 0x45, 0x4e, 0x44, 0x45, 0x4e, 0x43, 0x59, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, - 0x4e, 0x47, 0x10, 0x0b, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x74, 0x65, 0x72, - 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, - 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, - 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4e, 0x47, 0x10, 0x0b, 0x12, 0x21, 0x0a, 0x1d, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x42, + 0x45, 0x43, 0x41, 0x55, 0x53, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, + 0x41, 0x52, 0x47, 0x45, 0x54, 0x10, 0x0c, 0x42, 0x42, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x74, 0x65, 0x72, 0x72, 0x61, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x70, 0x6c, 0x61, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/internal/plans/internal/planproto/planfile.proto b/internal/plans/internal/planproto/planfile.proto index 2941b1dc34a9..0de1753e83ba 100644 --- a/internal/plans/internal/planproto/planfile.proto +++ b/internal/plans/internal/planproto/planfile.proto @@ -151,6 +151,7 @@ enum ResourceInstanceActionReason { REPLACE_BY_TRIGGERS = 9; READ_BECAUSE_CONFIG_UNKNOWN = 10; READ_BECAUSE_DEPENDENCY_PENDING = 11; + DELETE_BECAUSE_NO_MOVE_TARGET = 12; } message ResourceInstanceChange { diff --git a/internal/plans/planfile/tfplan.go b/internal/plans/planfile/tfplan.go index a840c378efff..cb3b34f25124 100644 --- a/internal/plans/planfile/tfplan.go +++ b/internal/plans/planfile/tfplan.go @@ -331,6 +331,8 @@ func resourceChangeFromTfplan(rawChange *planproto.ResourceInstanceChange) (*pla ret.ActionReason = plans.ResourceInstanceReadBecauseConfigUnknown case planproto.ResourceInstanceActionReason_READ_BECAUSE_DEPENDENCY_PENDING: ret.ActionReason = plans.ResourceInstanceReadBecauseDependencyPending + case planproto.ResourceInstanceActionReason_DELETE_BECAUSE_NO_MOVE_TARGET: + ret.ActionReason = plans.ResourceInstanceDeleteBecauseNoMoveTarget default: return nil, fmt.Errorf("resource has invalid action reason %s", rawChange.ActionReason) } @@ -705,6 +707,8 @@ func resourceChangeToTfplan(change *plans.ResourceInstanceChangeSrc) (*planproto ret.ActionReason = planproto.ResourceInstanceActionReason_READ_BECAUSE_CONFIG_UNKNOWN case plans.ResourceInstanceReadBecauseDependencyPending: ret.ActionReason = planproto.ResourceInstanceActionReason_READ_BECAUSE_DEPENDENCY_PENDING + case plans.ResourceInstanceDeleteBecauseNoMoveTarget: + ret.ActionReason = planproto.ResourceInstanceActionReason_DELETE_BECAUSE_NO_MOVE_TARGET default: return nil, fmt.Errorf("resource %s has unsupported action reason %s", change.Addr, change.ActionReason) } diff --git a/internal/plans/resourceinstancechangeactionreason_string.go b/internal/plans/resourceinstancechangeactionreason_string.go index fbc2abe0c9db..742aae235651 100644 --- a/internal/plans/resourceinstancechangeactionreason_string.go +++ b/internal/plans/resourceinstancechangeactionreason_string.go @@ -18,6 +18,7 @@ func _() { _ = x[ResourceInstanceDeleteBecauseCountIndex-67] _ = x[ResourceInstanceDeleteBecauseEachKey-69] _ = x[ResourceInstanceDeleteBecauseNoModule-77] + _ = x[ResourceInstanceDeleteBecauseNoMoveTarget-65] _ = x[ResourceInstanceReadBecauseConfigUnknown-63] _ = x[ResourceInstanceReadBecauseDependencyPending-33] } @@ -26,16 +27,17 @@ const ( _ResourceInstanceChangeActionReason_name_0 = "ResourceInstanceChangeNoReason" _ResourceInstanceChangeActionReason_name_1 = "ResourceInstanceReadBecauseDependencyPending" _ResourceInstanceChangeActionReason_name_2 = "ResourceInstanceReadBecauseConfigUnknown" - _ResourceInstanceChangeActionReason_name_3 = "ResourceInstanceDeleteBecauseCountIndexResourceInstanceReplaceByTriggersResourceInstanceDeleteBecauseEachKeyResourceInstanceReplaceBecauseCannotUpdate" - _ResourceInstanceChangeActionReason_name_4 = "ResourceInstanceDeleteBecauseNoModuleResourceInstanceDeleteBecauseNoResourceConfig" - _ResourceInstanceChangeActionReason_name_5 = "ResourceInstanceReplaceByRequest" - _ResourceInstanceChangeActionReason_name_6 = "ResourceInstanceReplaceBecauseTainted" - _ResourceInstanceChangeActionReason_name_7 = "ResourceInstanceDeleteBecauseWrongRepetition" + _ResourceInstanceChangeActionReason_name_3 = "ResourceInstanceDeleteBecauseNoMoveTarget" + _ResourceInstanceChangeActionReason_name_4 = "ResourceInstanceDeleteBecauseCountIndexResourceInstanceReplaceByTriggersResourceInstanceDeleteBecauseEachKeyResourceInstanceReplaceBecauseCannotUpdate" + _ResourceInstanceChangeActionReason_name_5 = "ResourceInstanceDeleteBecauseNoModuleResourceInstanceDeleteBecauseNoResourceConfig" + _ResourceInstanceChangeActionReason_name_6 = "ResourceInstanceReplaceByRequest" + _ResourceInstanceChangeActionReason_name_7 = "ResourceInstanceReplaceBecauseTainted" + _ResourceInstanceChangeActionReason_name_8 = "ResourceInstanceDeleteBecauseWrongRepetition" ) var ( - _ResourceInstanceChangeActionReason_index_3 = [...]uint8{0, 39, 72, 108, 150} - _ResourceInstanceChangeActionReason_index_4 = [...]uint8{0, 37, 82} + _ResourceInstanceChangeActionReason_index_4 = [...]uint8{0, 39, 72, 108, 150} + _ResourceInstanceChangeActionReason_index_5 = [...]uint8{0, 37, 82} ) func (i ResourceInstanceChangeActionReason) String() string { @@ -46,18 +48,20 @@ func (i ResourceInstanceChangeActionReason) String() string { return _ResourceInstanceChangeActionReason_name_1 case i == 63: return _ResourceInstanceChangeActionReason_name_2 + case i == 65: + return _ResourceInstanceChangeActionReason_name_3 case 67 <= i && i <= 70: i -= 67 - return _ResourceInstanceChangeActionReason_name_3[_ResourceInstanceChangeActionReason_index_3[i]:_ResourceInstanceChangeActionReason_index_3[i+1]] + return _ResourceInstanceChangeActionReason_name_4[_ResourceInstanceChangeActionReason_index_4[i]:_ResourceInstanceChangeActionReason_index_4[i+1]] case 77 <= i && i <= 78: i -= 77 - return _ResourceInstanceChangeActionReason_name_4[_ResourceInstanceChangeActionReason_index_4[i]:_ResourceInstanceChangeActionReason_index_4[i+1]] + return _ResourceInstanceChangeActionReason_name_5[_ResourceInstanceChangeActionReason_index_5[i]:_ResourceInstanceChangeActionReason_index_5[i+1]] case i == 82: - return _ResourceInstanceChangeActionReason_name_5 - case i == 84: return _ResourceInstanceChangeActionReason_name_6 - case i == 87: + case i == 84: return _ResourceInstanceChangeActionReason_name_7 + case i == 87: + return _ResourceInstanceChangeActionReason_name_8 default: return "ResourceInstanceChangeActionReason(" + strconv.FormatInt(int64(i), 10) + ")" } diff --git a/internal/terraform/node_resource_plan_orphan.go b/internal/terraform/node_resource_plan_orphan.go index 94aa18f980e5..6002a2f25d74 100644 --- a/internal/terraform/node_resource_plan_orphan.go +++ b/internal/terraform/node_resource_plan_orphan.go @@ -157,6 +157,13 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon func (n *NodePlannableResourceInstanceOrphan) deleteActionReason(ctx EvalContext) plans.ResourceInstanceChangeActionReason { cfg := n.Config if cfg == nil { + if !n.Addr.Equal(n.prevRunAddr(ctx)) { + // This means the resource was moved - see also + // ResourceInstanceChange.Moved() which calculates + // this the same way. + return plans.ResourceInstanceDeleteBecauseNoMoveTarget + } + return plans.ResourceInstanceDeleteBecauseNoResourceConfig }