diff --git a/go.mod b/go.mod index 876f395fe3b1..615edd8a1442 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/hcl v1.0.0 - github.com/hashicorp/hcl/v2 v2.20.0 + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a github.com/hashicorp/jsonapi v1.3.1 github.com/hashicorp/terraform-registry-address v0.2.3 github.com/hashicorp/terraform-svchost v0.1.1 diff --git a/go.sum b/go.sum index 846610507fd5..0e58e07b35cb 100644 --- a/go.sum +++ b/go.sum @@ -279,8 +279,6 @@ github.com/antchfx/xpath v1.1.10/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByN github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA= -github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM= github.com/apparentlymart/go-shquot v0.0.1 h1:MGV8lwxF4zw75lN7e0MGs7o6AFYn7L6AZaExUpLh0Mo= github.com/apparentlymart/go-shquot v0.0.1/go.mod h1:lw58XsE5IgUXZ9h0cxnypdx31p9mPFIVEQ9P3c7MlrU= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= @@ -705,8 +703,8 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= -github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a h1:pIZ61qH0Iq0v+GPTsnWlx46HDgvDQBysVjtCRX0ojpw= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/jsonapi v1.3.1 h1:GtPvnmcWgYwCuDGvYT5VZBHcUyFdq9lSyCzDjn1DdPo= github.com/hashicorp/jsonapi v1.3.1/go.mod h1:kWfdn49yCjQvbpnvY1dxxAuAFzISwrrMDQOcu6NsFoM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -961,8 +959,6 @@ github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= diff --git a/internal/addrs/checkable.go b/internal/addrs/checkable.go index 6db6b86646ab..e0c41a17ae19 100644 --- a/internal/addrs/checkable.go +++ b/internal/addrs/checkable.go @@ -100,7 +100,7 @@ func ParseCheckableStr(kind CheckableKind, src string) (Checkable, tfdiags.Diagn return nil, diags } - path, remain, diags := parseModuleInstancePrefix(traversal) + path, remain, diags := parseModuleInstancePrefix(traversal, false) if diags.HasErrors() { return nil, diags } @@ -157,7 +157,7 @@ func ParseCheckableStr(kind CheckableKind, src string) (Checkable, tfdiags.Diagn // might be a resource whose type is literally "output". switch kind { case CheckableResource: - riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain) + riAddr, moreDiags := parseResourceInstanceUnderModule(path, false, remain) diags = diags.Append(moreDiags) if diags.HasErrors() { return nil, diags diff --git a/internal/addrs/instance_key.go b/internal/addrs/instance_key.go index cfd918af2862..1340edee8145 100644 --- a/internal/addrs/instance_key.go +++ b/internal/addrs/instance_key.go @@ -56,7 +56,23 @@ var NoKey InstanceKey // WildcardKey represents the "unknown" value of an InstanceKey. This is used // within the deferral logic to express absolute module and resource addresses // that are not known at the time of planning. -var WildcardKey InstanceKey = StringKey("*") +var WildcardKey InstanceKey = &wildcardKey{} + +// wildcardKey is a special kind of InstanceKey that represents the "unknown" +// value of an InstanceKey. This is used within the deferral logic to express +// absolute module and resource addresses that are not known at the time of +// planning. +type wildcardKey struct{} + +func (w *wildcardKey) instanceKeySigil() {} + +func (w *wildcardKey) String() string { + return "[*]" +} + +func (w *wildcardKey) Value() cty.Value { + return cty.DynamicVal +} // IntKey is the InstanceKey representation representing integer indices, as // used when the "count" argument is specified or if for_each is used with diff --git a/internal/addrs/module_instance.go b/internal/addrs/module_instance.go index a0e06b839eb7..5ebce0ab95d9 100644 --- a/internal/addrs/module_instance.go +++ b/internal/addrs/module_instance.go @@ -30,7 +30,7 @@ var ( ) func ParseModuleInstance(traversal hcl.Traversal) (ModuleInstance, tfdiags.Diagnostics) { - mi, remain, diags := parseModuleInstancePrefix(traversal) + mi, remain, diags := parseModuleInstancePrefix(traversal, false) if len(remain) != 0 { if len(remain) == len(traversal) { diags = diags.Append(&hcl.Diagnostic{ @@ -80,7 +80,7 @@ func ParseModuleInstanceStr(str string) (ModuleInstance, tfdiags.Diagnostics) { return addr, diags } -func parseModuleInstancePrefix(traversal hcl.Traversal) (ModuleInstance, hcl.Traversal, tfdiags.Diagnostics) { +func parseModuleInstancePrefix(traversal hcl.Traversal, allowPartial bool) (ModuleInstance, hcl.Traversal, tfdiags.Diagnostics) { remain := traversal var mi ModuleInstance var diags tfdiags.Diagnostics @@ -141,7 +141,8 @@ LOOP: } if len(remain) > 0 { - if idx, ok := remain[0].(hcl.TraverseIndex); ok { + switch idx := remain[0].(type) { + case hcl.TraverseIndex: remain = remain[1:] switch idx.Key.Type() { @@ -169,6 +170,12 @@ LOOP: Subject: idx.SourceRange().Ptr(), }) } + + case hcl.TraverseSplat: + if allowPartial { + remain = remain[1:] + step.InstanceKey = WildcardKey + } } } diff --git a/internal/addrs/move_endpoint.go b/internal/addrs/move_endpoint.go index 4f61e66a5acd..3bfa86e5718e 100644 --- a/internal/addrs/move_endpoint.go +++ b/internal/addrs/move_endpoint.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/terraform/internal/tfdiags" ) @@ -126,7 +127,7 @@ func (e *MoveEndpoint) ConfigMoveable(baseModule Module) ConfigMoveable { // it with the address of the module where it was declared in order to get // an absolute address relative to the root module. func ParseMoveEndpoint(traversal hcl.Traversal) (*MoveEndpoint, tfdiags.Diagnostics) { - path, remain, diags := parseModuleInstancePrefix(traversal) + path, remain, diags := parseModuleInstancePrefix(traversal, false) if diags.HasErrors() { return nil, diags } @@ -140,7 +141,7 @@ func ParseMoveEndpoint(traversal hcl.Traversal) (*MoveEndpoint, tfdiags.Diagnost }, diags } - riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain) + riAddr, moreDiags := parseResourceInstanceUnderModule(path, false, remain) diags = diags.Append(moreDiags) if diags.HasErrors() { return nil, diags diff --git a/internal/addrs/output_value.go b/internal/addrs/output_value.go index 78ef98bc9aa4..0c23b0cdb941 100644 --- a/internal/addrs/output_value.go +++ b/internal/addrs/output_value.go @@ -126,7 +126,7 @@ type absOutputValueUniqueKey string func (k absOutputValueUniqueKey) uniqueKeySigil() {} func ParseAbsOutputValue(traversal hcl.Traversal) (AbsOutputValue, tfdiags.Diagnostics) { - path, remain, diags := parseModuleInstancePrefix(traversal) + path, remain, diags := parseModuleInstancePrefix(traversal, false) if diags.HasErrors() { return AbsOutputValue{}, diags } diff --git a/internal/addrs/parse_target.go b/internal/addrs/parse_target.go index b84515b42aad..dd9d7a46a794 100644 --- a/internal/addrs/parse_target.go +++ b/internal/addrs/parse_target.go @@ -6,9 +6,9 @@ package addrs import ( "fmt" + "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" - "github.com/hashicorp/hcl/v2" "github.com/hashicorp/terraform/internal/tfdiags" ) @@ -28,7 +28,19 @@ type Target struct { // If error diagnostics are returned then the Target value is invalid and // must not be used. func ParseTarget(traversal hcl.Traversal) (*Target, tfdiags.Diagnostics) { - path, remain, diags := parseModuleInstancePrefix(traversal) + return parseTarget(traversal, false) +} + +// ParsePartialTarget is like ParseTarget, but it allows the given traversal +// to support the [*] wildcard syntax for resource instances. These indicate +// a "partial" resource address that refers to all potential instances of a +// resource or module. +func ParsePartialTarget(traversal hcl.Traversal) (*Target, tfdiags.Diagnostics) { + return parseTarget(traversal, true) +} + +func parseTarget(traversal hcl.Traversal, allowPartial bool) (*Target, tfdiags.Diagnostics) { + path, remain, diags := parseModuleInstancePrefix(traversal, allowPartial) if diags.HasErrors() { return nil, diags } @@ -42,7 +54,7 @@ func ParseTarget(traversal hcl.Traversal) (*Target, tfdiags.Diagnostics) { }, diags } - riAddr, moreDiags := parseResourceInstanceUnderModule(path, remain) + riAddr, moreDiags := parseResourceInstanceUnderModule(path, allowPartial, remain) diags = diags.Append(moreDiags) if diags.HasErrors() { return nil, diags @@ -150,7 +162,7 @@ func parseConfigResourceUnderModule(moduleAddr Module, remain hcl.Traversal) (Co }, diags } -func parseResourceInstanceUnderModule(moduleAddr ModuleInstance, remain hcl.Traversal) (AbsResourceInstance, tfdiags.Diagnostics) { +func parseResourceInstanceUnderModule(moduleAddr ModuleInstance, allowPartial bool, remain hcl.Traversal) (AbsResourceInstance, tfdiags.Diagnostics) { // Note that this helper is used as part of both ParseTarget and // ParseMoveEndpoint, so its error messages should be generic // enough to suit both situations. @@ -219,7 +231,8 @@ func parseResourceInstanceUnderModule(moduleAddr ModuleInstance, remain hcl.Trav case 0: return moduleAddr.ResourceInstance(mode, typeName, name, NoKey), diags case 1: - if tt, ok := remain[0].(hcl.TraverseIndex); ok { + switch tt := remain[0].(type) { + case hcl.TraverseIndex: key, err := ParseInstanceKey(tt.Key) if err != nil { diags = diags.Append(&hcl.Diagnostic{ @@ -232,7 +245,20 @@ func parseResourceInstanceUnderModule(moduleAddr ModuleInstance, remain hcl.Trav } return moduleAddr.ResourceInstance(mode, typeName, name, key), diags - } else { + case hcl.TraverseSplat: + if allowPartial { + return moduleAddr.ResourceInstance(mode, typeName, name, WildcardKey), diags + } + + // Otherwise, return an error. + diags = diags.Append(&hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Invalid address", + Detail: "Resource instance key must be given in square brackets.", + Subject: remain[0].SourceRange().Ptr(), + }) + return AbsResourceInstance{}, diags + default: diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid address", @@ -369,11 +395,39 @@ func ParseAbsResourceStr(str string) (AbsResource, tfdiags.Diagnostics) { // If error diagnostics are returned then the AbsResource value is invalid and // must not be used. func ParseAbsResourceInstance(traversal hcl.Traversal) (AbsResourceInstance, tfdiags.Diagnostics) { - addr, diags := ParseTarget(traversal) + target, diags := ParseTarget(traversal) + if diags.HasErrors() { + return AbsResourceInstance{}, diags + } + + addr, validateDiags := validateResourceFromTarget(target, traversal.SourceRange().Ptr()) + diags = diags.Append(validateDiags) + return addr, diags +} + +// ParsePartialResourceInstance attempts to interpret the given traversal as a +// partial absolute resource instance address, using the same syntax as expected +// by ParsePartialTarget. +// +// If no error diagnostics are returned, the returned target includes the +// address that was extracted and the source range it was extracted from. +// +// If error diagnostics are returned then the AbsResource value is invalid and +// must not be used. +func ParsePartialResourceInstance(traversal hcl.Traversal) (AbsResourceInstance, tfdiags.Diagnostics) { + target, diags := ParsePartialTarget(traversal) if diags.HasErrors() { return AbsResourceInstance{}, diags } + addr, validateDiags := validateResourceFromTarget(target, traversal.SourceRange().Ptr()) + diags = diags.Append(validateDiags) + return addr, diags +} + +func validateResourceFromTarget(addr *Target, src *hcl.Range) (AbsResourceInstance, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + switch tt := addr.Subject.(type) { case AbsResource: @@ -387,7 +441,7 @@ func ParseAbsResourceInstance(traversal hcl.Traversal) (AbsResourceInstance, tfd Severity: hcl.DiagError, Summary: "Invalid address", Detail: "A resource instance address is required here. The module path must be followed by a resource instance specification.", - Subject: traversal.SourceRange().Ptr(), + Subject: src, }) return AbsResourceInstance{}, diags @@ -396,7 +450,7 @@ func ParseAbsResourceInstance(traversal hcl.Traversal) (AbsResourceInstance, tfd Severity: hcl.DiagError, Summary: "Invalid address", Detail: "A resource address is required here.", - Subject: traversal.SourceRange().Ptr(), + Subject: src, }) return AbsResourceInstance{}, diags @@ -429,6 +483,32 @@ func ParseAbsResourceInstanceStr(str string) (AbsResourceInstance, tfdiags.Diagn return addr, diags } +// ParsePartialResourceInstanceStr is a helper wrapper around +// ParsePartialResourceInstance that takes a string and parses it with the HCL +// native syntax traversal parser before interpreting it. +// +// Error diagnostics are returned if either the parsing fails or the analysis +// of the traversal fails. There is no way for the caller to distinguish the +// two kinds of diagnostics programmatically. If error diagnostics are returned +// the returned address may be incomplete. +// +// Since this function has no context about the source of the given string, +// any returned diagnostics will not have meaningful source location +// information. +func ParsePartialResourceInstanceStr(str string) (AbsResourceInstance, tfdiags.Diagnostics) { + var diags tfdiags.Diagnostics + + traversal, parseDiags := hclsyntax.ParseTraversalPartial([]byte(str), "", hcl.Pos{Line: 1, Column: 1}) + diags = diags.Append(parseDiags) + if parseDiags.HasErrors() { + return AbsResourceInstance{}, diags + } + + addr, addrDiags := ParsePartialResourceInstance(traversal) + diags = diags.Append(addrDiags) + return addr, diags +} + // ModuleAddr returns the module address portion of the subject of // the recieving target. // diff --git a/internal/addrs/provider_config.go b/internal/addrs/provider_config.go index 317c25006bd3..21f36fc70fc6 100644 --- a/internal/addrs/provider_config.go +++ b/internal/addrs/provider_config.go @@ -7,9 +7,10 @@ import ( "fmt" "strings" - "github.com/hashicorp/terraform/internal/tfdiags" "github.com/zclconf/go-cty/cty" + "github.com/hashicorp/terraform/internal/tfdiags" + "github.com/hashicorp/hcl/v2" "github.com/hashicorp/hcl/v2/hclsyntax" ) @@ -121,7 +122,7 @@ var _ UniqueKeyer = AbsProviderConfig{} // This type of address is typically not used prominently in the UI, except in // error messages that refer to provider configurations. func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) { - modInst, remain, diags := parseModuleInstancePrefix(traversal) + modInst, remain, diags := parseModuleInstancePrefix(traversal, false) var ret AbsProviderConfig // Providers cannot resolve within module instances, so verify that there @@ -260,7 +261,7 @@ func ParseLegacyAbsProviderConfigStr(str string) (AbsProviderConfig, tfdiags.Dia // // We will not use this address form for any new file formats. func ParseLegacyAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) { - modInst, remain, diags := parseModuleInstancePrefix(traversal) + modInst, remain, diags := parseModuleInstancePrefix(traversal, false) var ret AbsProviderConfig // Providers cannot resolve within module instances, so verify that there diff --git a/internal/backend/remote-state/azure/go.mod b/internal/backend/remote-state/azure/go.mod index 9e99034175bd..b1d6a34645b8 100644 --- a/internal/backend/remote-state/azure/go.mod +++ b/internal/backend/remote-state/azure/go.mod @@ -40,7 +40,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/kr/pretty v0.3.0 // indirect diff --git a/internal/backend/remote-state/azure/go.sum b/internal/backend/remote-state/azure/go.sum index c479cde1ef0b..6f4f31f1c164 100644 --- a/internal/backend/remote-state/azure/go.sum +++ b/internal/backend/remote-state/azure/go.sum @@ -243,6 +243,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/consul/go.mod b/internal/backend/remote-state/consul/go.mod index 662660179c2a..f6c634cc4d80 100644 --- a/internal/backend/remote-state/consul/go.mod +++ b/internal/backend/remote-state/consul/go.mod @@ -28,7 +28,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v0.5.1 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/serf v0.9.6 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect diff --git a/internal/backend/remote-state/consul/go.sum b/internal/backend/remote-state/consul/go.sum index f6df4fcd603e..694add770e51 100644 --- a/internal/backend/remote-state/consul/go.sum +++ b/internal/backend/remote-state/consul/go.sum @@ -217,6 +217,7 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= diff --git a/internal/backend/remote-state/cos/go.mod b/internal/backend/remote-state/cos/go.mod index 375002b11c26..f7e1b23e50c5 100644 --- a/internal/backend/remote-state/cos/go.mod +++ b/internal/backend/remote-state/cos/go.mod @@ -22,7 +22,7 @@ require ( github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/internal/backend/remote-state/cos/go.sum b/internal/backend/remote-state/cos/go.sum index 6cfeeb0e1e16..fd0474903b73 100644 --- a/internal/backend/remote-state/cos/go.sum +++ b/internal/backend/remote-state/cos/go.sum @@ -185,6 +185,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/gcs/go.mod b/internal/backend/remote-state/gcs/go.mod index 69c2fe3a494b..842b3df20376 100644 --- a/internal/backend/remote-state/gcs/go.mod +++ b/internal/backend/remote-state/gcs/go.mod @@ -34,7 +34,7 @@ require ( github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/internal/backend/remote-state/gcs/go.sum b/internal/backend/remote-state/gcs/go.sum index 3f5724bf62e3..4745d56470bc 100644 --- a/internal/backend/remote-state/gcs/go.sum +++ b/internal/backend/remote-state/gcs/go.sum @@ -196,6 +196,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/kubernetes/go.mod b/internal/backend/remote-state/kubernetes/go.mod index fe51a8e25275..b81056642e8c 100644 --- a/internal/backend/remote-state/kubernetes/go.mod +++ b/internal/backend/remote-state/kubernetes/go.mod @@ -41,7 +41,7 @@ require ( github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/imdario/mergo v0.3.13 // indirect diff --git a/internal/backend/remote-state/kubernetes/go.sum b/internal/backend/remote-state/kubernetes/go.sum index a93de7d755ab..2b617a10e299 100644 --- a/internal/backend/remote-state/kubernetes/go.sum +++ b/internal/backend/remote-state/kubernetes/go.sum @@ -227,6 +227,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/oss/go.mod b/internal/backend/remote-state/oss/go.mod index 1883b4f9fe6e..629739e273fd 100644 --- a/internal/backend/remote-state/oss/go.mod +++ b/internal/backend/remote-state/oss/go.mod @@ -24,7 +24,7 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/json-iterator/go v1.1.12 // indirect diff --git a/internal/backend/remote-state/oss/go.sum b/internal/backend/remote-state/oss/go.sum index 2cbdb9d71fd6..f6ee2f44d09c 100644 --- a/internal/backend/remote-state/oss/go.sum +++ b/internal/backend/remote-state/oss/go.sum @@ -190,6 +190,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/pg/go.mod b/internal/backend/remote-state/pg/go.mod index e11e88976d4a..ac757ca37cd6 100644 --- a/internal/backend/remote-state/pg/go.mod +++ b/internal/backend/remote-state/pg/go.mod @@ -4,7 +4,7 @@ go 1.22.0 require ( github.com/hashicorp/go-uuid v1.0.3 - github.com/hashicorp/hcl/v2 v2.20.0 + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a github.com/hashicorp/terraform v0.0.0-00010101000000-000000000000 github.com/hashicorp/terraform/internal/legacy v0.0.0-00010101000000-000000000000 github.com/lib/pq v1.10.3 diff --git a/internal/backend/remote-state/pg/go.sum b/internal/backend/remote-state/pg/go.sum index 9e3c308b38b8..f08cd40560ed 100644 --- a/internal/backend/remote-state/pg/go.sum +++ b/internal/backend/remote-state/pg/go.sum @@ -178,6 +178,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/backend/remote-state/s3/go.mod b/internal/backend/remote-state/s3/go.mod index 278364b97196..b7a081851978 100644 --- a/internal/backend/remote-state/s3/go.mod +++ b/internal/backend/remote-state/s3/go.mod @@ -13,7 +13,7 @@ require ( github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.45 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-uuid v1.0.3 - github.com/hashicorp/hcl/v2 v2.20.0 + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a github.com/hashicorp/terraform v0.0.0-00010101000000-000000000000 github.com/zclconf/go-cty v1.14.3 ) diff --git a/internal/backend/remote-state/s3/go.sum b/internal/backend/remote-state/s3/go.sum index 71ae992de5cd..6ceead4b80a1 100644 --- a/internal/backend/remote-state/s3/go.sum +++ b/internal/backend/remote-state/s3/go.sum @@ -237,6 +237,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= diff --git a/internal/legacy/go.mod b/internal/legacy/go.mod index 6447d96741dd..f703d616f0c4 100644 --- a/internal/legacy/go.mod +++ b/internal/legacy/go.mod @@ -20,7 +20,7 @@ require ( github.com/apparentlymart/go-versions v1.0.1 // indirect github.com/hashicorp/go-slug v0.14.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.20.0 // indirect + github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect diff --git a/internal/legacy/go.sum b/internal/legacy/go.sum index e715f2ac95b8..bcca87052216 100644 --- a/internal/legacy/go.sum +++ b/internal/legacy/go.sum @@ -175,6 +175,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4= github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk= +github.com/hashicorp/hcl/v2 v2.20.2-0.20240408171805-5fdb81b0624a/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= diff --git a/internal/plans/planfile/tfplan.go b/internal/plans/planfile/tfplan.go index ca792ab6252e..9b52862b8f79 100644 --- a/internal/plans/planfile/tfplan.go +++ b/internal/plans/planfile/tfplan.go @@ -20,6 +20,7 @@ import ( "github.com/hashicorp/terraform/internal/plans/planproto" "github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/states" + "github.com/hashicorp/terraform/internal/tfdiags" "github.com/hashicorp/terraform/version" ) @@ -107,7 +108,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { plan.Checks = checkResults for _, rawRC := range rawPlan.ResourceChanges { - change, err := resourceChangeFromTfplan(rawRC) + change, err := resourceChangeFromTfplan(rawRC, addrs.ParseAbsResourceInstanceStr) if err != nil { // errors from resourceChangeFromTfplan already include context return nil, err @@ -117,7 +118,7 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { } for _, rawRC := range rawPlan.ResourceDrift { - change, err := resourceChangeFromTfplan(rawRC) + change, err := resourceChangeFromTfplan(rawRC, addrs.ParsePartialResourceInstanceStr) if err != nil { // errors from resourceChangeFromTfplan already include context return nil, err @@ -203,10 +204,10 @@ func readTfplan(r io.Reader) (*plans.Plan, error) { // This is used by the stackplan package, which includes planproto messages // in its own wire format while using a different overall container. func ResourceChangeFromProto(rawChange *planproto.ResourceInstanceChange) (*plans.ResourceInstanceChangeSrc, error) { - return resourceChangeFromTfplan(rawChange) + return resourceChangeFromTfplan(rawChange, addrs.ParseAbsResourceInstanceStr) } -func resourceChangeFromTfplan(rawChange *planproto.ResourceInstanceChange) (*plans.ResourceInstanceChangeSrc, error) { +func resourceChangeFromTfplan(rawChange *planproto.ResourceInstanceChange, parseAddr func(str string) (addrs.AbsResourceInstance, tfdiags.Diagnostics)) (*plans.ResourceInstanceChangeSrc, error) { if rawChange == nil { // Should never happen in practice, since protobuf can't represent // a nil value in a list. @@ -223,7 +224,7 @@ func resourceChangeFromTfplan(rawChange *planproto.ResourceInstanceChange) (*pla return nil, fmt.Errorf("no instance address for resource instance change; perhaps this plan was created by a different version of Terraform?") } - instAddr, diags := addrs.ParseAbsResourceInstanceStr(rawChange.Addr) + instAddr, diags := parseAddr(rawChange.Addr) if diags.HasErrors() { return nil, fmt.Errorf("invalid resource instance address %q: %w", rawChange.Addr, diags.Err()) } @@ -448,7 +449,7 @@ func deferredChangeFromTfplan(dc *planproto.DeferredResourceInstanceChange) (*pl return nil, fmt.Errorf("deferred change object is absent") } - change, err := resourceChangeFromTfplan(dc.Change) + change, err := resourceChangeFromTfplan(dc.Change, addrs.ParsePartialResourceInstanceStr) if err != nil { return nil, err } diff --git a/internal/plans/planfile/tfplan_test.go b/internal/plans/planfile/tfplan_test.go index 2a6cd1256d13..51957723d9fe 100644 --- a/internal/plans/planfile/tfplan_test.go +++ b/internal/plans/planfile/tfplan_test.go @@ -219,6 +219,35 @@ func TestTFPlanRoundTrip(t *testing.T) { }, }, }, + { + DeferredReason: providers.DeferredReasonInstanceCountUnknown, + ChangeSrc: &plans.ResourceInstanceChangeSrc{ + Addr: addrs.Resource{ + Mode: addrs.ManagedResourceMode, + Type: "test_thing", + Name: "woot", + }.Instance(addrs.WildcardKey).Absolute(addrs.ModuleInstance{ + addrs.ModuleInstanceStep{ + Name: "mod", + InstanceKey: addrs.WildcardKey, + }, + }), + ProviderAddr: addrs.AbsProviderConfig{ + Provider: addrs.NewDefaultProvider("test"), + Module: addrs.RootModule, + }, + ChangeSrc: plans.ChangeSrc{ + Action: plans.Create, + After: mustNewDynamicValue(cty.ObjectVal(map[string]cty.Value{ + "id": cty.UnknownVal(cty.String), + "boop": cty.ListVal([]cty.Value{ + cty.StringVal("beep"), + cty.StringVal("bonk"), + }), + }), objTy), + }, + }, + }, }, RelevantAttributes: []globalref.ResourceAttr{ { diff --git a/internal/terraform/context_apply_deferred_test.go b/internal/terraform/context_apply_deferred_test.go index f1d311b5aa3f..cc68c1e0e672 100644 --- a/internal/terraform/context_apply_deferred_test.go +++ b/internal/terraform/context_apply_deferred_test.go @@ -153,8 +153,8 @@ output "c" { // have any action at this stage. }, wantDeferred: map[string]providers.DeferredReason{ - "test.b[\"*\"]": providers.DeferredReasonInstanceCountUnknown, - "test.c": providers.DeferredReasonDeferredPrereq, + "test.b[*]": providers.DeferredReasonInstanceCountUnknown, + "test.c": providers.DeferredReasonDeferredPrereq, }, wantApplied: map[string]cty.Value{ "a": cty.ObjectVal(map[string]cty.Value{ @@ -434,8 +434,8 @@ resource "test" "c" { "test.a": plans.Create, }, wantDeferred: map[string]providers.DeferredReason{ - "test.b[\"*\"]": providers.DeferredReasonInstanceCountUnknown, - "test.c": providers.DeferredReasonDeferredPrereq, + "test.b[*]": providers.DeferredReasonInstanceCountUnknown, + "test.c": providers.DeferredReasonDeferredPrereq, }, wantApplied: map[string]cty.Value{ "a": cty.ObjectVal(map[string]cty.Value{ @@ -551,8 +551,8 @@ output "names" { }, wantActions: map[string]plans.Action{}, wantDeferred: map[string]providers.DeferredReason{ - "module.mod.test.names[\"*\"]": providers.DeferredReasonInstanceCountUnknown, - "test.a": providers.DeferredReasonDeferredPrereq, + "module.mod.test.names[*]": providers.DeferredReasonInstanceCountUnknown, + "test.a": providers.DeferredReasonDeferredPrereq, }, wantApplied: make(map[string]cty.Value), wantOutputs: make(map[string]cty.Value), @@ -693,7 +693,7 @@ resource "test" "c" { "test.b": plans.DeleteThenCreate, }, wantDeferred: map[string]providers.DeferredReason{ - "test.c[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.c[*]": providers.DeferredReasonInstanceCountUnknown, }, }, }, @@ -792,7 +792,7 @@ import { }, wantActions: make(map[string]plans.Action), wantDeferred: map[string]providers.DeferredReason{ - "test.a[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.a[*]": providers.DeferredReasonInstanceCountUnknown, }, wantApplied: make(map[string]cty.Value), wantOutputs: make(map[string]cty.Value), @@ -865,7 +865,7 @@ resource "test" "c" { "test.b": plans.Create, }, wantDeferred: map[string]providers.DeferredReason{ - "test.a[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.a[*]": providers.DeferredReasonInstanceCountUnknown, }, allowWarnings: true, }, @@ -895,7 +895,7 @@ resource "test" "c" { "test.b": plans.Create, }, wantDeferred: map[string]providers.DeferredReason{ - "test.a[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.a[*]": providers.DeferredReasonInstanceCountUnknown, }, allowWarnings: true, }, @@ -1099,7 +1099,7 @@ resource "test" "c" { "test.c": plans.NoOp, }, wantDeferred: map[string]providers.DeferredReason{ - "test.a[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.a[*]": providers.DeferredReasonInstanceCountUnknown, }, }, }, @@ -1160,7 +1160,7 @@ resource "test" "b" { "test.b": plans.Create, }, wantDeferred: map[string]providers.DeferredReason{ - "test.a[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.a[*]": providers.DeferredReasonInstanceCountUnknown, }, wantApplied: map[string]cty.Value{ "b": cty.ObjectVal(map[string]cty.Value{ @@ -1284,7 +1284,7 @@ resource "test" "c" { "test.b": plans.Create, }, wantDeferred: map[string]providers.DeferredReason{ - "test.c[\"*\"]": providers.DeferredReasonInstanceCountUnknown, + "test.c[*]": providers.DeferredReasonInstanceCountUnknown, }, wantApplied: map[string]cty.Value{ "b": cty.ObjectVal(map[string]cty.Value{