code: func providerConfigsStr(pcs []*ProviderConfig) string {
  	result := ""
  
  	ns := make([]string, 0, len(pcs))
  	m := make(map[string]*ProviderConfig)
  	for _, n := range pcs {
  		ns = append(ns, n.Name)
  		m[n.Name] = n
  	}
  	sort.Strings(ns)
  
  	for _, n := range ns {
  		pc := m[n]
  
  		result += fmt.Sprintf("%s\n", n)
  
  		keys := make([]string, 0, len(pc.RawConfig.Raw))
  		for k, _ := range pc.RawConfig.Raw {
  			keys = append(keys, k)
  		}
  		sort.Strings(keys)
  
  		for _, k := range keys {
  			result += fmt.Sprintf("  %s\n", k)
  		}
  
  		if len(pc.RawConfig.Variables) > 0 {
  			result += fmt.Sprintf("  vars\n")
  			for _, rawV := range pc.RawConfig.Variables {
  				kind := "unknown"
  				str := rawV.FullKey()
  
  				switch rawV.(type) {
  				case *ResourceVariable:
  					kind = "resource"
  				case *UserVariable:
  					kind = "user"
  				}
  
  				result += fmt.Sprintf("    %s: %s\n", kind, str)
  			}
  		}
  	}
  
  	return strings.TrimSpace(result)
  }
docs: // This helper turns a provider configs field into a deterministic
  // string value for comparison in tests.