@ -3504,6 +3504,229 @@ func TestResourceChange_nestedMap(t *testing.T) {
runTestCases ( t , testCases )
}
func TestResourceChange_actionReason ( t * testing . T ) {
emptySchema := & configschema . Block { }
nullVal := cty . NullVal ( cty . EmptyObject )
emptyVal := cty . EmptyObjectVal
testCases := map [ string ] testCase {
"delete for no particular reason" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceChangeNoReason ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example will be destroyed
- resource "test_instance" "example" { }
` ,
} ,
"delete because of wrong repetition mode (NoKey)" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseWrongRepetition ,
Mode : addrs . ManagedResourceMode ,
InstanceKey : addrs . NoKey ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example will be destroyed
# ( because resource uses count or for_each )
- resource "test_instance" "example" { }
` ,
} ,
"delete because of wrong repetition mode (IntKey)" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseWrongRepetition ,
Mode : addrs . ManagedResourceMode ,
InstanceKey : addrs . IntKey ( 1 ) ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example [ 1 ] will be destroyed
# ( because resource does not use count )
- resource "test_instance" "example" { }
` ,
} ,
"delete because of wrong repetition mode (StringKey)" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseWrongRepetition ,
Mode : addrs . ManagedResourceMode ,
InstanceKey : addrs . StringKey ( "a" ) ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example [ "a" ] will be destroyed
# ( because resource does not use for_each )
- resource "test_instance" "example" { }
` ,
} ,
"delete because no resource configuration" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseNoResourceConfig ,
ModuleInst : addrs . RootModuleInstance . Child ( "foo" , addrs . NoKey ) ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # module . foo . test_instance . example will be destroyed
# ( because test_instance . example is not in configuration )
- resource "test_instance" "example" { }
` ,
} ,
"delete because no module" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseNoModule ,
ModuleInst : addrs . RootModuleInstance . Child ( "foo" , addrs . IntKey ( 1 ) ) ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # module . foo [ 1 ] . test_instance . example will be destroyed
# ( because module . foo [ 1 ] is not in configuration )
- resource "test_instance" "example" { }
` ,
} ,
"delete because out of range for count" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseCountIndex ,
Mode : addrs . ManagedResourceMode ,
InstanceKey : addrs . IntKey ( 1 ) ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example [ 1 ] will be destroyed
# ( because index [ 1 ] is out of range for count )
- resource "test_instance" "example" { }
` ,
} ,
"delete because out of range for for_each" : {
Action : plans . Delete ,
ActionReason : plans . ResourceInstanceDeleteBecauseEachKey ,
Mode : addrs . ManagedResourceMode ,
InstanceKey : addrs . StringKey ( "boop" ) ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example [ "boop" ] will be destroyed
# ( because key [ "boop" ] is not in for_each map )
- resource "test_instance" "example" { }
` ,
} ,
"replace for no particular reason (delete first)" : {
Action : plans . DeleteThenCreate ,
ActionReason : plans . ResourceInstanceChangeNoReason ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example must be replaced
- / + resource "test_instance" "example" { }
` ,
} ,
"replace for no particular reason (create first)" : {
Action : plans . CreateThenDelete ,
ActionReason : plans . ResourceInstanceChangeNoReason ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example must be replaced
+ / - resource "test_instance" "example" { }
` ,
} ,
"replace by request (delete first)" : {
Action : plans . DeleteThenCreate ,
ActionReason : plans . ResourceInstanceReplaceByRequest ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example will be replaced , as requested
- / + resource "test_instance" "example" { }
` ,
} ,
"replace by request (create first)" : {
Action : plans . CreateThenDelete ,
ActionReason : plans . ResourceInstanceReplaceByRequest ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example will be replaced , as requested
+ / - resource "test_instance" "example" { }
` ,
} ,
"replace because tainted (delete first)" : {
Action : plans . DeleteThenCreate ,
ActionReason : plans . ResourceInstanceReplaceBecauseTainted ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example is tainted , so must be replaced
- / + resource "test_instance" "example" { }
` ,
} ,
"replace because tainted (create first)" : {
Action : plans . CreateThenDelete ,
ActionReason : plans . ResourceInstanceReplaceBecauseTainted ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example is tainted , so must be replaced
+ / - resource "test_instance" "example" { }
` ,
} ,
"replace because cannot update (delete first)" : {
Action : plans . DeleteThenCreate ,
ActionReason : plans . ResourceInstanceReplaceBecauseCannotUpdate ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
// This one has no special message, because the fuller explanation
// typically appears inline as a "# forces replacement" comment.
// (not shown here)
ExpectedOutput : ` # test_instance . example must be replaced
- / + resource "test_instance" "example" { }
` ,
} ,
"replace because cannot update (create first)" : {
Action : plans . CreateThenDelete ,
ActionReason : plans . ResourceInstanceReplaceBecauseCannotUpdate ,
Mode : addrs . ManagedResourceMode ,
Before : emptyVal ,
After : nullVal ,
Schema : emptySchema ,
RequiredReplace : cty . NewPathSet ( ) ,
// This one has no special message, because the fuller explanation
// typically appears inline as a "# forces replacement" comment.
// (not shown here)
ExpectedOutput : ` # test_instance . example must be replaced
+ / - resource "test_instance" "example" { }
` ,
} ,
}
runTestCases ( t , testCases )
}
func TestResourceChange_sensitiveVariable ( t * testing . T ) {
testCases := map [ string ] testCase {
"creation" : {
@ -4479,7 +4702,7 @@ func TestResourceChange_moved(t *testing.T) {
} ,
RequiredReplace : cty . NewPathSet ( ) ,
ExpectedOutput : ` # test_instance . example will be updated in - place
# ( test_instance. previous has moved to test_instance . example )
# ( moved from test_instance . previous )
~ resource "test_instance" "example" {
~ bar = "baz" - > "boop"
id = "12345"
@ -4524,7 +4747,9 @@ func TestResourceChange_moved(t *testing.T) {
type testCase struct {
Action plans . Action
ActionReason plans . ResourceInstanceChangeActionReason
ModuleInst addrs . ModuleInstance
Mode addrs . ResourceMode
InstanceKey addrs . InstanceKey
DeposedKey states . DeposedKey
Before cty . Value
BeforeValMarks [ ] cty . PathValueMarks
@ -4571,7 +4796,7 @@ func runTestCases(t *testing.T, testCases map[string]testCase) {
Mode : tc . Mode ,
Type : "test_instance" ,
Name : "example" ,
} . Instance ( addrs. NoKey ) . Absolute ( addrs . RootModuleInstance )
} . Instance ( tc. InstanceKey ) . Absolute ( tc . ModuleInst )
prevRunAddr := tc . PrevRunAddr
// If no previous run address is given, reuse the current address