|
|
|
|
@ -3744,14 +3744,571 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
+ new_field = "new_value"
|
|
|
|
|
+ volume_type = "gp2"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"force-new update (whole block)": {
|
|
|
|
|
Action: plans.DeleteThenCreate,
|
|
|
|
|
ActionReason: plans.ResourceInstanceReplaceBecauseCannotUpdate,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("standard"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("100GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("different"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("standard"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
|
|
|
|
cty.GetAttrStep{Name: "root_block_device"},
|
|
|
|
|
cty.IndexStep{Key: cty.StringVal("a")},
|
|
|
|
|
},
|
|
|
|
|
cty.Path{cty.GetAttrStep{Name: "disks"}},
|
|
|
|
|
),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example must be replaced
|
|
|
|
|
-/+ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
~ "disk_a" = { # forces replacement
|
|
|
|
|
~ size = "50GB" -> "100GB"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
|
|
|
|
|
~ root_block_device "a" { # forces replacement
|
|
|
|
|
~ volume_type = "gp2" -> "different"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - deletion": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
"root_block_device": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"volume_type": cty.String,
|
|
|
|
|
"new_field": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
- "disk_a" = {
|
|
|
|
|
- mount_point = "/var/diska" -> null
|
|
|
|
|
- size = "50GB" -> null
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
|
|
|
|
|
- root_block_device "a" {
|
|
|
|
|
- new_field = "new_value" -> null
|
|
|
|
|
- volume_type = "gp2" -> null
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - unknown": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.UnknownVal(cty.Map(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
}))),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
- "disk_a" = {
|
|
|
|
|
- mount_point = "/var/diska" -> null
|
|
|
|
|
- size = "50GB" -> null
|
|
|
|
|
},
|
|
|
|
|
} -> (known after apply)
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - insertion sensitive": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
AfterValMarks: []cty.PathValueMarks{
|
|
|
|
|
{
|
|
|
|
|
Path: cty.Path{cty.GetAttrStep{Name: "disks"},
|
|
|
|
|
cty.IndexStep{Key: cty.StringVal("disk_a")},
|
|
|
|
|
cty.GetAttrStep{Name: "mount_point"},
|
|
|
|
|
},
|
|
|
|
|
Marks: cty.NewValueMarks(marks.Sensitive),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
+ "disk_a" = {
|
|
|
|
|
+ mount_point = (sensitive)
|
|
|
|
|
+ size = "50GB"
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple unchanged blocks": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
# (2 unchanged blocks hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple blocks first changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
~ root_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple blocks second changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
~ root_block_device "a" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple blocks changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
~ root_block_device "a" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
~ root_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple different unchanged blocks": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
# (2 unchanged blocks hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - multiple different blocks first changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
~ leaf_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"force-new update (whole block)": {
|
|
|
|
|
Action: plans.DeleteThenCreate,
|
|
|
|
|
ActionReason: plans.ResourceInstanceReplaceBecauseCannotUpdate,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
"in-place update - multiple different blocks second changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
@ -3765,8 +4322,10 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("standard"),
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
@ -3776,44 +4335,37 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("100GB"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("different"),
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("standard"),
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
|
|
|
|
cty.GetAttrStep{Name: "root_block_device"},
|
|
|
|
|
cty.IndexStep{Key: cty.StringVal("a")},
|
|
|
|
|
},
|
|
|
|
|
cty.Path{cty.GetAttrStep{Name: "disks"}},
|
|
|
|
|
),
|
|
|
|
|
Schema: testSchema(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example must be replaced
|
|
|
|
|
-/+ resource "test_instance" "example" {
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
~ "disk_a" = { # forces replacement
|
|
|
|
|
~ size = "50GB" -> "100GB"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
~ root_block_device "a" { # forces replacement
|
|
|
|
|
~ volume_type = "gp2" -> "different"
|
|
|
|
|
~ root_block_device "a" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - deletion": {
|
|
|
|
|
"in-place update - multiple different blocks changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
@ -3828,43 +4380,53 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
"root_block_device": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"volume_type": cty.String,
|
|
|
|
|
"new_field": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
- "disk_a" = {
|
|
|
|
|
- mount_point = "/var/diska" -> null
|
|
|
|
|
- size = "50GB" -> null
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
- root_block_device "a" {
|
|
|
|
|
- new_field = "new_value" -> null
|
|
|
|
|
- volume_type = "gp2" -> null
|
|
|
|
|
~ leaf_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ root_block_device "a" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - unknown": {
|
|
|
|
|
"in-place update - mixed blocks unchanged": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
@ -3879,55 +4441,84 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
After: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-AFTER"),
|
|
|
|
|
"disks": cty.UnknownVal(cty.Map(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
}))),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
- "disk_a" = {
|
|
|
|
|
- mount_point = "/var/diska" -> null
|
|
|
|
|
- size = "50GB" -> null
|
|
|
|
|
},
|
|
|
|
|
} -> (known after apply)
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
# (4 unchanged blocks hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
"in-place update - insertion sensitive": {
|
|
|
|
|
"in-place update - mixed blocks changed": {
|
|
|
|
|
Action: plans.Update,
|
|
|
|
|
Mode: addrs.ManagedResourceMode,
|
|
|
|
|
Before: cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
|
|
|
|
"ami": cty.StringVal("ami-BEFORE"),
|
|
|
|
|
"disks": cty.MapValEmpty(cty.Object(map[string]cty.Type{
|
|
|
|
|
"mount_point": cty.String,
|
|
|
|
|
"size": cty.String,
|
|
|
|
|
})),
|
|
|
|
|
"disks": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"disk_a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"mount_point": cty.StringVal("/var/diska"),
|
|
|
|
|
"size": cty.StringVal("50GB"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
@ -3943,33 +4534,37 @@ func TestResourceChange_nestedMap(t *testing.T) {
|
|
|
|
|
"root_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
"new_field": cty.StringVal("new_value"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
"leaf_block_device": cty.MapVal(map[string]cty.Value{
|
|
|
|
|
"a": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp2"),
|
|
|
|
|
}),
|
|
|
|
|
"b": cty.ObjectVal(map[string]cty.Value{
|
|
|
|
|
"volume_type": cty.StringVal("gp3"),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
AfterValMarks: []cty.PathValueMarks{
|
|
|
|
|
{
|
|
|
|
|
Path: cty.Path{cty.GetAttrStep{Name: "disks"},
|
|
|
|
|
cty.IndexStep{Key: cty.StringVal("disk_a")},
|
|
|
|
|
cty.GetAttrStep{Name: "mount_point"},
|
|
|
|
|
},
|
|
|
|
|
Marks: cty.NewValueMarks(marks.Sensitive),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
RequiredReplace: cty.NewPathSet(),
|
|
|
|
|
Schema: testSchemaPlus(configschema.NestingMap),
|
|
|
|
|
Schema: testSchemaMultipleBlocks(configschema.NestingMap),
|
|
|
|
|
ExpectedOutput: ` # test_instance.example will be updated in-place
|
|
|
|
|
~ resource "test_instance" "example" {
|
|
|
|
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
|
|
|
|
~ disks = {
|
|
|
|
|
+ "disk_a" = {
|
|
|
|
|
+ mount_point = (sensitive)
|
|
|
|
|
+ size = "50GB"
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
id = "i-02ae66f368e8518a9"
|
|
|
|
|
# (1 unchanged attribute hidden)
|
|
|
|
|
|
|
|
|
|
# (1 unchanged block hidden)
|
|
|
|
|
~ leaf_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ root_block_device "b" {
|
|
|
|
|
~ volume_type = "gp2" -> "gp3"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# (2 unchanged blocks hidden)
|
|
|
|
|
}
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
@ -5459,6 +6054,50 @@ func testSchema(nesting configschema.NestingMode) *configschema.Block {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func testSchemaMultipleBlocks(nesting configschema.NestingMode) *configschema.Block {
|
|
|
|
|
return &configschema.Block{
|
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
|
|
|
|
"ami": {Type: cty.String, Optional: true},
|
|
|
|
|
"disks": {
|
|
|
|
|
NestedType: &configschema.Object{
|
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
|
"mount_point": {Type: cty.String, Optional: true},
|
|
|
|
|
"size": {Type: cty.String, Optional: true},
|
|
|
|
|
},
|
|
|
|
|
Nesting: nesting,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
BlockTypes: map[string]*configschema.NestedBlock{
|
|
|
|
|
"root_block_device": {
|
|
|
|
|
Block: configschema.Block{
|
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
|
"volume_type": {
|
|
|
|
|
Type: cty.String,
|
|
|
|
|
Optional: true,
|
|
|
|
|
Computed: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Nesting: nesting,
|
|
|
|
|
},
|
|
|
|
|
"leaf_block_device": {
|
|
|
|
|
Block: configschema.Block{
|
|
|
|
|
Attributes: map[string]*configschema.Attribute{
|
|
|
|
|
"volume_type": {
|
|
|
|
|
Type: cty.String,
|
|
|
|
|
Optional: true,
|
|
|
|
|
Computed: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Nesting: nesting,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// similar to testSchema with the addition of a "new_field" block
|
|
|
|
|
func testSchemaPlus(nesting configschema.NestingMode) *configschema.Block {
|
|
|
|
|
return &configschema.Block{
|
|
|
|
|
|