diff --git a/terraform/eval_output.go b/terraform/eval_output.go index bee4f1084..cf61781e5 100644 --- a/terraform/eval_output.go +++ b/terraform/eval_output.go @@ -98,6 +98,19 @@ func (n *EvalWriteOutput) Eval(ctx EvalContext) (interface{}, error) { Sensitive: n.Sensitive, Value: valueTyped, } + case []map[string]interface{}: + // an HCL map is multi-valued, so if this was read out of a config the + // map may still be in a slice. + if len(valueTyped) == 1 { + mod.Outputs[n.Name] = &OutputState{ + Type: "map", + Sensitive: n.Sensitive, + Value: valueTyped[0], + } + break + } + return nil, fmt.Errorf("output %s type (%T) with %d values not valid for type map", + n.Name, valueTyped, len(valueTyped)) default: return nil, fmt.Errorf("output %s is not a valid type (%T)\n", n.Name, valueTyped) } diff --git a/terraform/eval_output_test.go b/terraform/eval_output_test.go new file mode 100644 index 000000000..f73b127de --- /dev/null +++ b/terraform/eval_output_test.go @@ -0,0 +1,56 @@ +package terraform + +import ( + "sync" + "testing" +) + +func TestEvalWriteMapOutput(t *testing.T) { + ctx := new(MockEvalContext) + ctx.StateState = NewState() + ctx.StateLock = new(sync.RWMutex) + + cases := []struct { + name string + cfg *ResourceConfig + err bool + }{ + { + // Eval should recognize a single map in a slice, and collapse it + // into the map value + "single-map", + &ResourceConfig{ + Config: map[string]interface{}{ + "value": []map[string]interface{}{ + map[string]interface{}{"a": "b"}, + }, + }, + }, + false, + }, + { + // we can't apply a multi-valued map to a variable, so this should error + "multi-map", + &ResourceConfig{ + Config: map[string]interface{}{ + "value": []map[string]interface{}{ + map[string]interface{}{"a": "b"}, + map[string]interface{}{"c": "d"}, + }, + }, + }, + true, + }, + } + + for _, tc := range cases { + evalNode := &EvalWriteOutput{Name: tc.name} + ctx.InterpolateConfigResult = tc.cfg + t.Run(tc.name, func(t *testing.T) { + _, err := evalNode.Eval(ctx) + if err != nil && !tc.err { + t.Fatal(err) + } + }) + } +}