diff --git a/terraform/eval_apply.go b/terraform/eval_apply.go index f58ab19f2..2dd9112e3 100644 --- a/terraform/eval_apply.go +++ b/terraform/eval_apply.go @@ -32,7 +32,7 @@ func (n *EvalApply) Eval(ctx EvalContext) (interface{}, error) { state := *n.State // The provider API still expects our legacy InstanceInfo type, so we must shim it. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) if diff.Empty() { log.Printf("[DEBUG] apply %s: diff is empty, so skipping.", n.Addr) @@ -113,7 +113,7 @@ func (n *EvalApplyPre) Eval(ctx EvalContext) (interface{}, error) { // The hook API still uses our legacy InstanceInfo type, so we must // shim it. - legacyInfo := NewInstanceInfo(n.Addr.ContainingResource().Absolute(ctx.Path())) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // If the state is nil, make it non-nil if state == nil { @@ -147,7 +147,7 @@ func (n *EvalApplyPost) Eval(ctx EvalContext) (interface{}, error) { // The hook API still uses our legacy InstanceInfo type, so we must // shim it. - legacyInfo := NewInstanceInfo(n.Addr.ContainingResource().Absolute(ctx.Path())) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) if resourceHasUserVisibleApply(legacyInfo) { // Call post-apply hook @@ -199,7 +199,7 @@ func (n *EvalApplyProvisioners) Eval(ctx EvalContext) (interface{}, error) { state := *n.State // The hook API still uses the legacy InstanceInfo type, so we need to shim it. - legacyInfo := NewInstanceInfo(n.Addr.Resource.Absolute(ctx.Path())) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) if n.CreateNew != nil && !*n.CreateNew { // If we're not creating a new resource, then don't run provisioners @@ -286,7 +286,7 @@ func (n *EvalApplyProvisioners) apply(ctx EvalContext, provs []*configs.Provisio state := *n.State // The hook API still uses the legacy InstanceInfo type, so we need to shim it. - legacyInfo := NewInstanceInfo(n.Addr.Resource.Absolute(ctx.Path())) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // Store the original connection info, restore later origConnInfo := state.Ephemeral.ConnInfo diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index f5884b873..bbd2558fb 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -104,7 +104,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { var diags tfdiags.Diagnostics // The provider and hook APIs still expect our legacy InstanceInfo type. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // State still uses legacy-style internal ids, so we need to shim to get // a suitable key to use. @@ -439,7 +439,7 @@ func (n *EvalDiffDestroy) Eval(ctx EvalContext) (interface{}, error) { } // The provider and hook APIs still expect our legacy InstanceInfo type. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // Call pre-diff hook err := ctx.Hook(func(h Hook) (HookAction, error) { diff --git a/terraform/eval_read_data.go b/terraform/eval_read_data.go index 5b3637cdf..ec50bfe82 100644 --- a/terraform/eval_read_data.go +++ b/terraform/eval_read_data.go @@ -37,7 +37,7 @@ func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) { var diags tfdiags.Diagnostics // The provider and hook APIs still expect our legacy InstanceInfo type. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) err := ctx.Hook(func(h Hook) (HookAction, error) { return h.PreDiff(legacyInfo, nil) @@ -138,7 +138,7 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) { diff := *n.Diff // The provider and hook APIs still expect our legacy InstanceInfo type. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // If the diff is for *destroying* this resource then we'll // just drop its state and move on, since data resources don't diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index 53666e19e..2490a3111 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -22,7 +22,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { state := *n.State // The provider and hook APIs still expect our legacy InstanceInfo type. - legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path()).ContainingResource()) + legacyInfo := NewInstanceInfo(n.Addr.Absolute(ctx.Path())) // If we have no state, we don't do any refreshing if state == nil { diff --git a/terraform/resource.go b/terraform/resource.go index a5fba8392..1d9acbfec 100644 --- a/terraform/resource.go +++ b/terraform/resource.go @@ -105,10 +105,8 @@ type InstanceInfo struct { uniqueExtra string } -// NewInstanceInfo constructs an InstanceInfo from an addrs.AbsResource. +// NewInstanceInfo constructs an InstanceInfo from an addrs.AbsResourceInstance. // -// In spite of the confusing name, an InstanceInfo actually identifies a -// particular resource rather than a particular resource instance. // InstanceInfo is a legacy type, and uses of it should be gradually replaced // by direct use of addrs.AbsResource or addrs.AbsResourceInstance as // appropriate. @@ -117,7 +115,11 @@ type InstanceInfo struct { // keys, so this function will panic if given such a path. Uses of this type // should all be removed or replaced before implementing "count" and "for_each" // arguments on modules in order to avoid such panics. -func NewInstanceInfo(addr addrs.AbsResource) *InstanceInfo { +// +// This legacy type also cannot represent resource instances with string +// instance keys. It will panic if the given key is not either NoKey or an +// IntKey. +func NewInstanceInfo(addr addrs.AbsResourceInstance) *InstanceInfo { // We need an old-style []string module path for InstanceInfo. path := make([]string, len(addr.Module)) for i, step := range addr.Module { @@ -132,15 +134,23 @@ func NewInstanceInfo(addr addrs.AbsResource) *InstanceInfo { // a representation of the resource mode, and so it's impossible to // determine from an InstanceInfo alone whether it is a managed or data // resource that is being referred to. - id := fmt.Sprintf("%s.%s", addr.Resource.Type, addr.Resource.Name) - if addr.Resource.Mode == addrs.DataResourceMode { + id := fmt.Sprintf("%s.%s", addr.Resource.Resource.Type, addr.Resource.Resource.Name) + if addr.Resource.Resource.Mode == addrs.DataResourceMode { id = "data." + id } + if addr.Resource.Key != addrs.NoKey { + switch k := addr.Resource.Key.(type) { + case addrs.IntKey: + id = id + fmt.Sprintf(".%d", int(k)) + default: + panic(fmt.Sprintf("NewInstanceInfo cannot convert resource instance with %T instance key", addr.Resource.Key)) + } + } return &InstanceInfo{ Id: id, ModulePath: path, - Type: addr.Resource.Type, + Type: addr.Resource.Resource.Type, } } diff --git a/terraform/transform_import_state.go b/terraform/transform_import_state.go index 7b15be538..834c40f83 100644 --- a/terraform/transform_import_state.go +++ b/terraform/transform_import_state.go @@ -67,7 +67,7 @@ func (n *graphNodeImportState) Path() addrs.ModuleInstance { // GraphNodeEvalable impl. func (n *graphNodeImportState) EvalTree() EvalNode { var provider ResourceProvider - info := NewInstanceInfo(n.Addr.ContainingResource()) + info := NewInstanceInfo(n.Addr) // Reset our states n.states = nil