diff --git a/terraform/context.go b/terraform/context.go index 72f6a8813..03394a6a5 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -555,6 +555,13 @@ func (c *Context) applyWalkFn() depgraph.WalkFunc { // defined after the resource creation has already completed. func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) (*ResourceState, error) { var err error + + // Store the original connection info, restore later + origConnInfo := rs.ConnInfo + defer func() { + rs.ConnInfo = origConnInfo + }() + for _, prov := range r.Provisioners { // Interpolate since we may have variables that depend on the // local resource. @@ -562,6 +569,24 @@ func (c *Context) applyProvisioners(r *Resource, rs *ResourceState) (*ResourceSt return rs, err } + // Interpolate the conn info, since it may contain variables + connInfo := NewResourceConfig(prov.ConnInfo) + if err := connInfo.interpolate(c); err != nil { + return rs, err + } + + // Merge the connection information + overlay := make(map[string]interface{}) + if origConnInfo != nil { + for k, v := range origConnInfo.Raw { + overlay[k] = v + } + } + for k, v := range connInfo.Config { + overlay[k] = v + } + rs.ConnInfo = &ResourceConnectionInfo{Raw: overlay} + // Invoke the Provisioner rs, err = prov.Provisioner.Apply(rs, prov.Config) if err != nil { diff --git a/terraform/graph.go b/terraform/graph.go index 445d9e99d..e757c3072 100644 --- a/terraform/graph.go +++ b/terraform/graph.go @@ -546,6 +546,9 @@ func graphAddVariableDeps(g *depgraph.Graph) { for _, p := range m.Resource.Provisioners { vars = p.RawConfig.Variables nounAddVariableDeps(g, n, vars) + + vars = p.ConnInfo.Variables + nounAddVariableDeps(g, n, vars) } case *GraphNodeResourceProvider: @@ -774,6 +777,7 @@ func graphMapResourceProvisioners(g *depgraph.Graph, Provisioner: provisioner, Config: NewResourceConfig(p.RawConfig), RawConfig: p.RawConfig, + ConnInfo: p.ConnInfo, }) } } diff --git a/terraform/resource.go b/terraform/resource.go index 5d7aaee4d..d19949840 100644 --- a/terraform/resource.go +++ b/terraform/resource.go @@ -18,6 +18,7 @@ type ResourceProvisionerConfig struct { Provisioner ResourceProvisioner Config *ResourceConfig RawConfig *config.RawConfig + ConnInfo *config.RawConfig } // Resource encapsulates a resource, its configuration, its provider, diff --git a/terraform/state.go b/terraform/state.go index f8972364a..81bec0b1f 100644 --- a/terraform/state.go +++ b/terraform/state.go @@ -250,14 +250,10 @@ func WriteState(d *State, dst io.Writer) error { // by a provider so that provisioners can connect and run on the // resource. type ResourceConnectionInfo struct { - // Type is set so that an appropriate connection can be formed. - // As an example, for a Linux machine, the Type may be "ssh" - Type string - - // Raw is used to store any relevant keys for the given Type + // Raw is used to store any relevant keys for the given 'type' // so that a provisioner can connect to the resource. This could // contain credentials or address information. - Raw map[string]string + Raw map[string]interface{} } // ResourceState holds the state of a resource that is used so that diff --git a/terraform/state_test.go b/terraform/state_test.go index 53af97908..aa8231729 100644 --- a/terraform/state_test.go +++ b/terraform/state_test.go @@ -99,8 +99,8 @@ func TestReadWriteState(t *testing.T) { "foo": &ResourceState{ ID: "bar", ConnInfo: &ResourceConnectionInfo{ - Type: "ssh", - Raw: map[string]string{ + Raw: map[string]interface{}{ + "type": "ssh", "user": "root", "password": "supersecret", },