Repository: hashicorp/vault
File: builtin/logical/aws/client.go (Go)

Code before:
		}

		sessionSuffix := strconv.FormatInt(time.Now().UnixNano(), 10)
		credsConfig.RoleSessionName = fmt.Sprintf("vault-aws-secrets-%s", sessionSuffix)
		credsConfig.WebIdentityTokenFetcher = fetcher
		credsConfig.RoleARN = config.RoleARN

		// explicitly disable environment and shared credential providers when using Web Identity Token Fetcher
		// enables WIF usage in environments that may use AWS Profiles or environment variables for other use-cases
		opts = append(opts, awsutil.WithEnvironmentCredentials(false), awsutil.WithSharedCredentials(false))
	}

	// at this point, in the IAM case, regions contains config.Region, if it was set.
	//                                 endpoints contains iam_endpoint, if it was set.
	// in the sts case, regions contains sts_region, if it was set, then the sts_fallback_regions in order, if they were set.
	//                  endpoints contains sts_endpint, if it wa set, then sts_fallback_endpoints in order, if they were set.

	logger.Info("pre", "region", fmt.Sprintf("%+v", regions), "endpoint", fmt.Sprintf("%+v", endpoints))

	// case in which nothing was supplied
	if len(regions) == 0 {
		// fallback region is in descending order, AWS_REGION, or AWS_DEFAULT_REGION, or us-east-1
		regions = append(regions, fallbackRegion)
	}

	if len(endpoints) == 0 {
		switch clientType {
		case "sts":
			for _, v := range regions {
				endpoints = append(endpoints, matchingSTSEndpoint(v))
			}
		case "iam":
			for range regions {
				// for custom IAM implementations, iam_endpoint would have been set above - this case will only occur in
				// real IAM deployments, where you don't specify an endpoint, and in fact, AWS doesn't seem to like it
				// if you do.
				endpoints = append(endpoints, "")
			}
		}
	}

	// for this approach of using parallel arrays to part out the configs, we want equal numbers of regions and endpoints
	if len(regions) != len(endpoints) {
		return nil, errors.New("number of regions does not match number of endpoints")
	}

	logger.Info("data", "region", fmt.Sprintf("%+v", regions), "endpoint", fmt.Sprintf("%+v", endpoints))

	for i := 0; i < len(endpoints); i++ {
		if len(regions) > i {
			credsConfig.Region = regions[i]

Review comment (bug):
This (probably) was the bug that was causing gov-cloud issues - we weren't pre-setting the region defined in the config, so it was getting lost.

Code after:
		}
		configs = append(configs, &aws.Config{
			Credentials: creds,
			Region:      aws.String(fallbackRegion),
			Endpoint:    aws.String(""),
			MaxRetries:  aws.Int(maxRetries),
		})

		return configs, nil
	}

	var config rootConfig
	if err := entry.DecodeJSON(&config); err != nil {
		return nil, fmt.Errorf("error reading root configuration: %w", err)
	}

	var endpoints []string
	var regions []string
	credsConfig := &awsutil.CredentialsConfig{}

	credsConfig.AccessKey = config.AccessKey
	credsConfig.SecretKey = config.SecretKey
	credsConfig.HTTPClient = cleanhttp.DefaultClient()
	credsConfig.Logger = logger

	if config.Region != "" {
		regions = append(regions, config.Region)
	}

	maxRetries = config.MaxRetries
	if config.STSEndpoint != "" {
		endpoints = append(endpoints, config.STSEndpoint)
		if config.STSRegion != "" {
			// this retains original logic, where sts region was only used if sts endpoint was set
			regions = []string{config.STSRegion} // override to be "only" region if set
		}

		if len(config.STSFallbackEndpoints) > 0 {
			endpoints = append(endpoints, config.STSFallbackEndpoints...)
		}

		if len(config.STSFallbackRegions) > 0 {
			regions = append(regions, config.STSFallbackRegions...)
		}
	}

	opts := make([]awsutil.Option, 0)
	if config.IdentityTokenAudience != "" {
		ns, err := namespace.FromContext(ctx)
		if err != nil {
			return nil, fmt.Errorf("failed to get namespace from context: %w", err)