diff --git a/helper/schema/schema.go b/helper/schema/schema.go index 050ce11ed7..8c2c206742 100644 --- a/helper/schema/schema.go +++ b/helper/schema/schema.go @@ -583,6 +583,41 @@ func (m schemaMap) diffMap( return fmt.Errorf("%s: %s", k, err) } + // Delete any count values, since we don't use those + delete(configMap, "#") + delete(stateMap, "#") + + // Check if the number of elements has changed. If we're computing + // a list and there isn't a config, then it hasn't changed. + oldLen, newLen := len(stateMap), len(configMap) + changed := oldLen != newLen + if oldLen != 0 && newLen == 0 && schema.Computed { + changed = false + } + computed := oldLen == 0 && newLen == 0 && schema.Computed + if changed || computed { + countSchema := &Schema{ + Type: TypeInt, + Computed: schema.Computed, + ForceNew: schema.ForceNew, + } + + oldStr := strconv.FormatInt(int64(oldLen), 10) + newStr := "" + if !computed { + newStr = strconv.FormatInt(int64(newLen), 10) + } else { + oldStr = "" + } + + diff.Attributes[k+".#"] = countSchema.finalizeDiff( + &terraform.ResourceAttrDiff{ + Old: oldStr, + New: newStr, + }, + ) + } + // If the new map is nil and we're computed, then ignore it. if n == nil && schema.Computed { return nil diff --git a/helper/schema/schema_test.go b/helper/schema/schema_test.go index 9aba383162..fbb4027462 100644 --- a/helper/schema/schema_test.go +++ b/helper/schema/schema_test.go @@ -1205,6 +1205,11 @@ func TestSchemaMap_Diff(t *testing.T) { Diff: &terraform.InstanceDiff{ Attributes: map[string]*terraform.ResourceAttrDiff{ + "config_vars.#": &terraform.ResourceAttrDiff{ + Old: "0", + New: "1", + }, + "config_vars.bar": &terraform.ResourceAttrDiff{ Old: "", New: "baz", @@ -1381,6 +1386,10 @@ func TestSchemaMap_Diff(t *testing.T) { Old: "1", New: "0", }, + "config_vars.0.#": &terraform.ResourceAttrDiff{ + Old: "2", + New: "0", + }, "config_vars.0.foo": &terraform.ResourceAttrDiff{ Old: "bar", NewRemoved: true, @@ -1663,6 +1672,68 @@ func TestSchemaMap_Diff(t *testing.T) { Err: false, }, + + // #43 - Computed maps + { + Schema: map[string]*Schema{ + "vars": &Schema{ + Type: TypeMap, + Computed: true, + }, + }, + + State: nil, + + Config: nil, + + Diff: &terraform.InstanceDiff{ + Attributes: map[string]*terraform.ResourceAttrDiff{ + "vars.#": &terraform.ResourceAttrDiff{ + Old: "", + NewComputed: true, + }, + }, + }, + + Err: false, + }, + + // #44 - Computed maps + { + Schema: map[string]*Schema{ + "vars": &Schema{ + Type: TypeMap, + Computed: true, + }, + }, + + State: &terraform.InstanceState{ + Attributes: map[string]string{ + "vars.#": "0", + }, + }, + + Config: map[string]interface{}{ + "vars": map[string]interface{}{ + "bar": "${var.foo}", + }, + }, + + ConfigVariables: map[string]string{ + "var.foo": config.UnknownVariableValue, + }, + + Diff: &terraform.InstanceDiff{ + Attributes: map[string]*terraform.ResourceAttrDiff{ + "vars.#": &terraform.ResourceAttrDiff{ + Old: "", + NewComputed: true, + }, + }, + }, + + Err: false, + }, } for i, tc := range cases {