@ -103,50 +103,70 @@ func (l *Loader) moduleWalkerLoad(req *configs.ModuleRequest) (*configs.Module,
// The providers associated with expanding modules must be present in the proxy/passed providers
// block. Guarding here for accessing the module call just in case.
if mc , exists := req . Parent . Module . ModuleCalls [ req . Name ] ; exists {
if mc . Count != nil || mc . ForEach != nil {
for key , pc := range mod . ProviderConfigs {
// Use these to track if a provider is configured (not allowed),
// or if we've found its matching proxy
var isConfigured bool
var foundMatchingProxy bool
// Validate the config against an empty schema to see if it's empty.
_ , pcConfigDiags := pc . Config . Content ( & hcl . BodySchema { } )
if pcConfigDiags . HasErrors ( ) || pc . Version . Required != nil {
isConfigured = true
}
var validateDiags hcl . Diagnostics
validateDiags = validateProviderConfigs ( mc , mod , req . Parent , validateDiags )
diags = append ( diags , validateDiags ... )
}
return mod , record . Version , diags
}
func validateProviderConfigs ( mc * configs . ModuleCall , mod * configs . Module , parent * configs . Config , diags hcl . Diagnostics ) hcl . Diagnostics {
if mc . Count != nil || mc . ForEach != nil {
for key , pc := range mod . ProviderConfigs {
// Use these to track if a provider is configured (not allowed),
// or if we've found its matching proxy
var isConfigured bool
var foundMatchingProxy bool
// Validate the config against an empty schema to see if it's empty.
_ , pcConfigDiags := pc . Config . Content ( & hcl . BodySchema { } )
if pcConfigDiags . HasErrors ( ) || pc . Version . Required != nil {
isConfigured = true
}
// If it is empty or only has an alias,
// does this provider exist in our proxy configs?
for _ , r := range mc . Providers {
// Must match on name and Alias
if pc . Name == r . InChild . Name && pc . Alias == r . InChild . Alias {
foundMatchingProxy = true
break
}
// If it is empty or only has an alias,
// does this provider exist in our proxy configs?
for _ , r := range mc . Providers {
// Must match on name and Alias
if pc . Name == r . InChild . Name && pc . Alias == r . InChild . Alias {
foundMatchingProxy = true
break
}
if isConfigured || ! foundMatchingProxy {
if mc . Count != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Module does not support count" ,
Detail : fmt . Sprintf ( moduleProviderError , mc . Name , "count" , key , pc . NameRange ) ,
Subject : mc . Count . Range ( ) . Ptr ( ) ,
} )
}
if mc . ForEach != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Module does not support for_each" ,
Detail : fmt . Sprintf ( moduleProviderError , mc . Name , "for_each" , key , pc . NameRange ) ,
Subject : mc . ForEach . Range ( ) . Ptr ( ) ,
} )
}
}
if isConfigured || ! foundMatchingProxy {
if mc . Count != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Module does not support count" ,
Detail : fmt . Sprintf ( moduleProviderError , mc . Name , "count" , key , pc . NameRange ) ,
Subject : mc . Count . Range ( ) . Ptr ( ) ,
} )
}
if mc . ForEach != nil {
diags = append ( diags , & hcl . Diagnostic {
Severity : hcl . DiagError ,
Summary : "Module does not support for_each" ,
Detail : fmt . Sprintf ( moduleProviderError , mc . Name , "for_each" , key , pc . NameRange ) ,
Subject : mc . ForEach . Range ( ) . Ptr ( ) ,
} )
}
}
}
}
return mod , record . Version , diags
// If this module has further parents, go through them recursively
if ! parent . Path . IsRoot ( ) {
// Use the path to get the name so we can look it up in the parent module calls
path := parent . Path
name := path [ len ( path ) - 1 ]
// This parent's module call, so we can check for count/for_each here,
// guarding with exists just in case. We pass the diags through to the recursive
// call so they will accumulate if needed.
if mc , exists := parent . Parent . Module . ModuleCalls [ name ] ; exists {
return validateProviderConfigs ( mc , mod , parent . Parent , diags )
}
}
return diags
}
var moduleProviderError = ` Module "%s" cannot be used with % s because it contains a nested provider configuration for "%s" , at % s .