helper/schema: mark diff as forcenew if element is computed
Fixes #10125 If the elements are computed and the field is ForceNew, then we should mark the computed count as potentially forcing a new operation. Example, assuming `groups` forces new... **Step 1:** groups = ["1", "2", "3"] At this point, the resource isn't create, so this should result in a diff like: CREATE resource: groups: "" => ["1", "2", "3"] **Step 2:** groups = ["${computedvar}"] The OLD behavior was: UPDATE resource groups.#: "3" => "computed" This would cause a diff mismatch because if `${computedvar}` was different then it should force new. The NEW behavior is: DESTROY/CREATE resource: groups.#: "3" => "computed" (forces new)
This commit is contained in:
parent
75aabd7a79
commit
39542898b0
|
@ -925,6 +925,13 @@ func (m schemaMap) diffSet(
|
|||
oldStr := strconv.Itoa(oldLen)
|
||||
newStr := strconv.Itoa(newLen)
|
||||
|
||||
// Build a schema for our count
|
||||
countSchema := &Schema{
|
||||
Type: TypeInt,
|
||||
Computed: schema.Computed,
|
||||
ForceNew: schema.ForceNew,
|
||||
}
|
||||
|
||||
// If the set computed then say that the # is computed
|
||||
if computedSet || schema.Computed && !nSet {
|
||||
// If # already exists, equals 0 and no new set is supplied, there
|
||||
|
@ -941,22 +948,16 @@ func (m schemaMap) diffSet(
|
|||
countStr = ""
|
||||
}
|
||||
|
||||
diff.Attributes[k+".#"] = &terraform.ResourceAttrDiff{
|
||||
diff.Attributes[k+".#"] = countSchema.finalizeDiff(&terraform.ResourceAttrDiff{
|
||||
Old: countStr,
|
||||
NewComputed: true,
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// If the counts are not the same, then record that diff
|
||||
changed := oldLen != newLen
|
||||
if changed || all {
|
||||
countSchema := &Schema{
|
||||
Type: TypeInt,
|
||||
Computed: schema.Computed,
|
||||
ForceNew: schema.ForceNew,
|
||||
}
|
||||
|
||||
diff.Attributes[k+".#"] = countSchema.finalizeDiff(&terraform.ResourceAttrDiff{
|
||||
Old: oldStr,
|
||||
New: newStr,
|
||||
|
|
|
@ -2608,6 +2608,49 @@ func TestSchemaMap_Diff(t *testing.T) {
|
|||
|
||||
Err: false,
|
||||
},
|
||||
|
||||
{
|
||||
Name: "Set ForceNew marks count as ForceNew if computed",
|
||||
Schema: map[string]*Schema{
|
||||
"ports": &Schema{
|
||||
Type: TypeSet,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Elem: &Schema{Type: TypeInt},
|
||||
Set: func(a interface{}) int {
|
||||
return a.(int)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"ports.#": "3",
|
||||
"ports.1": "1",
|
||||
"ports.2": "2",
|
||||
"ports.4": "4",
|
||||
},
|
||||
},
|
||||
|
||||
Config: map[string]interface{}{
|
||||
"ports": []interface{}{"${var.foo}", 2, 1},
|
||||
},
|
||||
|
||||
ConfigVariables: map[string]ast.Variable{
|
||||
"var.foo": interfaceToVariableSwallowError(config.UnknownVariableValue),
|
||||
},
|
||||
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"ports.#": &terraform.ResourceAttrDiff{
|
||||
Old: "3",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
RequiresNew: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range cases {
|
||||
|
|
Loading…
Reference in New Issue