diff --git a/terraform/context.go b/terraform/context.go index 32d93cafe..cb598da65 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -75,9 +75,11 @@ func NewContext(opts *ContextOpts) *Context { // Calculate all the default variables defaultVars := make(map[string]string) - for _, v := range opts.Config.Variables { - for k, val := range v.DefaultsMap() { - defaultVars[k] = val + if opts.Config != nil { + for _, v := range opts.Config.Variables { + for k, val := range v.DefaultsMap() { + defaultVars[k] = val + } } } diff --git a/terraform/resource.go b/terraform/resource.go index 33737a795..b5a29c155 100644 --- a/terraform/resource.go +++ b/terraform/resource.go @@ -89,9 +89,43 @@ func (c *ResourceConfig) CheckSet(keys []string) []error { // The second return value is true if the get was successful. Get will // not succeed if the value is being computed. func (c *ResourceConfig) Get(k string) (interface{}, bool) { + result, ok := c.get(k, c.Config) + if ok { + return result, ok + } + + return c.get(k, c.Raw) +} + +// IsSet checks if the key in the configuration is set. A key is set if +// it has a value or the value is being computed (is unknown currently). +// +// This function should be used rather than checking the keys of the +// raw configuration itself, since a key may be omitted from the raw +// configuration if it is being computed. +func (c *ResourceConfig) IsSet(k string) bool { + if c == nil { + return false + } + + for _, ck := range c.ComputedKeys { + if ck == k { + return true + } + } + + if _, ok := c.Get(k); ok { + return true + } + + return false +} + +func (c *ResourceConfig) get( + k string, raw map[string]interface{}) (interface{}, bool) { parts := strings.Split(k, ".") - var current interface{} = c.Raw + var current interface{} = raw for _, part := range parts { if current == nil { return nil, false @@ -123,30 +157,6 @@ func (c *ResourceConfig) Get(k string) (interface{}, bool) { return current, true } -// IsSet checks if the key in the configuration is set. A key is set if -// it has a value or the value is being computed (is unknown currently). -// -// This function should be used rather than checking the keys of the -// raw configuration itself, since a key may be omitted from the raw -// configuration if it is being computed. -func (c *ResourceConfig) IsSet(k string) bool { - if c == nil { - return false - } - - for _, ck := range c.ComputedKeys { - if ck == k { - return true - } - } - - if _, ok := c.Get(k); ok { - return true - } - - return false -} - func (c *ResourceConfig) interpolate(ctx *Context) error { if c == nil { return nil diff --git a/terraform/resource_test.go b/terraform/resource_test.go index 9837cee29..a7d4b75db 100644 --- a/terraform/resource_test.go +++ b/terraform/resource_test.go @@ -3,6 +3,8 @@ package terraform import ( "reflect" "testing" + + "github.com/hashicorp/terraform/config" ) func TestResource_Vars(t *testing.T) { @@ -29,3 +31,49 @@ func TestResource_Vars(t *testing.T) { t.Fatalf("bad: %#v", actual) } } + +func TestResourceConfigGet(t *testing.T) { + cases := []struct { + Config map[string]interface{} + Vars map[string]string + Key string + Value interface{} + }{ + { + Config: map[string]interface{}{ + "foo": "${var.foo}", + }, + Key: "foo", + Value: "${var.foo}", + }, + + { + Config: map[string]interface{}{ + "foo": "${var.foo}", + }, + Vars: map[string]string{"foo": "bar"}, + Key: "foo", + Value: "bar", + }, + } + + for i, tc := range cases { + rawC, err := config.NewRawConfig(tc.Config) + if err != nil { + t.Fatalf("err: %s", err) + } + rc := NewResourceConfig(rawC) + + if tc.Vars != nil { + ctx := NewContext(&ContextOpts{Variables: tc.Vars}) + if err := rc.interpolate(ctx); err != nil { + t.Fatalf("err: %s", err) + } + } + + v, _ := rc.Get(tc.Key) + if !reflect.DeepEqual(v, tc.Value) { + t.Fatalf("%d bad: %#v", i, v) + } + } +}