command/format: Fix rendering of force-new updates
This commit is contained in:
parent
9a1f79a7da
commit
0b981fa641
|
@ -844,7 +844,7 @@ func (p *blockBodyDiffPrinter) writeActionSymbol(action plans.Action) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *blockBodyDiffPrinter) pathForcesNewResource(path cty.Path) bool {
|
func (p *blockBodyDiffPrinter) pathForcesNewResource(path cty.Path) bool {
|
||||||
if p.action.IsReplace() {
|
if !p.action.IsReplace() {
|
||||||
// "requiredReplace" only applies when the instance is being replaced
|
// "requiredReplace" only applies when the instance is being replaced
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ func TestResourceChange_primitiveTypes(t *testing.T) {
|
||||||
}),
|
}),
|
||||||
ExpectedOutput: ` # test_instance.example must be replaced
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
-/+ resource "test_instance" "example" {
|
-/+ resource "test_instance" "example" {
|
||||||
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
~ ami = "ami-BEFORE" -> "ami-AFTER" # forces replacement
|
||||||
id = "i-02ae66f368e8518a9"
|
id = "i-02ae66f368e8518a9"
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
@ -161,6 +161,39 @@ new line
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
"force-new update of multi-line string field": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"more_lines": cty.StringVal(`original
|
||||||
|
`),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"more_lines": cty.StringVal(`original
|
||||||
|
new line
|
||||||
|
`),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"more_lines": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "more_lines"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ more_lines = <<~EOT # forces replacement
|
||||||
|
original
|
||||||
|
+ new line
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
|
||||||
// Sensitive
|
// Sensitive
|
||||||
|
|
||||||
|
@ -262,6 +295,40 @@ func TestResourceChange_JSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"json_field": cty.StringVal(`{"aaa": "value"}`),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"json_field": cty.StringVal(`{"aaa": "value", "bbb": "new_value"}`),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"json_field": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "json_field"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ json_field = jsonencode(
|
||||||
|
~ {
|
||||||
|
- aaa = "value"
|
||||||
|
} -> {
|
||||||
|
+ aaa = "value"
|
||||||
|
+ bbb = "new_value"
|
||||||
|
} # forces replacement
|
||||||
|
)
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update (whitespace change)": {
|
"in-place update (whitespace change)": {
|
||||||
|
@ -293,6 +360,39 @@ func TestResourceChange_JSON(t *testing.T) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update (whitespace change)": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"json_field": cty.StringVal(`{"aaa": "value", "bbb": "another"}`),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"json_field": cty.StringVal(`{"aaa":"value",
|
||||||
|
"bbb":"another"}`),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"json_field": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "json_field"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ json_field = jsonencode( # whitespace changes force replacement
|
||||||
|
{
|
||||||
|
aaa = "value"
|
||||||
|
bbb = "another"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -372,6 +472,48 @@ func TestResourceChange_primitiveList(t *testing.T) {
|
||||||
"cccc",
|
"cccc",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update - insertion": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"list_field": cty.ListVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"list_field": {Type: cty.List(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "list_field"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ list_field = [ # forces replacement
|
||||||
|
"aaaa",
|
||||||
|
+ "bbbb",
|
||||||
|
"cccc",
|
||||||
|
]
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update - deletion": {
|
"in-place update - deletion": {
|
||||||
|
@ -490,6 +632,48 @@ func TestResourceChange_primitiveSet(t *testing.T) {
|
||||||
"cccc",
|
"cccc",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update - insertion": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.SetVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"set_field": cty.SetVal([]cty.Value{
|
||||||
|
cty.StringVal("aaaa"),
|
||||||
|
cty.StringVal("bbbb"),
|
||||||
|
cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"set_field": {Type: cty.Set(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "set_field"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ set_field = [ # forces replacement
|
||||||
|
"aaaa",
|
||||||
|
+ "bbbb",
|
||||||
|
"cccc",
|
||||||
|
]
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update - deletion": {
|
"in-place update - deletion": {
|
||||||
|
@ -608,6 +792,48 @@ func TestResourceChange_map(t *testing.T) {
|
||||||
"c" = "cccc"
|
"c" = "cccc"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update - insertion": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"map_field": cty.MapVal(map[string]cty.Value{
|
||||||
|
"a": cty.StringVal("aaaa"),
|
||||||
|
"c": cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
After: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.UnknownVal(cty.String),
|
||||||
|
"ami": cty.StringVal("ami-STATIC"),
|
||||||
|
"map_field": cty.MapVal(map[string]cty.Value{
|
||||||
|
"a": cty.StringVal("aaaa"),
|
||||||
|
"b": cty.StringVal("bbbb"),
|
||||||
|
"c": cty.StringVal("cccc"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
"map_field": {Type: cty.Map(cty.String), Optional: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "map_field"},
|
||||||
|
}),
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
ami = "ami-STATIC"
|
||||||
|
~ id = "i-02ae66f368e8518a9" -> (known after apply)
|
||||||
|
~ map_field = { # forces replacement
|
||||||
|
"a" = "aaaa"
|
||||||
|
+ "b" = "bbbb"
|
||||||
|
"c" = "cccc"
|
||||||
|
}
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update - deletion": {
|
"in-place update - deletion": {
|
||||||
|
@ -816,6 +1042,118 @@ func TestResourceChange_nestedList(t *testing.T) {
|
||||||
volume_type = "gp2"
|
volume_type = "gp2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update (inside block)": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
"root_block_device": cty.ListVal([]cty.Value{
|
||||||
|
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"),
|
||||||
|
"root_block_device": cty.ListVal([]cty.Value{
|
||||||
|
cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"volume_type": cty.StringVal("different"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "root_block_device"},
|
||||||
|
cty.IndexStep{Key: cty.NumberIntVal(0)},
|
||||||
|
cty.GetAttrStep{Name: "volume_type"},
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
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: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
id = "i-02ae66f368e8518a9"
|
||||||
|
|
||||||
|
~ root_block_device {
|
||||||
|
~ volume_type = "gp2" -> "different" # forces replacement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update (whole block)": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
"root_block_device": cty.ListVal([]cty.Value{
|
||||||
|
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"),
|
||||||
|
"root_block_device": cty.ListVal([]cty.Value{
|
||||||
|
cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"volume_type": cty.StringVal("different"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "root_block_device"},
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
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: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
id = "i-02ae66f368e8518a9"
|
||||||
|
|
||||||
|
~ root_block_device { # forces replacement
|
||||||
|
~ volume_type = "gp2" -> "different"
|
||||||
|
}
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update - deletion": {
|
"in-place update - deletion": {
|
||||||
|
@ -988,6 +1326,118 @@ func TestResourceChange_nestedSet(t *testing.T) {
|
||||||
volume_type = "gp2"
|
volume_type = "gp2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update (inside block)": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
"root_block_device": cty.SetVal([]cty.Value{
|
||||||
|
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"),
|
||||||
|
"root_block_device": cty.SetVal([]cty.Value{
|
||||||
|
cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"volume_type": cty.StringVal("different"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "root_block_device"},
|
||||||
|
cty.IndexStep{Key: cty.NumberIntVal(0)},
|
||||||
|
cty.GetAttrStep{Name: "volume_type"},
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
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: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
id = "i-02ae66f368e8518a9"
|
||||||
|
|
||||||
|
~ root_block_device {
|
||||||
|
~ volume_type = "gp2" -> "different" # forces replacement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"force-new update (whole block)": {
|
||||||
|
Action: plans.DeleteThenCreate,
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Before: cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"id": cty.StringVal("i-02ae66f368e8518a9"),
|
||||||
|
"ami": cty.StringVal("ami-BEFORE"),
|
||||||
|
"root_block_device": cty.SetVal([]cty.Value{
|
||||||
|
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"),
|
||||||
|
"root_block_device": cty.SetVal([]cty.Value{
|
||||||
|
cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"volume_type": cty.StringVal("different"),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
RequiredReplace: cty.NewPathSet(cty.Path{
|
||||||
|
cty.GetAttrStep{Name: "root_block_device"},
|
||||||
|
}),
|
||||||
|
Schema: &configschema.Block{
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {Type: cty.String, Optional: true, Computed: true},
|
||||||
|
"ami": {Type: cty.String, Optional: true},
|
||||||
|
},
|
||||||
|
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: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: ` # test_instance.example must be replaced
|
||||||
|
-/+ resource "test_instance" "example" {
|
||||||
|
~ ami = "ami-BEFORE" -> "ami-AFTER"
|
||||||
|
id = "i-02ae66f368e8518a9"
|
||||||
|
|
||||||
|
~ root_block_device { # forces replacement
|
||||||
|
~ volume_type = "gp2" -> "different"
|
||||||
|
}
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
"in-place update - deletion": {
|
"in-place update - deletion": {
|
||||||
|
|
Loading…
Reference in New Issue